// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
// 加载环境变量（必须在其他导入之前）
import * as dotenv from 'dotenv';
import * as path from 'path';
import * as fs from 'fs';

// 根据 NODE_ENV 加载对应的环境配置文件
const nodeEnv = process.env.NODE_ENV || 'development';
const envFile = `.env.${nodeEnv}`;
// scripts 目录的父目录就是 backend 目录
const backendDir = path.resolve(__dirname, '..');
const envPath = path.resolve(backendDir, envFile);

// 尝试加载环境特定的配置文件
dotenv.config({ path: envPath });

// 如果环境特定文件不存在，尝试加载默认的 .env 文件
if (!process.env.DATABASE_URL) {
  dotenv.config({ path: path.resolve(backendDir, '.env') });
}

// 验证必要的环境变量
if (!process.env.DATABASE_URL) {
  console.error('❌ 错误: 未找到 DATABASE_URL 环境变量');
  console.error(`   请确保存在以下文件之一:`);
  console.error(`   - ${envPath}`);
  console.error(`   - ${path.resolve(backendDir, '.env')}`);
  console.error(`   或者设置 NODE_ENV 环境变量（当前: ${nodeEnv})`);
  process.exit(1);
}

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

const prisma = new PrismaClient();

// 从 JSON 文件加载权限数据
const permissionsFilePath = path.resolve(backendDir, 'data', 'permissions.json');

if (!fs.existsSync(permissionsFilePath)) {
  console.error(`❌ 错误: 权限数据文件不存在: ${permissionsFilePath}`);
  process.exit(1);
}

const permissions = JSON.parse(fs.readFileSync(permissionsFilePath, 'utf-8'));

async function initTenantMenuAndPermissions(tenantCode: string) {
  try {
    console.log(`🚀 开始为租户 "${tenantCode}" 初始化菜单和权限...\n`);

    // 1. 查找或创建租户
    console.log(`📋 步骤 1: 查找或创建租户 "${tenantCode}"...`);
    let tenant = await prisma.tenant.findUnique({
      where: { code: tenantCode },
    });

    if (!tenant) {
      // 创建租户
      tenant = await prisma.tenant.create({
        data: {
          name: `${tenantCode} 租户`,
          code: tenantCode,
          domain: tenantCode,
          description: `租户 ${tenantCode}`,
          isSuper: 0,
          validState: 1,
        },
      });
      console.log(`✅ 租户创建成功: ${tenant.name} (${tenant.code})\n`);
    } else {
      if (tenant.validState !== 1) {
        console.error(`❌ 错误: 租户 "${tenantCode}" 状态无效！`);
        process.exit(1);
      }
      console.log(`✅ 找到租户: ${tenant.name} (${tenant.code})\n`);
    }

    // 2. 查找或创建 admin 用户
    console.log(`👤 步骤 2: 查找或创建 admin 用户...`);
    let adminUser = await prisma.user.findFirst({
      where: {
        tenantId: tenant.id,
        username: 'admin',
      },
    });

    const password = `admin@${tenantCode}`;
    const hashedPassword = await bcrypt.hash(password, 10);

    if (!adminUser) {
      adminUser = await prisma.user.create({
        data: {
          tenantId: tenant.id,
          username: 'admin',
          password: hashedPassword,
          nickname: '管理员',
          email: `admin@${tenantCode}.com`,
          validState: 1,
        },
      });
      console.log(`✅ admin 用户创建成功: ${adminUser.username}\n`);
    } else {
      // 更新密码（确保密码是最新的）
      adminUser = await prisma.user.update({
        where: { id: adminUser.id },
        data: {
          password: hashedPassword,
          nickname: '管理员',
          email: `admin@${tenantCode}.com`,
          validState: 1,
        },
      });
      console.log(`✅ admin 用户已存在: ${adminUser.username}\n`);
    }

    // 3. 查找或创建 admin 角色
    console.log(`👤 步骤 3: 查找或创建 admin 角色...`);
    let adminRole = await prisma.role.findFirst({
      where: {
        tenantId: tenant.id,
        code: 'admin',
      },
    });

    if (!adminRole) {
      adminRole = await prisma.role.create({
        data: {
          tenantId: tenant.id,
          name: '管理员',
          code: 'admin',
          description: '租户管理员角色，拥有租户的所有权限',
          validState: 1,
        },
      });
      console.log(`✅ admin 角色创建成功: ${adminRole.name} (${adminRole.code})\n`);
    } else {
      adminRole = await prisma.role.update({
        where: { id: adminRole.id },
        data: {
          name: '管理员',
          description: '租户管理员角色，拥有租户的所有权限',
          validState: 1,
        },
      });
      console.log(`✅ admin 角色已存在: ${adminRole.name} (${adminRole.code})\n`);
    }

    // 4. 为 admin 用户分配 admin 角色
    console.log(`🔗 步骤 4: 为 admin 用户分配 admin 角色...`);
    const existingUserRole = await prisma.userRole.findUnique({
      where: {
        userId_roleId: {
          userId: adminUser.id,
          roleId: adminRole.id,
        },
      },
    });

    if (!existingUserRole) {
      await prisma.userRole.create({
        data: {
          userId: adminUser.id,
          roleId: adminRole.id,
        },
      });
      console.log(`✅ 角色分配成功\n`);
    } else {
      console.log(`✅ 用户已拥有 admin 角色\n`);
    }

    // 5. 初始化租户权限（如果不存在则创建）
    console.log(`📝 步骤 5: 初始化租户权限...`);
    const createdPermissions = [];

    for (const perm of permissions) {
      // 检查权限是否已存在
      const existingPermission = await prisma.permission.findFirst({
        where: {
          tenantId: tenant.id,
          code: perm.code,
        },
      });

      if (!existingPermission) {
        // 创建权限
        const permission = await prisma.permission.create({
          data: {
            tenantId: tenant.id,
            code: perm.code,
            resource: perm.resource,
            action: perm.action,
            name: perm.name,
            description: perm.description,
            validState: 1,
          },
        });
        createdPermissions.push(permission);
        console.log(`  ✓ 创建权限: ${perm.code} - ${perm.name}`);
      } else {
        // 更新现有权限（确保信息是最新的）
        const permission = await prisma.permission.update({
          where: { id: existingPermission.id },
          data: {
            name: perm.name,
            resource: perm.resource,
            action: perm.action,
            description: perm.description,
            validState: 1,
          },
        });
        createdPermissions.push(permission);
      }
    }

    console.log(`✅ 共确保 ${createdPermissions.length} 个权限存在\n`);

    // 获取租户的所有有效权限
    const tenantPermissions = await prisma.permission.findMany({
      where: {
        tenantId: tenant.id,
        validState: 1,
      },
    });

    // 6. 为 admin 角色分配所有权限
    console.log(`🔗 步骤 6: 为 admin 角色分配所有权限...`);
    const existingRolePermissions = await prisma.rolePermission.findMany({
      where: { roleId: adminRole.id },
      select: { permissionId: true },
    });
    const existingPermissionIds = new Set(
      existingRolePermissions.map((rp) => rp.permissionId),
    );

    let addedPermissionCount = 0;
    for (const permission of tenantPermissions) {
      if (!existingPermissionIds.has(permission.id)) {
        await prisma.rolePermission.create({
          data: {
            roleId: adminRole.id,
            permissionId: permission.id,
          },
        });
        addedPermissionCount++;
      }
    }

    if (addedPermissionCount > 0) {
      console.log(`✅ 为 admin 角色添加了 ${addedPermissionCount} 个权限`);
      console.log(`✅ admin 角色现在拥有 ${tenantPermissions.length} 个权限\n`);
    } else {
      console.log(
        `✅ admin 角色已拥有所有权限（${tenantPermissions.length} 个）\n`,
      );
    }

    // 7. 为租户分配所有菜单
    console.log(`📋 步骤 7: 为租户分配所有菜单...`);

    // 获取所有有效菜单
    const allMenus = await prisma.menu.findMany({
      where: {
        validState: 1,
      },
      orderBy: [{ sort: 'asc' }, { id: 'asc' }],
    });

    if (allMenus.length === 0) {
      console.log('⚠️  警告: 数据库中没有任何菜单');
      console.log('   请先运行 pnpm init:menus 初始化菜单\n');
    } else {
      console.log(`   找到 ${allMenus.length} 个菜单\n`);

      // 获取租户已分配的菜单
      const existingTenantMenus = await prisma.tenantMenu.findMany({
        where: {
          tenantId: tenant.id,
        },
        select: {
          menuId: true,
        },
      });

      const existingMenuIds = new Set(existingTenantMenus.map((tm) => tm.menuId));

      // 为租户分配所有菜单
      let addedMenuCount = 0;
      const menuNames: string[] = [];

      for (const menu of allMenus) {
        if (!existingMenuIds.has(menu.id)) {
          await prisma.tenantMenu.create({
            data: {
              tenantId: tenant.id,
              menuId: menu.id,
            },
          });
          addedMenuCount++;
          menuNames.push(menu.name);
        }
      }

      if (addedMenuCount > 0) {
        console.log(`✅ 为租户添加了 ${addedMenuCount} 个菜单:`);
        menuNames.forEach((name) => {
          console.log(`   ✓ ${name}`);
        });
        console.log(`\n✅ 租户现在拥有 ${allMenus.length} 个菜单\n`);
      } else {
        console.log(`✅ 租户已拥有所有菜单（${allMenus.length} 个）\n`);
      }
    }

    // 8. 验证结果
    console.log('🔍 步骤 8: 验证结果...');
    const userWithRoles = await prisma.user.findUnique({
      where: { id: adminUser.id },
      include: {
        roles: {
          include: {
            role: {
              include: {
                permissions: {
                  include: {
                    permission: true,
                  },
                },
              },
            },
          },
        },
      },
    });

    const roleCodes = userWithRoles?.roles.map((ur) => ur.role.code) || [];
    const permissionCodes = new Set<string>();
    userWithRoles?.roles.forEach((ur) => {
      ur.role.permissions.forEach((rp) => {
        permissionCodes.add(rp.permission.code);
      });
    });

    const finalMenus = await prisma.tenantMenu.findMany({
      where: {
        tenantId: tenant.id,
      },
      include: {
        menu: true,
      },
    });

    console.log(`\n📊 初始化结果:`);
    console.log('========================================');
    console.log('租户信息:');
    console.log(`  租户名称: ${tenant.name}`);
    console.log(`  租户编码: ${tenant.code}`);
    console.log(`  访问链接: http://your-domain.com/?tenant=${tenant.code}`);
    console.log('========================================');
    console.log('管理员登录信息:');
    console.log(`  用户名: ${adminUser.username}`);
    console.log(`  密码: ${password}`);
    console.log(`  昵称: ${adminUser.nickname}`);
    console.log(`  邮箱: ${adminUser.email}`);
    console.log('========================================');
    console.log('角色和权限:');
    console.log(`  角色: ${roleCodes.join(', ')}`);
    console.log(`  权限数量: ${permissionCodes.size}`);
    if (permissionCodes.size > 0 && permissionCodes.size <= 20) {
      console.log(`  权限列表:`);
      Array.from(permissionCodes)
        .sort()
        .forEach((code) => {
          console.log(`    - ${code}`);
        });
    } else if (permissionCodes.size > 20) {
      console.log(`  权限列表（前20个）:`);
      Array.from(permissionCodes)
        .sort()
        .slice(0, 20)
        .forEach((code) => {
          console.log(`    - ${code}`);
        });
      console.log(`  ... 还有 ${permissionCodes.size - 20} 个权限`);
    }
    console.log('========================================');
    console.log('菜单分配:');
    console.log(`  已分配菜单数: ${finalMenus.length}`);
    if (finalMenus.length > 0) {
      const topLevelMenus = finalMenus.filter((tm) => !tm.menu.parentId);
      console.log(`  顶级菜单数: ${topLevelMenus.length}`);
    }
    console.log('========================================');
    console.log(`\n✅ 租户菜单和权限初始化完成！`);
    console.log(`\n💡 现在可以使用以下凭据登录:`);
    console.log(`   租户编码: ${tenant.code}`);
    console.log(`   用户名: ${adminUser.username}`);
    console.log(`   密码: ${password}`);
  } catch (error) {
    console.error('❌ 初始化失败:', error);
    throw error;
  } finally {
    await prisma.$disconnect();
  }
}

// 获取命令行参数
const tenantCode = process.argv[2];

if (!tenantCode) {
  console.error('❌ 错误: 请提供租户编码作为参数');
  console.error('   使用方法:');
  console.error('     pnpm init:tenant-menu-permissions <租户编码>');
  console.error('   示例:');
  console.error('     pnpm init:tenant-menu-permissions tenant1');
  process.exit(1);
}

// 执行初始化
initTenantMenuAndPermissions(tenantCode)
  .then(() => {
    console.log('\n🎉 初始化脚本执行完成！');
    process.exit(0);
  })
  .catch((error) => {
    console.error('\n💥 初始化脚本执行失败:', error);
    process.exit(1);
  });

