import { PrismaClient } from '@prisma/client'
import bcrypt from 'bcryptjs'
import { encrypt } from '../src/lib/crypto'

const prisma = new PrismaClient()

// 社保计算（与 payroll.service.ts 一致）
function calcSocial(base: number, config: any) {
  const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
  const socialEmp = actualBase * (config.pensionEmp + config.medicalEmp + config.unemploymentEmp) / 100
  const socialOrg = actualBase * (config.pensionOrg + config.medicalOrg + config.unemploymentOrg + config.injuryOrg + config.maternityOrg) / 100
  return { socialEmp: Math.round(socialEmp * 100) / 100, socialOrg: Math.round(socialOrg * 100) / 100 }
}
function calcHousing(base: number, config: any) {
  const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
  const housingEmp = actualBase * config.housingEmp / 100
  const housingOrg = actualBase * config.housingOrg / 100
  return { housingEmp: Math.round(housingEmp * 100) / 100, housingOrg: Math.round(housingOrg * 100) / 100 }
}
function calcTax(taxableIncome: number): number {
  if (taxableIncome <= 0) return 0
  let tax = 0
  if (taxableIncome <= 36000) tax = taxableIncome * 0.03
  else if (taxableIncome <= 144000) tax = taxableIncome * 0.10 - 2520
  else if (taxableIncome <= 300000) tax = taxableIncome * 0.20 - 16920
  else if (taxableIncome <= 420000) tax = taxableIncome * 0.25 - 31920
  else if (taxableIncome <= 660000) tax = taxableIncome * 0.30 - 52920
  else if (taxableIncome <= 960000) tax = taxableIncome * 0.35 - 85920
  else tax = taxableIncome * 0.45 - 181920
  return Math.max(0, Math.round(tax * 100) / 100)
}

// 9名员工完整数据
const EMPLOYEES = [
  { name: '张伟', gender: '男', dept: '技术部', phone: '13900000001', idCard: '310101199001011234', salary: 18000, hireDate: '2023-03-01', socialBase: 18000, housingBase: 18000, specialDeduction: 2000, contractType: 'FIXED', years: 3, probation: 3, probationSalary: 14400, bank: '工商银行', account: '6222021234567890001', emergency: '张父', emergencyPhone: '13800001001', address: '上海市浦东新区张江路100号' },
  { name: '李娜', gender: '女', dept: '技术部', phone: '13900000002', idCard: '310102199203052345', salary: 15000, hireDate: '2023-06-15', socialBase: 15000, housingBase: 15000, specialDeduction: 1000, contractType: 'FIXED', years: 3, probation: 2, probationSalary: 12000, bank: '建设银行', account: '6227001234567890002', emergency: '李母', emergencyPhone: '13800001002', address: '上海市徐汇区漕河泾50号', pregnant: true },
  { name: '王强', gender: '男', dept: '销售部', phone: '13900000003', idCard: '310103198812103456', salary: 12000, hireDate: '2024-01-10', socialBase: 12000, housingBase: 12000, specialDeduction: 3000, contractType: 'FIXED', years: 3, probation: 3, probationSalary: 9600, bank: '招商银行', account: '6225881234567890003', emergency: '王妻', emergencyPhone: '13800001003', address: '上海市闵行区莘庄路200号' },
  { name: '赵敏', gender: '女', dept: '人事部', phone: '13900000004', idCard: '310104199506154567', salary: 10000, hireDate: '2022-09-01', socialBase: 10000, housingBase: 10000, specialDeduction: 1500, contractType: 'UNFIXED', years: 0, probation: 0, probationSalary: 0, bank: '农业银行', account: '6228481234567890004', emergency: '赵父', emergencyPhone: '13800001004', address: '上海市黄浦区南京东路300号' },
  { name: '陈刚', gender: '男', dept: '销售部', phone: '13900000005', idCard: '310105199907205678', salary: 8000, hireDate: '2024-07-01', socialBase: 8000, housingBase: 8000, specialDeduction: 0, contractType: 'FIXED', years: 3, probation: 2, probationSalary: 6400, bank: '中国银行', account: '6217001234567890005', emergency: '陈母', emergencyPhone: '13800001005', address: '上海市杨浦区五角场400号' },
  { name: '刘洋', gender: '男', dept: '技术部', phone: '13900000006', idCard: '310106198504016789', salary: 22000, hireDate: '2021-04-01', socialBase: 33891, housingBase: 33891, specialDeduction: 4000, contractType: 'UNFIXED', years: 0, probation: 0, probationSalary: 0, bank: '交通银行', account: '6222601234567890006', emergency: '刘妻', emergencyPhone: '13800001006', address: '上海市长宁区中山公园500号' },
  { name: '周婷', gender: '女', dept: '财务部', phone: '13900000007', idCard: '310107199311157890', salary: 13000, hireDate: '2023-11-15', socialBase: 13000, housingBase: 13000, specialDeduction: 2500, contractType: 'FIXED', years: 3, probation: 2, probationSalary: 10400, bank: '浦发银行', account: '6225161234567890007', emergency: '周父', emergencyPhone: '13800001007', address: '上海市静安区南京西路600号' },
  { name: '孙磊', gender: '男', dept: '技术部', phone: '13900000008', idCard: '310108199008018901', salary: 16000, hireDate: '2022-06-01', socialBase: 16000, housingBase: 16000, specialDeduction: 1000, contractType: 'FIXED', years: 3, probation: 3, probationSalary: 12800, bank: '民生银行', account: '6226161234567890008', emergency: '孙母', emergencyPhone: '13800001008', address: '上海市虹口区四川北路700号' },
  { name: '吴芳', gender: '女', dept: '销售部', phone: '13900000009', idCard: '310109199702159012', salary: 9000, hireDate: '2025-02-15', socialBase: 9000, housingBase: 9000, specialDeduction: 500, contractType: 'FIXED', years: 3, probation: 2, probationSalary: 7200, bank: '光大银行', account: '6226621234567890009', emergency: '吴夫', emergencyPhone: '13800001009', address: '上海市宝山区牡丹江路800号' },
]

async function main() {
  // 1. 清空所有数据（按依赖顺序删除）
  console.log('清空现有数据...')
  await prisma.notificationLog.deleteMany()
  await prisma.auditLog.deleteMany()
  await prisma.batchEntry.deleteMany()
  await prisma.payrollBatch.deleteMany()
  await prisma.payslipItem.deleteMany()
  await prisma.salaryChangeRecord.deleteMany()
  await prisma.payslip.deleteMany()
  await prisma.overtimeRecord.deleteMany()
  await prisma.terminationRecord.deleteMany()
  await prisma.riskItem.deleteMany()
  await prisma.employeeAttachment.deleteMany()
  await prisma.disciplinaryRecord.deleteMany()
  await prisma.attendanceRecord.deleteMany()
  await prisma.trainingRecord.deleteMany()
  await prisma.performanceRecord.deleteMany()
  await prisma.laborContract.deleteMany()
  await prisma.contractConfirmLink.deleteMany()
  await prisma.onboardingLink.deleteMany()
  await prisma.employee.deleteMany()
  await prisma.socialInsuranceConfig.deleteMany()
  await prisma.notificationSetting.deleteMany()
  await prisma.user.deleteMany()
  await prisma.organization.deleteMany()
  console.log('数据已清空')

  // 2. 创建企业
  const org = await prisma.organization.create({
    data: {
      name: '智云科技有限公司',
      plan: 'PRO',
      maxEmployees: 50,
      city: '上海',
      payrollDays: [10],
    },
  })
  console.log('企业已创建:', org.name)

  // 3. 创建管理员
  const passwordHash = await bcrypt.hash('12345678', 10)
  const admin = await prisma.user.create({
    data: {
      orgId: org.id,
      phone: '13800000001',
      name: '管理员',
      passwordHash,
      role: 'ADMIN',
    },
  })
  console.log('管理员已创建:', admin.phone)

  // 4. 创建社保配置（上海标准）
  await prisma.socialInsuranceConfig.create({
    data: {
      orgId: org.id,
      city: '上海',
      pensionOrg: 16,
      pensionEmp: 8,
      medicalOrg: 9.8,
      medicalEmp: 2,
      unemploymentOrg: 0.5,
      unemploymentEmp: 0.5,
      injuryOrg: 0.2,
      maternityOrg: 0.8,
      baseMin: 7384,
      baseMax: 36921,
      effectiveFrom: '2025-07',
      createdBy: admin.id,
    },
  })
  console.log('社保配置已创建')

  // 4.5 创建公积金配置（上海标准）
  await prisma.housingFundConfig.create({
    data: {
      orgId: org.id,
      city: '上海',
      housingOrg: 7,
      housingEmp: 7,
      baseMin: 7384,
      baseMax: 36921,
      effectiveFrom: '2025-07',
      createdBy: admin.id,
    },
  })
  console.log('公积金配置已创建')

  // 4.6 创建河北省社保配置（2025年度标准）
  await prisma.socialInsuranceConfig.create({
    data: {
      orgId: org.id,
      city: '石家庄',
      pensionOrg: 16,
      pensionEmp: 8,
      medicalOrg: 8,
      medicalEmp: 2,
      unemploymentOrg: 0.7,
      unemploymentEmp: 0.3,
      injuryOrg: 0.3,
      maternityOrg: 0.5,
      baseMin: 3920,
      baseMax: 19602,
      medicalBaseMin: 3920,
      medicalBaseMax: 19602,
      extraInsurances: [
        { name: '大病医疗', baseType: 'fixed', fixedAmount: 5, empFixedAmount: 0, orgRate: 0, empRate: 0 },
        { name: '长期护理险', baseType: 'pension', orgRate: 0.1, empRate: 0.1 },
      ],
      effectiveFrom: '2025-07',
      createdBy: admin.id,
    },
  })
  console.log('河北省社保配置已创建')

  // 4.7 创建河北省公积金配置
  await prisma.housingFundConfig.create({
    data: {
      orgId: org.id,
      city: '石家庄',
      housingOrg: 12,
      housingEmp: 12,
      baseMin: 3920,
      baseMax: 19602,
      effectiveFrom: '2025-07',
      createdBy: admin.id,
    },
  })
  console.log('河北省公积金配置已创建')

  // 5. 创建通知设置
  await prisma.notificationSetting.create({
    data: {
      orgId: org.id,
      contractExpiry: true,
      expiryDays: 30,
      contractUnsigned: true,
      overtimeAlert: true,
      payslipReady: true,
      payrollDay: 10,
      socialInsDay: 15,
      housingFundDay: 15,
      taxDay: 15,
    },
  })

  // 6. 创建薪酬模版（预置项）
  const defaultItems: { name: string; code: string; type: 'INPUT' | 'CALCULATED'; formula: string | null; order: number; isDefault: boolean; isEditable: boolean }[] = [
    { name: '基本工资', code: 'baseSalary', type: 'INPUT', formula: null, order: 1, isDefault: true, isEditable: true },
    { name: '加班费', code: 'overtimePay', type: 'CALCULATED', formula: 'weekdayOvertimePay + weekendOvertimePay + holidayOvertimePay', order: 2, isDefault: true, isEditable: false },
    { name: '津贴补贴', code: 'allowance', type: 'INPUT', formula: null, order: 3, isDefault: true, isEditable: true },
    { name: '奖金', code: 'bonus', type: 'INPUT', formula: null, order: 4, isDefault: true, isEditable: true },
    { name: '扣款', code: 'deduction', type: 'INPUT', formula: null, order: 5, isDefault: true, isEditable: true },
    { name: '应发合计', code: 'totalPay', type: 'CALCULATED', formula: 'baseSalary + overtimePay + allowance + bonus - deduction', order: 6, isDefault: true, isEditable: false },
    { name: '个人社保', code: 'socialEmp', type: 'CALCULATED', formula: 'SOCIAL_EMP', order: 7, isDefault: true, isEditable: false },
    { name: '个人公积金', code: 'housingEmp', type: 'CALCULATED', formula: 'HOUSING_EMP', order: 8, isDefault: true, isEditable: false },
    { name: '个人所得税', code: 'tax', type: 'CALCULATED', formula: 'TAX', order: 9, isDefault: true, isEditable: false },
    { name: '实发工资', code: 'netPay', type: 'CALCULATED', formula: 'totalPay - socialEmp - housingEmp - tax', order: 10, isDefault: true, isEditable: false },
  ]
  for (const item of defaultItems) {
    await prisma.payslipItem.create({
      data: { orgId: org.id, ...item },
    })
  }
  console.log('薪酬模版已创建')

  // 7. 创建9名员工 + 合同
  for (let i = 0; i < EMPLOYEES.length; i++) {
    const e = EMPLOYEES[i]
    const emp = await prisma.employee.create({
      data: {
        orgId: org.id,
        name: e.name,
        department: e.dept,
        hireDate: new Date(e.hireDate),
        monthlySalary: encrypt(String(e.salary)),
        phone: e.phone,
        idCardNumber: encrypt(e.idCard),
        gender: e.gender,
        socialInsBase: e.socialBase,
        housingFundBase: e.housingBase,
        specialDeduction: e.specialDeduction,
        bankName: e.bank,
        bankAccount: encrypt(e.account),
        emergencyContact: e.emergency,
        emergencyPhone: e.emergencyPhone,
        address: e.address,
        isPregnant: e.pregnant || false,
        createdBy: admin.id,
      },
    })

    // 创建合同
    const startDate = new Date(e.hireDate)
    const endDate = e.contractType === 'FIXED'
      ? new Date(startDate.getFullYear() + e.years, startDate.getMonth(), startDate.getDate() - 1)
      : null

    await prisma.laborContract.create({
      data: {
        orgId: org.id,
        employeeId: emp.id,
        signDate: new Date(e.hireDate),
        startDate,
        endDate,
        contractType: e.contractType as any,
        signMethod: 'PAPER',
        contractYears: e.years,
        probationMonths: e.probation,
        probationSalary: e.probationSalary,
        createdBy: admin.id,
      },
    })
    console.log(`员工 ${i + 1}/9 已创建: ${e.name} - ${e.dept} - ¥${e.salary}/月`)
  }

  // 8. 生成 1-6 月历史工资条（已发布），使 7 月累计预扣个税有 YTD 数据
  console.log('\n生成 1-6 月历史工资条...')
  const socialConfig = await prisma.socialInsuranceConfig.findFirst({ where: { orgId: org.id, isCurrent: true } })
  const housingConfig = await prisma.housingFundConfig.findFirst({ where: { orgId: org.id, isCurrent: true } })
  const allEmployees = await prisma.employee.findMany({ where: { orgId: org.id } })

  for (const emp of allEmployees) {
    // 跳过 2026 年之后入职的员工
    const hireYear = emp.hireDate.getFullYear()
    if (hireYear > 2026) continue
    const hireMonth = hireYear === 2026 ? emp.hireDate.getMonth() + 1 : 1

    let ytdIncome = 0, ytdSocialEmp = 0, ytdHousingEmp = 0, ytdTaxDeducted = 0

    for (let m = 1; m <= 6; m++) {
      if (m < hireMonth) continue
      const monthStr = `2026-${String(m).padStart(2, '0')}`
      const baseSalary = emp.socialInsBase || 0  // 用社保基数作为基本工资（简化）
      const social = calcSocial(emp.socialInsBase || baseSalary, socialConfig)
      const housing = calcHousing(emp.housingFundBase || baseSalary, housingConfig || socialConfig)
      const totalPay = baseSalary
      const specialDeduction = emp.specialDeduction * m

      ytdIncome += totalPay
      ytdSocialEmp += social.socialEmp
      ytdHousingEmp += housing.housingEmp

      const ytdTaxableIncome = Math.max(0, ytdIncome - 5000 * m - ytdSocialEmp - ytdHousingEmp - specialDeduction)
      const ytdTax = calcTax(ytdTaxableIncome)
      const monthTax = Math.max(0, Math.round((ytdTax - ytdTaxDeducted) * 100) / 100)
      ytdTaxDeducted += monthTax

      const netPay = Math.round((totalPay - social.socialEmp - housing.housingEmp - monthTax) * 100) / 100

      await prisma.payslip.create({
        data: {
          org: { connect: { id: org.id } },
          employee: { connect: { id: emp.id } },
          month: monthStr,
          baseSalary,
          overtimePay: 0,
          allowance: 0,
          deduction: 0,
          bonus: 0,
          totalPay,
          socialEmp: social.socialEmp,
          housingEmp: housing.housingEmp,
          tax: monthTax,
          netPay,
          ytdIncome,
          ytdTaxDeducted,
          ytdSocialEmp,
          ytdHousingEmp,
          status: 'PUBLISHED',
          publishedAt: new Date(`${monthStr}-10T10:00:00Z`),
          confirmedAt: new Date(`${monthStr}-12T10:00:00Z`),
        },
      })
    }
    console.log(`  ${emp.name}: 1-6月工资条已生成`)
  }

  console.log('\n===== 示例数据创建完成 =====')
  console.log(`企业: ${org.name}`)
  console.log(`管理员: 13800000001 / 密码: 12345678`)
  console.log(`员工: ${EMPLOYEES.length} 人`)
  console.log('社保配置: 上海标准')
  console.log('薪酬模版: 10项预置')
}

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