/**
 * 广东省立中山图书馆 - 租户初始化脚本
 *
 * 运行方式:
 * npx ts-node -r tsconfig-paths/register scripts/init-guangdong-library.ts
 *
 * 功能:
 * 1. 创建广东省图租户（library 类型）
 * 2. 创建管理员账号
 * 3. 分配必要的角色和权限
 * 4. 分配菜单
 */

import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';

const prisma = new PrismaClient();

async function main() {
  console.log('开始初始化广东省图数据...\n');

  // 1. 创建租户
  const tenantCode = 'gdlib';
  let tenant = await prisma.tenant.findUnique({ where: { code: tenantCode } });

  if (tenant) {
    console.log(`租户 ${tenantCode} 已存在 (ID: ${tenant.id})，跳过创建`);
  } else {
    tenant = await prisma.tenant.create({
      data: {
        name: '广东省立中山图书馆',
        code: tenantCode,
        tenantType: 'library',
        description: '广东省图少儿绘本创作活动主办方',
        isSuper: 0,
        validState: 1,
      },
    });
    console.log(`创建租户: ${tenant.name} (ID: ${tenant.id})`);
  }

  const tenantId = tenant.id;

  // 2. 创建权限
  const permissions = [
    // 活动管理
    { code: 'contest:create', resource: 'contest', action: 'create', name: '创建活动', description: '允许创建活动' },
    { code: 'contest:read', resource: 'contest', action: 'read', name: '查看活动', description: '允许查看活动' },
    { code: 'contest:update', resource: 'contest', action: 'update', name: '更新活动', description: '允许更新活动' },
    { code: 'contest:delete', resource: 'contest', action: 'delete', name: '删除活动', description: '允许删除活动' },
    { code: 'contest:publish', resource: 'contest', action: 'publish', name: '发布活动', description: '允许发布活动' },
    { code: 'contest:finish', resource: 'contest', action: 'finish', name: '结束活动', description: '允许结束活动' },
    // 报名管理
    { code: 'registration:approve', resource: 'registration', action: 'approve', name: '审核报名', description: '允许审核报名' },
    { code: 'registration:read', resource: 'registration', action: 'read', name: '查看报名', description: '允许查看报名记录' },
    // 评委管理
    { code: 'judge:read', resource: 'judge', action: 'read', name: '查看评委', description: '允许查看评委' },
    { code: 'judge:create', resource: 'judge', action: 'create', name: '添加评委', description: '允许添加评委' },
    { code: 'judge:assign', resource: 'judge', action: 'assign', name: '分配评委', description: '允许分配评委' },
    // 评审规则
    { code: 'review-rule:read', resource: 'review-rule', action: 'read', name: '查看评审规则', description: '允许查看评审规则' },
    { code: 'review-rule:create', resource: 'review-rule', action: 'create', name: '创建评审规则', description: '允许创建评审规则' },
    // 成果发布
    { code: 'result:read', resource: 'result', action: 'read', name: '查看成果', description: '允许查看活动成果' },
    { code: 'result:publish', resource: 'result', action: 'publish', name: '发布成果', description: '允许发布活动成果' },
    // 公告
    { code: 'notice:create', resource: 'notice', action: 'create', name: '创建公告', description: '允许创建活动公告' },
    { code: 'notice:read', resource: 'notice', action: 'read', name: '查看公告', description: '允许查看活动公告' },
    // 用户管理
    { code: 'user:read', resource: 'user', action: 'read', name: '查看用户', description: '允许查看用户' },
    { code: 'user:create', resource: 'user', action: 'create', name: '创建用户', description: '允许创建用户' },
    // 角色管理
    { code: 'role:read', resource: 'role', action: 'read', name: '查看角色', description: '允许查看角色' },
    // 菜单
    { code: 'menu:read', resource: 'menu', action: 'read', name: '查看菜单', description: '允许查看菜单' },
  ];

  const permissionIds: number[] = [];
  for (const perm of permissions) {
    const existing = await prisma.permission.findFirst({
      where: { tenantId, code: perm.code },
    });
    if (existing) {
      permissionIds.push(existing.id);
    } else {
      const created = await prisma.permission.create({
        data: { ...perm, tenantId, validState: 1 },
      });
      permissionIds.push(created.id);
    }
  }
  console.log(`权限已创建/确认: ${permissionIds.length} 个`);

  // 3. 创建管理员角色
  let adminRole = await prisma.role.findFirst({
    where: { tenantId, code: 'tenant_admin' },
  });
  if (!adminRole) {
    adminRole = await prisma.role.create({
      data: {
        tenantId,
        name: '机构管理员',
        code: 'tenant_admin',
        description: '广东省图机构管理员，管理活动和报名',
        validState: 1,
      },
    });
    console.log(`创建角色: ${adminRole.name}`);
  }

  // 分配所有权限给管理员角色
  for (const permId of permissionIds) {
    const existing = await prisma.rolePermission.findFirst({
      where: { roleId: adminRole.id, permissionId: permId },
    });
    if (!existing) {
      await prisma.rolePermission.create({
        data: { roleId: adminRole.id, permissionId: permId },
      });
    }
  }
  console.log(`角色权限已分配`);

  // 4. 创建管理员账号
  const adminUsername = 'admin';
  let adminUser = await prisma.user.findFirst({
    where: { tenantId, username: adminUsername },
  });
  if (!adminUser) {
    const hashedPassword = await bcrypt.hash('admin@gdlib', 10);
    adminUser = await prisma.user.create({
      data: {
        tenantId,
        username: adminUsername,
        password: hashedPassword,
        nickname: '广东省图管理员',
        userSource: 'admin_created',
        status: 'enabled',
        validState: 1,
        roles: {
          create: [{ roleId: adminRole.id }],
        },
      },
    });
    console.log(`创建管理员: ${adminUsername} / admin@gdlib`);
  } else {
    console.log(`管理员 ${adminUsername} 已存在`);
  }

  // 5. 分配菜单（活动管理 + 系统管理）
  const menuNames = ['活动管理', '系统管理'];
  const menus = await prisma.menu.findMany({
    where: { name: { in: menuNames }, parentId: null },
    include: { children: true },
  });

  for (const menu of menus) {
    // 分配父菜单
    const existing = await prisma.tenantMenu.findFirst({
      where: { tenantId, menuId: menu.id },
    });
    if (!existing) {
      await prisma.tenantMenu.create({
        data: { tenantId, menuId: menu.id },
      });
    }
    // 分配子菜单
    for (const child of menu.children || []) {
      const childExisting = await prisma.tenantMenu.findFirst({
        where: { tenantId, menuId: child.id },
      });
      if (!childExisting) {
        await prisma.tenantMenu.create({
          data: { tenantId, menuId: child.id },
        });
      }
    }
  }
  console.log(`菜单已分配: ${menuNames.join(', ')}`);

  console.log('\n广东省图初始化完成!');
  console.log(`登录地址: /${tenantCode}/login`);
  console.log(`账号: admin / admin@gdlib`);
}

main()
  .catch((e) => {
    console.error('初始化失败:', e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
