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> {
        let conn = manager.get_connection();

        // 为 m000088 之后创建的新表补充 RLS 策略。
        // 幂等操作：仅影响尚未启用 RLS 或缺少策略的表。
        conn.execute_unprepared(
            r#"
            DO $$
            DECLARE
                tbl TEXT;
                policy_exists BOOLEAN;
            BEGIN
                FOR tbl IN
                    SELECT c.table_name FROM information_schema.columns c
                    JOIN information_schema.tables t
                      ON c.table_name = t.table_name AND c.table_schema = t.table_schema
                    WHERE c.column_name = 'tenant_id'
                      AND c.table_schema = 'public'
                      AND t.table_type = 'BASE TABLE'
                    ORDER BY c.table_name
                LOOP
                    -- 启用 RLS（幂等）
                    EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY', tbl);

                    -- 检查是否已有 tenant_isolation 策略
                    SELECT EXISTS(
                        SELECT 1 FROM pg_policies
                        WHERE tablename = tbl
                          AND policyname = 'tenant_isolation'
                    ) INTO policy_exists;

                    IF NOT policy_exists THEN
                        EXECUTE format(
                            'CREATE POLICY tenant_isolation ON %I USING (
                                current_setting(''app.current_tenant_id'', true) != ''''
                                AND tenant_id = current_setting(''app.current_tenant_id'', true)::uuid
                            )',
                            tbl
                        );
                        RAISE NOTICE 'Created RLS policy for table: %', tbl;
                    END IF;
                END LOOP;
            END;
            $$;
            "#,
        )
        .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        // 回滚不需要移除 RLS，保持 m000088 的策略不变
        // 此迁移补充的 RLS 策略在 down() 中保留，因为 m000088 已处理回滚
        let _ = manager;
        Ok(())
    }
}
