use sea_orm_migration::prelude::*;
use sea_query::extension::postgres::Type;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        // Create RecurrenceType enum
        manager
            .create_type(
                Type::create()
                    .as_enum(RecurrenceType::Type)
                    .values([
                        RecurrenceType::Hourly,
                        RecurrenceType::Daily,
                        RecurrenceType::Weekly,
                        RecurrenceType::Monthly,
                        RecurrenceType::Yearly,
                    ])
                    .to_owned(),
            )
            .await?;

        // Create TargetType enum
        manager
            .create_type(
                Type::create()
                    .as_enum(TargetType::Type)
                    .values([TargetType::Todo, TargetType::ReminderTask])
                    .to_owned(),
            )
            .await?;

        // Create ChannelType enum
        manager
            .create_type(
                Type::create()
                    .as_enum(ChannelType::Type)
                    .values([ChannelType::Inapp, ChannelType::Bark])
                    .to_owned(),
            )
            .await?;

        // Create NotificationStatus enum
        manager
            .create_type(
                Type::create()
                    .as_enum(NotificationStatus::Type)
                    .values([
                        NotificationStatus::Pending,
                        NotificationStatus::Queued,
                        NotificationStatus::Sent,
                        NotificationStatus::Failed,
                    ])
                    .to_owned(),
            )
            .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_type(Type::drop().name(NotificationStatus::Type).to_owned())
            .await?;

        manager
            .drop_type(Type::drop().name(ChannelType::Type).to_owned())
            .await?;

        manager
            .drop_type(Type::drop().name(TargetType::Type).to_owned())
            .await?;

        manager
            .drop_type(Type::drop().name(RecurrenceType::Type).to_owned())
            .await?;

        Ok(())
    }
}

// RecurrenceType enum
#[derive(DeriveIden)]
pub enum RecurrenceType {
    #[sea_orm(iden = "recurrence_type")]
    Type,
    #[sea_orm(iden = "hourly")]
    Hourly,
    #[sea_orm(iden = "daily")]
    Daily,
    #[sea_orm(iden = "weekly")]
    Weekly,
    #[sea_orm(iden = "monthly")]
    Monthly,
    #[sea_orm(iden = "yearly")]
    Yearly,
}

// TargetType enum
#[derive(DeriveIden)]
pub enum TargetType {
    #[sea_orm(iden = "target_type")]
    Type,
    #[sea_orm(iden = "todo")]
    Todo,
    #[sea_orm(iden = "reminder_task")]
    ReminderTask,
}

// ChannelType enum
#[derive(DeriveIden)]
pub enum ChannelType {
    #[sea_orm(iden = "channel_type")]
    Type,
    #[sea_orm(iden = "inapp")]
    Inapp,
    #[sea_orm(iden = "bark")]
    Bark,
}

// NotificationStatus enum
#[derive(DeriveIden)]
pub enum NotificationStatus {
    #[sea_orm(iden = "notification_status")]
    Type,
    #[sea_orm(iden = "pending")]
    Pending,
    #[sea_orm(iden = "queued")]
    Queued,
    #[sea_orm(iden = "sent")]
    Sent,
    #[sea_orm(iden = "failed")]
    Failed,
}
