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

const prisma = new PrismaClient();

async function main() {
  const tenant = await prisma.tenant.upsert({
    where: { code: 'default' },
    update: {},
    create: { name: '默认租户', code: 'default' },
  });

  const china = await prisma.region.upsert({
    where: { code: '100000' },
    update: {},
    create: { code: '100000', name: '全国', level: 0, longitude: 104.195397, latitude: 35.86166 },
  });

  const province = await prisma.region.upsert({
    where: { code: '110000' },
    update: {},
    create: { code: '110000', name: '北京市', level: 1, parentId: china.id, longitude: 116.407526, latitude: 39.90403 },
  });

  const city = await prisma.region.upsert({
    where: { code: '110100' },
    update: {},
    create: { code: '110100', name: '北京市', level: 2, parentId: province.id, longitude: 116.407526, latitude: 39.90403 },
  });

  const district = await prisma.region.upsert({
    where: { code: '110101' },
    update: {},
    create: { code: '110101', name: '东城区', level: 3, parentId: city.id, longitude: 116.416357, latitude: 39.928353 },
  });

  const shanghai = await prisma.region.upsert({
    where: { code: '310000' },
    update: {},
    create: { code: '310000', name: '上海市', level: 1, parentId: china.id, longitude: 121.473701, latitude: 31.230416 },
  });
  const shanghaiCity = await prisma.region.upsert({
    where: { code: '310100' },
    update: {},
    create: { code: '310100', name: '上海市', level: 2, parentId: shanghai.id, longitude: 121.473701, latitude: 31.230416 },
  });
  const pudong = await prisma.region.upsert({
    where: { code: '310115' },
    update: {},
    create: { code: '310115', name: '浦东新区', level: 3, parentId: shanghaiCity.id, longitude: 121.544346, latitude: 31.221461 },
  });
  const guangdong = await prisma.region.upsert({
    where: { code: '440000' },
    update: {},
    create: { code: '440000', name: '广东省', level: 1, parentId: china.id, longitude: 113.266887, latitude: 23.133306 },
  });
  const guangzhou = await prisma.region.upsert({
    where: { code: '440100' },
    update: {},
    create: { code: '440100', name: '广州市', level: 2, parentId: guangdong.id, longitude: 113.264385, latitude: 23.129112 },
  });
  const tianhe = await prisma.region.upsert({
    where: { code: '440106' },
    update: {},
    create: { code: '440106', name: '天河区', level: 3, parentId: guangzhou.id, longitude: 113.361597, latitude: 23.124817 },
  });
  const zhejiang = await prisma.region.upsert({
    where: { code: '330000' },
    update: {},
    create: { code: '330000', name: '浙江省', level: 1, parentId: china.id, longitude: 120.152575, latitude: 30.266619 },
  });
  const hangzhou = await prisma.region.upsert({
    where: { code: '330100' },
    update: {},
    create: { code: '330100', name: '杭州市', level: 2, parentId: zhejiang.id, longitude: 120.15507, latitude: 30.274085 },
  });
  const xihu = await prisma.region.upsert({
    where: { code: '330106' },
    update: {},
    create: { code: '330106', name: '西湖区', level: 3, parentId: hangzhou.id, longitude: 120.130396, latitude: 30.259242 },
  });

  const permissions = [
    ['tenants:manage', '租户管理', 'MENU', '/system/tenants'],
    ['dashboard:view', '数据看板', 'MENU', '/dashboard'],
    ['map:view', '地图监控', 'MENU', '/map'],
    ['lamps:manage', '路灯管理', 'MENU', '/lamps'],
    ['alarms:manage', '报警管理', 'MENU', '/alarms'],
    ['system:manage', '系统管理', 'MENU', '/system/users'],
  ] as const;

  for (const [code, name, type, path] of permissions) {
    await prisma.permission.upsert({
      where: { code },
      update: {},
      create: { code, name, type, path },
    });
  }

  let platformRole = await prisma.role.findFirst({ where: { tenantId: null, code: 'platform_super_admin' } });
  if (!platformRole) {
    platformRole = await prisma.role.create({
      data: {
        name: '平台超级管理员',
        code: 'platform_super_admin',
        description: '仅用于平台租户管理，不在页面中配置',
      },
    });
  }
  const tenantManagePermission = await prisma.permission.findUnique({ where: { code: 'tenants:manage' } });
  if (tenantManagePermission) {
    await prisma.rolePermission.createMany({
      data: [{ roleId: platformRole.id, permissionId: tenantManagePermission.id }],
      skipDuplicates: true,
    });
  }
  let platformAdmin = await prisma.user.findFirst({ where: { tenantId: null, username: 'admin' } });
  if (!platformAdmin) {
    platformAdmin = await prisma.user.create({
      data: {
        username: 'admin',
        passwordHash: await bcrypt.hash('admin123456', 10),
        name: '平台超级管理员',
        roles: { create: [{ roleId: platformRole.id }] },
      },
    });
  }

  let role = await prisma.role.findFirst({ where: { tenantId: tenant.id, code: { in: ['tenant_admin', 'super_admin'] } } });
  if (role) {
    role = await prisma.role.update({
      where: { id: role.id },
      data: { name: '租户管理员', code: 'tenant_admin', description: '租户初始化管理员角色' },
    });
  } else {
    role = await prisma.role.create({
      data: { name: '租户管理员', code: 'tenant_admin', description: '租户初始化管理员角色', tenantId: tenant.id },
    });
  }

  const allPermissions = await prisma.permission.findMany({ where: { code: { not: 'tenants:manage' } } });
  await prisma.rolePermission.createMany({
    data: allPermissions.map((permission) => ({ roleId: role.id, permissionId: permission.id })),
    skipDuplicates: true,
  });
  await prisma.roleRegionScope.createMany({
    data: [{ roleId: role.id, regionId: china.id }],
    skipDuplicates: true,
  });

  let admin = await prisma.user.findFirst({ where: { tenantId: tenant.id, username: 'admin' } });
  if (admin) {
    admin = await prisma.user.update({
      where: { id: admin.id },
      data: { name: '系统管理员' },
    });
  } else {
    admin = await prisma.user.create({
      data: {
      username: 'admin',
      passwordHash: await bcrypt.hash('admin123456', 10),
      name: '系统管理员',
      tenantId: tenant.id,
      roles: { create: [{ roleId: role.id }] },
      regionScopes: { create: [{ regionId: china.id }] },
      },
    });
  }

  const sampleLamps = [
    ['BJ-DC-0001', '东城区智慧路灯 A01', district.id, '北京市东城区东长安街', 116.416357, 39.928353, '单灯', 'NORMAL', 'ONLINE'],
    ['BJ-DC-0002', '东城区智慧路灯 A02', district.id, '北京市东城区王府井大街', 116.411568, 39.908823, '单灯', 'FAULT', 'ONLINE'],
    ['BJ-DC-0003', '东城区智慧路灯 A03', district.id, '北京市东城区朝阳门内大街', 116.433235, 39.924463, '单灯', 'MAINTENANCE', 'OFFLINE'],
    ['SH-PD-0001', '浦东新区智慧路灯 P01', pudong.id, '上海市浦东新区世纪大道', 121.544346, 31.221461, '单灯', 'NORMAL', 'ONLINE'],
    ['SH-PD-0002', '浦东新区智慧路灯 P02', pudong.id, '上海市浦东新区陆家嘴环路', 121.502833, 31.239101, '单灯', 'FAULT', 'ONLINE'],
    ['GZ-TH-0001', '天河区智慧路灯 T01', tianhe.id, '广州市天河区体育西路', 113.321478, 23.132191, '单灯', 'NORMAL', 'ONLINE'],
    ['GZ-TH-0002', '天河区智慧路灯 T02', tianhe.id, '广州市天河区珠江新城', 113.32459, 23.119962, '单灯', 'OFFLINE', 'OFFLINE'],
    ['HZ-XH-0001', '西湖区智慧路灯 X01', xihu.id, '杭州市西湖区文三路', 120.130396, 30.279242, '单灯', 'NORMAL', 'ONLINE'],
    ['HZ-XH-0002', '西湖区智慧路灯 X02', xihu.id, '杭州市西湖区曙光路', 120.14321, 30.26311, '单灯', 'FAULT', 'ONLINE'],
  ] as const;

  const lampMap = new Map<string, { id: string; regionId: string }>();
  for (const [code, name, regionId, address, longitude, latitude, deviceType, status, onlineStatus] of sampleLamps) {
    const lamp = await prisma.streetLamp.upsert({
      where: { code },
      update: { name, regionId, address, longitude, latitude, deviceType, status, onlineStatus },
      create: {
        code,
        name,
        tenantId: tenant.id,
        regionId,
        address,
        longitude,
        latitude,
        deviceType,
        status,
        onlineStatus,
        lastReportedAt: onlineStatus === 'ONLINE' ? new Date(Date.now() - Math.random() * 1000 * 60 * 45) : undefined,
      },
    });
    lampMap.set(code, { id: lamp.id, regionId: lamp.regionId });
  }

  const sampleAlarms = [
    ['sample-alarm-001', 'BJ-DC-0001', 'POWER_FAILURE', '路灯断电报警', '设备供电异常，请尽快排查配电箱。', 'HIGH', 'OPEN', 18],
    ['sample-alarm-002', 'BJ-DC-0002', 'LAMP_FAULT', '灯具故障报警', '灯具电流异常，疑似光源损坏。', 'MEDIUM', 'PROCESSING', 65],
    ['sample-alarm-003', 'SH-PD-0002', 'DOOR_OPEN', '灯杆箱门开启', '箱门异常开启，存在安全风险。', 'CRITICAL', 'OPEN', 12],
    ['sample-alarm-004', 'GZ-TH-0002', 'OFFLINE', '设备离线报警', '设备超过 30 分钟未上报数据。', 'HIGH', 'OPEN', 42],
    ['sample-alarm-005', 'HZ-XH-0002', 'VOLTAGE_ABNORMAL', '电压异常报警', '输入电压波动超过阈值。', 'MEDIUM', 'PROCESSING', 95],
    ['sample-alarm-006', 'SH-PD-0001', 'BRIGHTNESS_LOW', '亮度不足报警', '夜间亮度低于策略要求。', 'LOW', 'RESOLVED', 240],
  ] as const;

  for (const [sourceAlarmId, lampCode, type, title, description, level, status, minutesAgo] of sampleAlarms) {
    const lamp = lampMap.get(lampCode);
    if (!lamp) {
      continue;
    }

    await prisma.alarm.upsert({
      where: { sourceAlarmId },
      update: { status },
      create: {
        sourceAlarmId,
        tenantId: tenant.id,
        lampId: lamp.id,
        regionId: lamp.regionId,
        type,
        title,
        description,
        level,
        status,
        occurredAt: new Date(Date.now() - minutesAgo * 60 * 1000),
        recoveredAt: status === 'RESOLVED' ? new Date(Date.now() - 60 * 60 * 1000) : undefined,
        events: { create: [{ eventType: 'CREATED', payload: { seededBy: platformAdmin.username, tenantAdmin: admin.username } }] },
      },
    });
  }
}

main()
  .then(async () => prisma.$disconnect())
  .catch(async (error) => {
    console.error(error);
    await prisma.$disconnect();
    process.exit(1);
  });
