/**
 * 数据库迁移脚本
 * 创建 Admin 管理系统所需的表结构
 *
 * 运行: bun run db:migrate
 */
import { query, closePool } from "../db";

const migrations = [
  // 1. 管理员用户表
  `CREATE TABLE IF NOT EXISTS admin_user (
    id SERIAL PRIMARY KEY,
    username VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  )`,

  // 2. 角色表
  `CREATE TABLE IF NOT EXISTS admin_role (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) UNIQUE NOT NULL,
    description TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  )`,

  // 3. 权限表
  `CREATE TABLE IF NOT EXISTS admin_permission (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    code VARCHAR(255) UNIQUE NOT NULL,
    description TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  )`,

  // 4. 用户-角色关联表
  `CREATE TABLE IF NOT EXISTS admin_user_role (
    user_id INTEGER NOT NULL REFERENCES admin_user(id) ON DELETE CASCADE,
    role_id INTEGER NOT NULL REFERENCES admin_role(id) ON DELETE CASCADE,
    PRIMARY KEY (user_id, role_id)
  )`,

  // 5. 角色-权限关联表
  `CREATE TABLE IF NOT EXISTS admin_role_permission (
    role_id INTEGER NOT NULL REFERENCES admin_role(id) ON DELETE CASCADE,
    permission_id INTEGER NOT NULL REFERENCES admin_permission(id) ON DELETE CASCADE,
    PRIMARY KEY (role_id, permission_id)
  )`,

  // 6. 审计日志表
  `CREATE TABLE IF NOT EXISTS admin_audit_log (
    id BIGSERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL,
    username VARCHAR(255) NOT NULL,
    action VARCHAR(50) NOT NULL,
    resource VARCHAR(255) NOT NULL,
    resource_id VARCHAR(255),
    request_params JSONB,
    ip_address VARCHAR(255),
    user_agent TEXT,
    result VARCHAR(20) NOT NULL DEFAULT 'success',
    error_message TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  )`,

  // 索引
  `CREATE INDEX IF NOT EXISTS idx_admin_user_username ON admin_user(username)`,
  `CREATE INDEX IF NOT EXISTS idx_admin_audit_log_user_id ON admin_audit_log(user_id)`,
  `CREATE INDEX IF NOT EXISTS idx_admin_audit_log_created_at ON admin_audit_log(created_at DESC)`,
  `CREATE INDEX IF NOT EXISTS idx_admin_audit_log_action ON admin_audit_log(action)`,
  `CREATE INDEX IF NOT EXISTS idx_admin_audit_log_resource ON admin_audit_log(resource)`,
];

const seedData = [
  // 默认权限
  `INSERT INTO admin_permission (name, code, description) VALUES
    ('用户管理', 'user:read', '查看用户列表'),
    ('用户创建', 'user:create', '创建管理员用户'),
    ('用户更新', 'user:update', '更新管理员用户'),
    ('用户删除', 'user:delete', '删除管理员用户'),
    ('角色管理', 'role:read', '查看角色'),
    ('角色创建', 'role:create', '创建角色'),
    ('角色更新', 'role:update', '更新角色'),
    ('角色删除', 'role:delete', '删除角色'),
    ('权限管理', 'permission:read', '查看权限'),
    ('权限创建', 'permission:create', '创建权限'),
    ('权限更新', 'permission:update', '更新权限'),
    ('权限删除', 'permission:delete', '删除权限'),
    ('日志查看', 'log:read', '查看审计日志'),
    ('会话管理', 'session:manage', '管理在线用户会话'),
    ('平台数据', 'platform:read', '查看平台数据'),
    ('平台管理', 'platform:manage', '管理平台数据')
   ON CONFLICT (code) DO NOTHING`,

  // 超级管理员角色
  `INSERT INTO admin_role (name, description) VALUES
    ('超级管理员', '拥有所有权限')
   ON CONFLICT (name) DO NOTHING`,

  // 将所有权限授予超级管理员
  `INSERT INTO admin_role_permission (role_id, permission_id)
   SELECT r.id, p.id
   FROM admin_role r
   CROSS JOIN admin_permission p
   WHERE r.name = '超级管理员'
   ON CONFLICT DO NOTHING`,
];

async function runMigrations() {
  console.log("Running admin database migrations...");

  for (let i = 0; i < migrations.length; i++) {
    try {
      await query(migrations[i]);
      console.log(`✓ Migration ${i + 1}/${migrations.length} succeeded`);
    } catch (e) {
      console.error(`✗ Migration ${i + 1}/${migrations.length} failed:`, e);
      throw e;
    }
  }

  console.log("\nSeeding initial data...");
  for (let i = 0; i < seedData.length; i++) {
    try {
      await query(seedData[i]);
      console.log(`✓ Seed ${i + 1}/${seedData.length} succeeded`);
    } catch (e) {
      console.error(`✗ Seed ${i + 1}/${seedData.length} failed:`, e);
    }
  }

  console.log("\n✓ All migrations completed!");
  await closePool();
}

runMigrations().catch((e) => {
  console.error("Migration failed:", e);
  process.exit(1);
});
