use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        for table_name in ["categories", "tags"] {
            if !manager.has_column(table_name, "description").await? {
                manager
                    .alter_table(
                        Table::alter()
                            .table(Alias::new(table_name))
                            .add_column(ColumnDef::new(Alias::new("description")).text().null())
                            .to_owned(),
                    )
                    .await?;
            }

            if !manager.has_column(table_name, "cover_image").await? {
                manager
                    .alter_table(
                        Table::alter()
                            .table(Alias::new(table_name))
                            .add_column(ColumnDef::new(Alias::new("cover_image")).string().null())
                            .to_owned(),
                    )
                    .await?;
            }

            if !manager.has_column(table_name, "accent_color").await? {
                manager
                    .alter_table(
                        Table::alter()
                            .table(Alias::new(table_name))
                            .add_column(ColumnDef::new(Alias::new("accent_color")).string().null())
                            .to_owned(),
                    )
                    .await?;
            }

            if !manager.has_column(table_name, "seo_title").await? {
                manager
                    .alter_table(
                        Table::alter()
                            .table(Alias::new(table_name))
                            .add_column(ColumnDef::new(Alias::new("seo_title")).string().null())
                            .to_owned(),
                    )
                    .await?;
            }

            if !manager.has_column(table_name, "seo_description").await? {
                manager
                    .alter_table(
                        Table::alter()
                            .table(Alias::new(table_name))
                            .add_column(ColumnDef::new(Alias::new("seo_description")).text().null())
                            .to_owned(),
                    )
                    .await?;
            }
        }

        if !manager.has_table("media_assets").await? {
            manager
                .create_table(
                    Table::create()
                        .table(Alias::new("media_assets"))
                        .if_not_exists()
                        .col(
                            ColumnDef::new(Alias::new("created_at"))
                                .timestamp_with_time_zone()
                                .not_null()
                                .default(Expr::current_timestamp()),
                        )
                        .col(
                            ColumnDef::new(Alias::new("updated_at"))
                                .timestamp_with_time_zone()
                                .not_null()
                                .default(Expr::current_timestamp()),
                        )
                        .col(
                            ColumnDef::new(Alias::new("id"))
                                .integer()
                                .not_null()
                                .auto_increment()
                                .primary_key(),
                        )
                        .col(ColumnDef::new(Alias::new("object_key")).string().not_null())
                        .col(ColumnDef::new(Alias::new("title")).string().null())
                        .col(ColumnDef::new(Alias::new("alt_text")).string().null())
                        .col(ColumnDef::new(Alias::new("caption")).text().null())
                        .col(ColumnDef::new(Alias::new("tags")).json_binary().null())
                        .col(ColumnDef::new(Alias::new("notes")).text().null())
                        .to_owned(),
                )
                .await?;
        }

        manager
            .create_index(
                Index::create()
                    .name("idx_media_assets_object_key_unique")
                    .table(Alias::new("media_assets"))
                    .col(Alias::new("object_key"))
                    .unique()
                    .if_not_exists()
                    .to_owned(),
            )
            .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        if manager
            .has_index("media_assets", "idx_media_assets_object_key_unique")
            .await?
        {
            manager
                .drop_index(
                    Index::drop()
                        .name("idx_media_assets_object_key_unique")
                        .table(Alias::new("media_assets"))
                        .to_owned(),
                )
                .await?;
        }

        if manager.has_table("media_assets").await? {
            manager
                .drop_table(Table::drop().table(Alias::new("media_assets")).to_owned())
                .await?;
        }

        for table_name in ["categories", "tags"] {
            for column in [
                "seo_description",
                "seo_title",
                "accent_color",
                "cover_image",
                "description",
            ] {
                if manager.has_column(table_name, column).await? {
                    manager
                        .alter_table(
                            Table::alter()
                                .table(Alias::new(table_name))
                                .drop_column(Alias::new(column))
                                .to_owned(),
                        )
                        .await?;
                }
            }
        }

        Ok(())
    }
}
