//! 修复 admin 角色权限绑定
//!
//! 根因链：
//! 1. m20260506_000126 对部分角色执行了软删除（SET deleted_at = NOW()）
//! 2. m20260508_000131 执行 `DELETE FROM role_permissions WHERE deleted_at IS NOT NULL`
//!    物理删除了所有被软删除的记录
//! 3. m20260508_000131 只重新分配了 doctor/nurse/operator 的权限，遗漏了 admin 角色
//! 4. 后续的 assign_permissions API 调用可能在内部先软删除再 INSERT，
//!    INSERT 失败时 admin 权限全部丢失
//!
//! 本迁移：
//! - Step 1: 恢复所有被软删除的 admin role_permissions（deleted_at IS NOT NULL → NULL）
//! - Step 2: 插入所有缺失的 admin role_permissions（ON CONFLICT DO NOTHING 保证幂等）
//!
//! 覆盖范围：全系统 128 个权限码（auth/config/workflow/message/plugin/health/ai/copilot/points）

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 db = manager.get_connection();

        // ================================================================
        // Step 1: 恢复被软删除的 admin role_permissions
        // ================================================================
        // 如果 admin 的某些权限记录仍然存在但被软删除了，恢复它们
        db.execute_unprepared(
            r#"
            UPDATE role_permissions rp
            SET deleted_at = NULL, updated_at = NOW(), version = rp.version + 1
            FROM roles r
            WHERE rp.role_id = r.id
              AND r.code = 'admin'
              AND r.deleted_at IS NULL
              AND rp.deleted_at IS NOT NULL
            "#,
        )
        .await?;

        // ================================================================
        // Step 2: 插入缺失的 admin role_permissions
        // ================================================================
        // 将 permissions 表中所有未被软删除的权限绑定到 admin 角色
        // ON CONFLICT (role_id, permission_id) DO NOTHING — 已存在（含刚恢复的）的跳过
        db.execute_unprepared(
            r#"
            INSERT INTO role_permissions (role_id, permission_id, tenant_id, data_scope,
                                          created_at, updated_at, created_by, updated_by,
                                          deleted_at, version)
            SELECT r.id, p.id, r.tenant_id, 'all',
                   NOW(), NOW(), r.id, r.id,
                   NULL, 1
            FROM roles r
            JOIN permissions p ON p.tenant_id = r.tenant_id AND p.deleted_at IS NULL
            WHERE r.code = 'admin' AND r.deleted_at IS NULL
              AND NOT EXISTS (
                  SELECT 1 FROM role_permissions rp
                  WHERE rp.role_id = r.id
                    AND rp.permission_id = p.id
                    AND rp.deleted_at IS NULL
              )
            ON CONFLICT (role_id, permission_id) DO NOTHING
            "#,
        )
        .await?;

        Ok(())
    }

    async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> {
        // 不回滚 — 这是修复性迁移，admin 应该始终拥有全部权限
        Ok(())
    }
}
