use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

const TABLE: &str = "comments";

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        let table = Alias::new(TABLE);

        if !manager.has_column(TABLE, "scope").await? {
            manager
                .alter_table(
                    Table::alter()
                        .table(table.clone())
                        .add_column(
                            ColumnDef::new(Alias::new("scope"))
                                .string()
                                .not_null()
                                .default("article"),
                        )
                        .to_owned(),
                )
                .await?;
        }

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

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

        if !manager.has_column(TABLE, "reply_to_comment_id").await? {
            manager
                .alter_table(
                    Table::alter()
                        .table(table.clone())
                        .add_column(
                            ColumnDef::new(Alias::new("reply_to_comment_id"))
                                .integer()
                                .null(),
                        )
                        .to_owned(),
                )
                .await?;
        }

        manager
            .get_connection()
            .execute_unprepared(
                "UPDATE comments SET scope = 'article' WHERE scope IS NULL OR trim(scope) = ''",
            )
            .await?;

        manager
            .get_connection()
            .execute_unprepared(
                "CREATE INDEX IF NOT EXISTS idx_comments_post_scope_paragraph ON comments (post_slug, scope, paragraph_key)",
            )
            .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .get_connection()
            .execute_unprepared("DROP INDEX IF EXISTS idx_comments_post_scope_paragraph")
            .await?;

        for column in [
            "reply_to_comment_id",
            "paragraph_excerpt",
            "paragraph_key",
            "scope",
        ] {
            if manager.has_column(TABLE, column).await? {
                manager
                    .alter_table(
                        Table::alter()
                            .table(Alias::new(TABLE))
                            .drop_column(Alias::new(column))
                            .to_owned(),
                    )
                    .await?;
            }
        }

        Ok(())
    }
}
