import { Router, Response, NextFunction } from 'express'
import prisma from '../lib/prisma'
import { authMiddleware, AuthRequest } from '../middleware/auth'
import { decrypt } from '../lib/crypto'
import { z } from 'zod'
import OpenAI from 'openai'

function decryptIdCard(encrypted: string | null): string | null {
  if (!encrypted) return null
  try {
    if (!encrypted.includes(':')) return encrypted
    return decrypt(encrypted)
  } catch { return null }
}

const router = Router()
router.use(authMiddleware)

const socialConfigFields = {
  city: z.string().min(1),
  pensionOrg: z.number().optional(),
  pensionEmp: z.number().optional(),
  medicalOrg: z.number().optional(),
  medicalEmp: z.number().optional(),
  medicalOrgExtra: z.number().min(0).optional(),
  medicalEmpExtra: z.number().min(0).optional(),
  unemploymentOrg: z.number().optional(),
  unemploymentEmp: z.number().optional(),
  injuryOrg: z.number().optional(),
  maternityOrg: z.number().optional(),
  baseMin: z.number().optional(),
  baseMax: z.number().optional(),
  medicalBaseMin: z.number().optional(),
  medicalBaseMax: z.number().optional(),
  extraInsurances: z.any().optional(),
  minWage: z.number().min(0).optional(),
}

const housingConfigFields = {
  city: z.string().min(1),
  accountType: z.string().optional(),
  housingOrg: z.number().optional(),
  housingEmp: z.number().optional(),
  baseMin: z.number().optional(),
  baseMax: z.number().optional(),
}

// ==========================================
// 账户管理 API（新）
// ==========================================

const accountSchema = z.object({
  type: z.enum(['SOCIAL', 'HOUSING']),
  name: z.string().min(1),
  city: z.string().min(1),
  accountNo: z.string().optional(),
  bankName: z.string().optional(),
  bankAccount: z.string().optional(),
  orgName: z.string().optional(),
  orgCode: z.string().optional(),
  accountType: z.string().optional(),
  paymentDay: z.number().int().min(1).max(28).optional(),
  isDefault: z.boolean().optional(),
  remark: z.string().optional(),
})

// 账户列表
router.get('/accounts', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const type = req.query.type as string | undefined
    const where: any = { orgId }
    if (type) where.type = type
    const accounts = await prisma.socialAccount.findMany({
      where,
      orderBy: [{ type: 'asc' }, { isDefault: 'desc' }, { city: 'asc' }],
      include: {
        _count: { select: { socialRecords: true, housingRecords: true, deptSocialAccounts: true, deptHousingAccounts: true } },
      },
    })
    res.json({ success: true, data: accounts })
  } catch (err) { next(err) }
})

// 新建账户
router.post('/accounts', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const data = accountSchema.parse(req.body)
    // 如果设为默认，先取消同 type 其他默认
    if (data.isDefault) {
      await prisma.socialAccount.updateMany({ where: { orgId, type: data.type, isDefault: true }, data: { isDefault: false } })
    }
    const account = await prisma.socialAccount.create({
      data: { ...data, orgId, createdBy: req.user!.id },
    })
    res.json({ success: true, data: account })
  } catch (err) { next(err) }
})

// 编辑账户
router.put('/accounts/:id', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const data = accountSchema.partial().parse(req.body)
    if (data.isDefault) {
      const account = await prisma.socialAccount.findUnique({ where: { id: req.params.id } })
      await prisma.socialAccount.updateMany({ where: { orgId, type: account?.type, isDefault: true, id: { not: req.params.id } }, data: { isDefault: false } })
    }
    const account = await prisma.socialAccount.update({
      where: { id: req.params.id },
      data,
    })
    res.json({ success: true, data: account })
  } catch (err) { next(err) }
})

// 删除账户（无关联记录时可删）
router.delete('/accounts/:id', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const account = await prisma.socialAccount.findFirst({ where: { id: req.params.id, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })
    // 检查是否有关联记录
    const [socialCount, housingCount, deptCount] = await Promise.all([
      prisma.employeeSocialInsRecord.count({ where: { accountId: account.id } }),
      prisma.employeeHousingFundRecord.count({ where: { accountId: account.id } }),
      prisma.department.count({ where: { OR: [{ socialAccountId: account.id }, { housingAccountId: account.id }] } }),
    ])
    if (socialCount + housingCount + deptCount > 0) {
      return res.status(400).json({ success: false, error: { code: 'IN_USE', message: `账户仍关联 ${socialCount + housingCount} 条参保记录、${deptCount} 个部门，无法删除` } })
    }
    await prisma.socialAccount.delete({ where: { id: account.id } })
    res.json({ success: true, data: { message: '已删除' } })
  } catch (err) { next(err) }
})

// 设为默认账户
router.put('/accounts/:id/default', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const account = await prisma.socialAccount.findFirst({ where: { id: req.params.id, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })
    await prisma.socialAccount.updateMany({ where: { orgId, type: account.type, isDefault: true }, data: { isDefault: false } })
    await prisma.socialAccount.update({ where: { id: account.id }, data: { isDefault: true } })
    res.json({ success: true, data: { message: '已设为默认' } })
  } catch (err) { next(err) }
})

// ==========================================
// 年度标准 API（新，按 accountId）
// ==========================================

// 按账户获取年度标准列表
router.get('/accounts/:accountId/standards', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { accountId } = req.params
    const standards = await prisma.socialYearStandard.findMany({
      where: { orgId, accountId },
      orderBy: { effectiveFrom: 'desc' },
    })
    res.json({ success: true, data: standards })
  } catch (err) { next(err) }
})

// 按账户获取当前生效标准
router.get('/accounts/:accountId/current-standard', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { accountId } = req.params
    const standard = await prisma.socialYearStandard.findFirst({
      where: { orgId, accountId, isCurrent: true },
      orderBy: { effectiveFrom: 'desc' },
    })
    res.json({ success: true, data: standard })
  } catch (err) { next(err) }
})

// 按账户获取继承数据（当前标准 → 旧社保配置 → 默认值），用于新建年度标准初始值
router.get('/accounts/:accountId/inherit-config', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { accountId } = req.params
    const account = await prisma.socialAccount.findFirst({ where: { id: accountId, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })

    // 1. 优先用当前年度标准
    const currentStandard = await prisma.socialYearStandard.findFirst({
      where: { orgId, accountId, isCurrent: true },
      orderBy: { effectiveFrom: 'desc' },
    })
    if (currentStandard) {
      return res.json({ success: true, data: { ...currentStandard, source: 'current_standard' } })
    }

    // 2. 回退到旧社保/公积金配置表（按城市）
    if (account.type === 'HOUSING') {
      const oldConfig = await prisma.housingFundConfig.findFirst({
        where: { orgId, city: account.city },
        orderBy: { effectiveFrom: 'desc' },
      })
      if (oldConfig) {
        return res.json({ success: true, data: { ...oldConfig, source: 'old_housing_config' } })
      }
    } else {
      const oldConfig = await prisma.socialInsuranceConfig.findFirst({
        where: { orgId, city: account.city },
        orderBy: { effectiveFrom: 'desc' },
      })
      if (oldConfig) {
        return res.json({ success: true, data: { ...oldConfig, source: 'old_social_config' } })
      }
    }

    // 3. 都没有，返回 null
    res.json({ success: true, data: null })
  } catch (err) { next(err) }
})

// 按账户+月份获取适用标准
router.get('/accounts/:accountId/standard-by-month/:month', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { accountId, month } = req.params
    const standard = await prisma.socialYearStandard.findFirst({
      where: {
        orgId, accountId,
        effectiveFrom: { lte: month },
        OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }],
      },
      orderBy: { effectiveFrom: 'desc' },
    })
    if (!standard) {
      const current = await prisma.socialYearStandard.findFirst({ where: { orgId, accountId, isCurrent: true } })
      return res.json({ success: true, data: current })
    }
    res.json({ success: true, data: standard })
  } catch (err) { next(err) }
})

// 新建年度标准
const yearStandardSchema = z.object({
  effectiveFrom: z.string().regex(/^\d{4}-\d{2}$/),
  pensionOrg: z.number().optional(),
  pensionEmp: z.number().optional(),
  medicalOrg: z.number().optional(),
  medicalEmp: z.number().optional(),
  medicalOrgExtra: z.number().min(0).optional(),
  medicalEmpExtra: z.number().min(0).optional(),
  unemploymentOrg: z.number().optional(),
  unemploymentEmp: z.number().optional(),
  injuryOrg: z.number().optional(),
  maternityOrg: z.number().optional(),
  baseMin: z.number().optional(),
  baseMax: z.number().optional(),
  medicalBaseMin: z.number().optional(),
  medicalBaseMax: z.number().optional(),
  extraInsurances: z.any().optional(),
  housingOrg: z.number().optional(),
  housingEmp: z.number().optional(),
  housingBaseMin: z.number().min(0).optional(),
  housingBaseMax: z.number().min(0).optional(),
  minWage: z.number().min(0).optional(),
})

router.post('/accounts/:accountId/standards', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { accountId } = req.params
    const data = yearStandardSchema.parse(req.body)
    const account = await prisma.socialAccount.findFirst({ where: { id: accountId, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })

    // 检查是否已存在同 effectiveFrom 的标准
    const existing = await prisma.socialYearStandard.findFirst({ where: { accountId, effectiveFrom: data.effectiveFrom } })
    if (existing) {
      // 已存在：更新而非报错
      const standard = await prisma.socialYearStandard.update({
        where: { id: existing.id },
        data: { ...data, isCurrent: true, effectiveTo: null },
      })
      // 将其他当前版本标记为失效
      await prisma.socialYearStandard.updateMany({
        where: { accountId, isCurrent: true, id: { not: existing.id } },
        data: { isCurrent: false, effectiveTo: data.effectiveFrom },
      })
      return res.json({ success: true, data: standard })
    }

    // 将旧当前版本标记为失效
    const current = await prisma.socialYearStandard.findFirst({ where: { accountId, isCurrent: true } })
    if (current) {
      const prevMonth = data.effectiveFrom
      await prisma.socialYearStandard.update({
        where: { id: current.id },
        data: { isCurrent: false, effectiveTo: prevMonth },
      })
    }

    const standard = await prisma.socialYearStandard.create({
      data: { ...data, orgId, accountId, isCurrent: true, createdBy: req.user!.id },
    })
    res.json({ success: true, data: standard })
  } catch (err) { next(err) }
})

/**
 * 快速更新当前年度标准的最低工资（无需新建版本）
 */
router.put('/accounts/:accountId/min-wage', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { accountId } = req.params
    const { minWage } = req.body as { minWage: number }
    if (minWage === undefined || minWage < 0) {
      return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: 'minWage 必须为非负数' } })
    }
    const account = await prisma.socialAccount.findFirst({ where: { id: accountId, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })
    const standard = await prisma.socialYearStandard.findFirst({ where: { accountId, isCurrent: true } })
    if (!standard) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '当前年度标准不存在' } })
    const updated = await prisma.socialYearStandard.update({ where: { id: standard.id }, data: { minWage } })
    res.json({ success: true, data: updated })
  } catch (err) { next(err) }
})

// 账户关联根部门（level=0）批量设置
router.put('/accounts/:id/departments', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { id } = req.params
    const { departmentIds } = req.body as { departmentIds: string[] }
    const account = await prisma.socialAccount.findFirst({ where: { id, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })

    // 先清除该账户的所有部门关联
    const field = account.type === 'SOCIAL' ? 'socialAccountId' : 'housingAccountId'
    await prisma.department.updateMany({
      where: { orgId, [field]: id },
      data: { [field]: null },
    })
    // 批量设置新关联（仅 level=0 根部门）
    if (departmentIds && departmentIds.length > 0) {
      await prisma.department.updateMany({
        where: { id: { in: departmentIds }, orgId, level: 0 },
        data: { [field]: id },
      })
    }
    res.json({ success: true, data: { message: `已关联 ${departmentIds?.length || 0} 个根部门` } })
  } catch (err) { next(err) }
})

// 获取账户已关联的根部门列表
router.get('/accounts/:id/departments', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { id } = req.params
    const account = await prisma.socialAccount.findFirst({ where: { id, orgId } })
    if (!account) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '账户不存在' } })

    const field = account.type === 'SOCIAL' ? 'socialAccountId' : 'housingAccountId'
    const departments = await prisma.department.findMany({
      where: { orgId, level: 0, [field]: id },
      select: { id: true, name: true },
    })
    res.json({ success: true, data: departments })
  } catch (err) { next(err) }
})

// 按部门获取适用账户（选部门时自动带出）
router.get('/department-account/:departmentId', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { departmentId } = req.params
    // 向上找到 level=0 的根部门
    let currentDept: any = await prisma.department.findFirst({ where: { id: departmentId, orgId } })
    if (!currentDept) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '部门不存在' } })

    while (currentDept && currentDept.level > 0 && currentDept.parentId) {
      currentDept = await prisma.department.findUnique({ where: { id: currentDept.parentId } })
    }
    const rootDeptId = currentDept?.id || null

    let socialAccount: any = null
    let housingAccount: any = null
    if (rootDeptId) {
      const rootDept = await prisma.department.findUnique({
        where: { id: rootDeptId },
        include: { socialAccount: true, housingAccount: true },
      })
      socialAccount = rootDept?.socialAccount || null
      housingAccount = rootDept?.housingAccount || null
    }

    // 回退到公司默认账户
    if (!socialAccount) {
      socialAccount = await prisma.socialAccount.findFirst({ where: { orgId, type: 'SOCIAL', isDefault: true } })
    }
    if (!housingAccount) {
      housingAccount = await prisma.socialAccount.findFirst({ where: { orgId, type: 'HOUSING', isDefault: true } })
    }

    // 获取当前生效标准
    const currentMonth = new Date().toISOString().slice(0, 7)
    let socialStandard: any = null
    let housingStandard: any = null
    if (socialAccount) {
      socialStandard = await prisma.socialYearStandard.findFirst({
        where: { accountId: socialAccount.id, isCurrent: true },
        orderBy: { effectiveFrom: 'desc' },
      })
    }
    if (housingAccount) {
      housingStandard = await prisma.socialYearStandard.findFirst({
        where: { accountId: housingAccount.id, isCurrent: true },
        orderBy: { effectiveFrom: 'desc' },
      })
    }

    res.json({ success: true, data: { socialAccount, housingAccount, socialStandard, housingStandard } })
  } catch (err) { next(err) }
})

// 按员工获取适用账户（通过根部门 level=0 继承，不向下到普通部门）
router.get('/employee-account/:employeeId', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { employeeId } = req.params
    const emp = await prisma.employee.findFirst({
      where: { id: employeeId, orgId },
      include: { dept: true },
    })
    if (!emp) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在' } })

    // 向上找到 level=0 的根部门（代表分公司/子公司）
    let currentDept: any = emp.dept
    while (currentDept && currentDept.level > 0 && currentDept.parentId) {
      currentDept = await prisma.department.findUnique({
        where: { id: currentDept.parentId },
      })
    }
    const rootDeptId = currentDept?.id || null

    // 从根部门获取关联账户
    let socialAccount: any = null
    let housingAccount: any = null
    if (rootDeptId) {
      const rootDept = await prisma.department.findUnique({
        where: { id: rootDeptId },
        include: { socialAccount: true, housingAccount: true },
      })
      socialAccount = rootDept?.socialAccount || null
      housingAccount = rootDept?.housingAccount || null
    }

    // 回退到公司默认账户
    if (!socialAccount) {
      socialAccount = await prisma.socialAccount.findFirst({ where: { orgId, type: 'SOCIAL', isDefault: true } })
    }
    if (!housingAccount) {
      housingAccount = await prisma.socialAccount.findFirst({ where: { orgId, type: 'HOUSING', isDefault: true } })
    }

    res.json({ success: true, data: { socialAccount, housingAccount } })
  } catch (err) { next(err) }
})

// 获取当前生效版本（支持按城市筛选）
router.get('/config', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const city = req.query.city as string | undefined
    const where: any = { orgId: req.user!.orgId, isCurrent: true }
    if (city) where.city = city
    let config = await prisma.socialInsuranceConfig.findFirst({
      where,
      orderBy: { effectiveFrom: 'desc' },
    })
    // 未指定城市时，返回任意当前配置
    if (!config && !city) {
      config = await prisma.socialInsuranceConfig.findFirst({
        where: { orgId: req.user!.orgId, isCurrent: true },
        orderBy: { effectiveFrom: 'desc' },
      })
    }
    if (!config) {
      return res.json({ success: true, data: null })
    }
    res.json({ success: true, data: config })
  } catch (err) {
    next(err)
  }
})

// 获取所有城市列表（从配置中提取）
router.get('/config/cities', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const configs = await prisma.socialInsuranceConfig.findMany({
      where: { orgId: req.user!.orgId },
      select: { city: true },
      distinct: ['city'],
    })
    const cities = configs.map(c => c.city).filter(Boolean)
    if (!cities.includes('北京')) cities.unshift('北京')
    res.json({ success: true, data: cities })
  } catch (err) {
    next(err)
  }
})

// 获取所有版本列表（支持按城市筛选）
router.get('/config/versions', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const city = req.query.city as string | undefined
    const where: any = { orgId: req.user!.orgId }
    if (city) where.city = city
    const versions = await prisma.socialInsuranceConfig.findMany({
      where,
      orderBy: { effectiveFrom: 'desc' },
    })
    res.json({ success: true, data: versions })
  } catch (err) {
    next(err)
  }
})

// 按月份获取适用版本
router.get('/config/by-month/:month', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { month } = req.params
    const config = await prisma.socialInsuranceConfig.findFirst({
      where: {
        orgId: req.user!.orgId,
        effectiveFrom: { lte: month },
        OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }],
      },
      orderBy: { effectiveFrom: 'desc' },
    })
    if (!config) {
      // 回退到当前版本
      const current = await prisma.socialInsuranceConfig.findFirst({
        where: { orgId: req.user!.orgId, isCurrent: true },
      })
      return res.json({ success: true, data: current })
    }
    res.json({ success: true, data: config })
  } catch (err) {
    next(err)
  }
})

// 新建版本（年度调基/比例变更）
const createVersionSchema = z.object({
  ...socialConfigFields,
  effectiveFrom: z.string().regex(/^\d{4}-\d{2}$/),
})

router.post('/config/versions', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const data = createVersionSchema.parse(req.body)
    const orgId = req.user!.orgId

    // 检查同一城市同一生效月份是否已有版本
    const existing = await prisma.socialInsuranceConfig.findFirst({
      where: { orgId, city: data.city, effectiveFrom: data.effectiveFrom },
    })
    if (existing) {
      return res.status(400).json({ success: false, message: `${data.effectiveFrom} 已有配置版本` })
    }

    // 将之前当前版本标记为失效（按城市过滤）
    const prevCurrent = await prisma.socialInsuranceConfig.findFirst({
      where: { orgId, city: data.city, isCurrent: true },
    })
    if (prevCurrent) {
      // 计算上个版本的失效月份 = 新版本生效月份的前一个月
      const [year, mon] = data.effectiveFrom.split('-').map(Number)
      const prevMonth = mon === 1
        ? `${year - 1}-12`
        : `${year}-${String(mon - 1).padStart(2, '0')}`
      await prisma.socialInsuranceConfig.update({
        where: { id: prevCurrent.id },
        data: { isCurrent: false, effectiveTo: prevMonth },
      })
    }

    // 创建新版本
    const version = await prisma.socialInsuranceConfig.create({
      data: {
        orgId,
        ...data,
        isCurrent: true,
        createdBy: req.user!.id,
      },
    })
    res.json({ success: true, data: version })
  } catch (err) {
    next(err)
  }
})

// 预览员工基数调整（返回全部在职员工，含当前基数和建议基数）
router.get('/config/:id/adjust-preview', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params
    const orgId = req.user!.orgId

    const config = await prisma.socialInsuranceConfig.findFirst({
      where: { id, orgId },
    })
    if (!config) return res.status(404).json({ success: false, message: '配置版本不存在' })
    if (config.adjustmentDone) return res.status(400).json({ success: false, message: '该版本已执行过基数调整' })

    const employees = await prisma.employee.findMany({
      where: { orgId, status: 'ACTIVE', city: config.city },
      select: { id: true, name: true, department: true, socialInsBase: true, monthlySalary: true },
      orderBy: { name: 'asc' },
    })

    // 计算上年平均工资：查询过去12个月的Payslip的totalPay平均值
    const now = new Date()
    const lastYearStart = `${now.getFullYear() - 1}-01`
    const lastYearEnd = `${now.getFullYear() - 1}-12`

    const lastYearPayslips = await prisma.payslip.findMany({
      where: {
        orgId,
        month: { gte: lastYearStart, lte: lastYearEnd },
      },
      select: { employeeId: true, totalPay: true },
    })

    // 按员工汇总上年月均工资
    const avgSalaryMap = new Map<string, number>()
    const empPayslipMap = new Map<string, number[]>()
    for (const p of lastYearPayslips) {
      if (!empPayslipMap.has(p.employeeId)) empPayslipMap.set(p.employeeId, [])
      empPayslipMap.get(p.employeeId)!.push(p.totalPay)
    }
    for (const [empId, pays] of empPayslipMap) {
      const avg = pays.reduce((s, v) => s + v, 0) / pays.length
      avgSalaryMap.set(empId, avg)
    }

    const items = employees.map((emp) => {
      let monthlyWage = 0
      try { monthlyWage = Number(decrypt(emp.monthlySalary)) } catch { monthlyWage = Number(emp.monthlySalary) || 0 }
      const oldSocialBase = emp.socialInsBase ?? monthlyWage
      const avgSalary = avgSalaryMap.get(emp.id) ?? monthlyWage
      const suggestedSocialBase = Math.min(Math.max(avgSalary, config.baseMin), config.baseMax)
      return {
        employeeId: emp.id,
        name: emp.name,
        department: emp.department,
        oldBase: oldSocialBase,
        avgSalary,
        monthlyWage,
        suggestedBase: suggestedSocialBase,
      }
    })

    res.json({ success: true, data: { items, total: items.length, baseMin: config.baseMin, baseMax: config.baseMax } })
  } catch (err) {
    next(err)
  }
})

// 执行员工基数调整（接收用户编辑后的数据）
const adjustApplySchema = z.object({
  items: z.array(z.object({
    employeeId: z.string(),
    newBase: z.number(),
  })),
})

router.post('/config/:id/adjust-apply', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params
    const orgId = req.user!.orgId

    const config = await prisma.socialInsuranceConfig.findFirst({
      where: { id, orgId },
    })
    if (!config) return res.status(404).json({ success: false, message: '配置版本不存在' })
    if (config.adjustmentDone) return res.status(400).json({ success: false, message: '该版本已执行过基数调整' })

    const { items } = adjustApplySchema.parse(req.body)
    const adjustMonth = config.effectiveFrom
    const prevAdjustMonth = (() => {
      const [y, m] = adjustMonth.split('-').map(Number)
      const d = new Date(y, m - 2, 1)
      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
    })()

    let adjusted = 0
    for (const item of items) {
      const socialBase = Math.min(Math.max(item.newBase, config.baseMin), config.baseMax)

      // 关闭旧社保记录
      await prisma.employeeSocialInsRecord.updateMany({
        where: { employeeId: item.employeeId, endMonth: null },
        data: { endMonth: prevAdjustMonth },
      })

      // 创建新社保记录
      await prisma.employeeSocialInsRecord.create({
        data: {
          orgId,
          employeeId: item.employeeId,
          city: config.city,
          startMonth: adjustMonth,
          endMonth: null,
          base: socialBase,
          changeType: 'ADJUST',
          createdBy: req.user!.id,
        },
      })

      // 同步 Employee 便捷字段
      await prisma.employee.update({
        where: { id: item.employeeId },
        data: { socialInsBase: socialBase, socialInsStartMonth: adjustMonth },
      })
      adjusted++
    }

    await prisma.socialInsuranceConfig.update({
      where: { id },
      data: { adjustmentDone: true },
    })

    res.json({ success: true, data: { adjusted, total: items.length } })
  } catch (err) {
    next(err)
  }
})

// 重置社保基数调整（撤销本次调整，重新来过）
router.post('/config/:id/reset-adjustment', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params
    const orgId = req.user!.orgId

    const config = await prisma.socialInsuranceConfig.findFirst({
      where: { id, orgId },
    })
    if (!config) return res.status(404).json({ success: false, message: '配置版本不存在' })
    if (!config.adjustmentDone) return res.status(400).json({ success: false, message: '该版本尚未执行过基数调整，无需重置' })

    // 恢复 adjustmentDone 标志
    await prisma.socialInsuranceConfig.update({
      where: { id },
      data: { adjustmentDone: false },
    })

    // 删除该版本创建的所有社保记录变更（按城市筛选）
    await prisma.employeeSocialInsRecord.deleteMany({
      where: {
        orgId,
        city: config.city,
        changeType: 'ADJUST',
        startMonth: config.effectiveFrom,
      },
    })

    // 恢复员工社保基数为调整前（找到 adjustment 前的最后一条记录，按城市）
    const employees = await prisma.employee.findMany({
      where: { orgId, status: 'ACTIVE', city: config.city },
      select: { id: true },
    })

    for (const emp of employees) {
      const prevRecord = await prisma.employeeSocialInsRecord.findFirst({
        where: { orgId, employeeId: emp.id, city: config.city, startMonth: { lt: config.effectiveFrom } },
        orderBy: { startMonth: 'desc' },
      })
      await prisma.employee.update({
        where: { id: emp.id },
        data: {
          socialInsBase: prevRecord?.base ?? null,
          socialInsStartMonth: prevRecord?.startMonth ?? null,
        },
      })
    }

    res.json({ success: true, message: '社保基数调整已重置，可以重新调整' })
  } catch (err) {
    next(err)
  }
})

// 社保计算（使用当前版本或指定月份版本）
const calcSchema = z.object({
  base: z.number().positive(),
  month: z.string().regex(/^\d{4}-\d{2}$/).optional(),
  city: z.string().optional(),
})

router.post('/calculate', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { base, month, city } = calcSchema.parse(req.body)
    const orgId = req.user!.orgId

    let config
    const whereBase: any = { orgId }
    if (city) whereBase.city = city
    if (month) {
      config = await prisma.socialInsuranceConfig.findFirst({
        where: {
          ...whereBase,
          effectiveFrom: { lte: month },
          OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }],
        },
        orderBy: { effectiveFrom: 'desc' },
      })
    }
    if (!config) {
      config = await prisma.socialInsuranceConfig.findFirst({
        where: { ...whereBase, isCurrent: true },
      })
    }
    // 回退到 SocialYearStandard（通过默认社保账户关联）
    if (!config) {
      const socialAccount = await prisma.socialAccount.findFirst({
        where: { orgId, type: 'SOCIAL', isDefault: true },
      })
      if (socialAccount) {
        const standard = await prisma.socialYearStandard.findFirst({
          where: {
            accountId: socialAccount.id,
            effectiveFrom: { lte: month || '9999-12' },
            OR: [{ effectiveTo: null }, { effectiveTo: { gte: month || '0000-01' } }],
          },
          orderBy: { effectiveFrom: 'desc' },
        })
        if (standard) {
          config = {
            baseMin: standard.baseMin,
            baseMax: standard.baseMax,
            medicalBaseMin: standard.medicalBaseMin,
            medicalBaseMax: standard.medicalBaseMax,
            pensionOrg: standard.pensionOrg,
            pensionEmp: standard.pensionEmp,
            medicalOrg: standard.medicalOrg,
            medicalEmp: standard.medicalEmp,
            medicalOrgExtra: standard.medicalOrgExtra,
            medicalEmpExtra: standard.medicalEmpExtra,
            unemploymentOrg: standard.unemploymentOrg,
            unemploymentEmp: standard.unemploymentEmp,
            injuryOrg: standard.injuryOrg,
            maternityOrg: standard.maternityOrg,
            extraInsurances: standard.extraInsurances,
          } as any
        }
      }
    }
    if (!config) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: `未找到${city || ''}的社保配置，请先在社保管理中创建` } })
    }

    const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
    const medMin = config.medicalBaseMin && config.medicalBaseMin > 0 ? config.medicalBaseMin : config.baseMin
    const medMax = config.medicalBaseMax && config.medicalBaseMax > 0 ? config.medicalBaseMax : config.baseMax
    const medicalBase = Math.min(Math.max(base, medMin), medMax)

    const pensionOrg = actualBase * config.pensionOrg / 100
    const pensionEmp = actualBase * config.pensionEmp / 100
    const medicalOrg = medicalBase * config.medicalOrg / 100 + (config.medicalOrgExtra || 0)
    const medicalEmp = medicalBase * config.medicalEmp / 100 + (config.medicalEmpExtra || 0)
    const unemploymentOrg = actualBase * config.unemploymentOrg / 100
    const unemploymentEmp = actualBase * config.unemploymentEmp / 100
    const injuryOrg = actualBase * config.injuryOrg / 100
    const maternityOrg = medicalBase * config.maternityOrg / 100
    let totalOrg = pensionOrg + medicalOrg + unemploymentOrg + injuryOrg + maternityOrg
    let totalEmp = pensionEmp + medicalEmp + unemploymentEmp

    // 附加险种
    const extraItems: any[] = []
    if (config.extraInsurances && Array.isArray(config.extraInsurances)) {
      for (const ins of config.extraInsurances as any[]) {
        const insBase = ins.baseType === 'medical' ? medicalBase : ins.baseType === 'fixed' ? 1 : actualBase
        if (ins.baseType === 'fixed' && ins.fixedAmount) {
          const orgAmt = ins.fixedAmount
          const empAmt = ins.empFixedAmount || 0
          totalOrg += orgAmt
          totalEmp += empAmt
          extraItems.push({ name: ins.name, orgRate: 0, empRate: 0, orgAmount: orgAmt, empAmount: empAmt })
        } else {
          const orgAmt = insBase * (ins.orgRate || 0) / 100
          const empAmt = insBase * (ins.empRate || 0) / 100
          totalOrg += orgAmt
          totalEmp += empAmt
          extraItems.push({ name: ins.name, orgRate: ins.orgRate || 0, empRate: ins.empRate || 0, orgAmount: orgAmt, empAmount: empAmt })
        }
      }
    }

    const total = totalOrg + totalEmp

    res.json({
      success: true,
      data: {
        actualBase,
        medicalBase,
        originalBase: base,
        capped: base > config.baseMax,
        floored: base < config.baseMin,
        configVersion: config.effectiveFrom,
        items: [
          { name: '养老保险', orgRate: config.pensionOrg, empRate: config.pensionEmp, orgAmount: pensionOrg, empAmount: pensionEmp },
          { name: '医疗保险', orgRate: config.medicalOrg, empRate: config.medicalEmp, orgAmount: medicalOrg, empAmount: medicalEmp },
          { name: '失业保险', orgRate: config.unemploymentOrg, empRate: config.unemploymentEmp, orgAmount: unemploymentOrg, empAmount: unemploymentEmp },
          { name: '工伤保险', orgRate: config.injuryOrg, empRate: 0, orgAmount: injuryOrg, empAmount: 0 },
          { name: '生育保险', orgRate: config.maternityOrg, empRate: 0, orgAmount: maternityOrg, empAmount: 0 },
          ...extraItems,
        ],
        totalOrg,
        totalEmp,
        total,
      },
    })
  } catch (err) {
    next(err)
  }
})

// ========== 公积金配置 ==========

// 获取当前公积金配置（支持按城市、账户类型筛选）
router.get('/housing-config', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const city = req.query.city as string | undefined
    const accountType = req.query.accountType as string | undefined
    const where: any = { orgId: req.user!.orgId, isCurrent: true }
    if (city) where.city = city
    if (accountType) where.accountType = accountType
    const configs = await prisma.housingFundConfig.findMany({
      where,
      orderBy: { effectiveFrom: 'desc' },
    })
    // 兼容旧接口：无 accountType 参数时返回第一条
    const config = accountType ? configs.find(c => c.accountType === accountType) || configs[0] : configs[0]
    if (!config) {
      return res.json({ success: true, data: null })
    }
    res.json({ success: true, data: config })
  } catch (err) {
    next(err)
  }
})

// 公积金配置版本列表（支持按城市、账户类型筛选）
router.get('/housing-config/versions', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const city = req.query.city as string | undefined
    const accountType = req.query.accountType as string | undefined
    const where: any = { orgId: req.user!.orgId }
    if (city) where.city = city
    if (accountType) where.accountType = accountType
    const versions = await prisma.housingFundConfig.findMany({
      where,
      orderBy: [{ accountType: 'asc' }, { effectiveFrom: 'desc' }],
    })
    res.json({ success: true, data: versions })
  } catch (err) {
    next(err)
  }
})

// 新建公积金配置版本
const createHousingVersionSchema = z.object({
  ...housingConfigFields,
  effectiveFrom: z.string().regex(/^\d{4}-\d{2}$/),
})

router.post('/housing-config/versions', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const data = createHousingVersionSchema.parse(req.body)
    const orgId = req.user!.orgId

    const acctType = data.accountType || 'BASIC'
    const existing = await prisma.housingFundConfig.findFirst({
      where: { orgId, city: data.city, accountType: acctType, effectiveFrom: data.effectiveFrom },
    })
    if (existing) {
      return res.status(400).json({ success: false, message: `${data.effectiveFrom} 已有${acctType === 'SUPPLEMENTARY' ? '补充' : '基本'}公积金配置版本` })
    }

    const prevCurrent = await prisma.housingFundConfig.findFirst({
      where: { orgId, city: data.city, accountType: acctType, isCurrent: true },
    })
    if (prevCurrent) {
      const [year, mon] = data.effectiveFrom.split('-').map(Number)
      const prevMonth = mon === 1
        ? `${year - 1}-12`
        : `${year}-${String(mon - 1).padStart(2, '0')}`
      await prisma.housingFundConfig.update({
        where: { id: prevCurrent.id },
        data: { isCurrent: false, effectiveTo: prevMonth },
      })
    }

    const version = await prisma.housingFundConfig.create({
      data: {
        orgId,
        accountType: acctType,
        ...data,
        isCurrent: true,
        createdBy: req.user!.id,
      },
    })
    res.json({ success: true, data: version })
  } catch (err) {
    next(err)
  }
})

// 公积金计算
router.post('/housing-calculate', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { base, month, city } = calcSchema.parse(req.body)
    const orgId = req.user!.orgId

    let config
    const whereBase: any = { orgId }
    if (city) whereBase.city = city
    if (month) {
      config = await prisma.housingFundConfig.findFirst({
        where: {
          ...whereBase,
          effectiveFrom: { lte: month },
          OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }],
        },
        orderBy: { effectiveFrom: 'desc' },
      })
    }
    if (!config) {
      config = await prisma.housingFundConfig.findFirst({
        where: { ...whereBase, isCurrent: true },
      })
    }
    // 回退到 SocialYearStandard（通过默认公积金账户关联）
    if (!config) {
      const housingAccount = await prisma.socialAccount.findFirst({
        where: { orgId, type: 'HOUSING', isDefault: true },
      })
      if (housingAccount) {
        const standard = await prisma.socialYearStandard.findFirst({
          where: {
            accountId: housingAccount.id,
            effectiveFrom: { lte: month || '9999-12' },
            OR: [{ effectiveTo: null }, { effectiveTo: { gte: month || '0000-01' } }],
          },
          orderBy: { effectiveFrom: 'desc' },
        })
        if (standard) {
          config = {
            baseMin: standard.housingBaseMin || standard.baseMin,
            baseMax: standard.housingBaseMax || standard.baseMax,
            housingOrg: standard.housingOrg,
            housingEmp: standard.housingEmp,
          } as any
        }
      }
    }
    if (!config) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: `未找到${city || ''}的公积金配置，请先在公积金管理中创建` } })
    }

    const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
    const housingOrg = actualBase * config.housingOrg / 100
    const housingEmp = actualBase * config.housingEmp / 100

    res.json({
      success: true,
      data: {
        actualBase,
        originalBase: base,
        capped: base > config.baseMax,
        floored: base < config.baseMin,
        configVersion: config.effectiveFrom,
        housingOrg,
        housingEmp,
        orgRate: config.housingOrg,
        empRate: config.housingEmp,
        total: housingOrg + housingEmp,
      },
    })
  } catch (err) {
    next(err)
  }
})

// 公积金调基预览
router.get('/housing-config/:id/adjust-preview', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params
    const orgId = req.user!.orgId

    const config = await prisma.housingFundConfig.findFirst({
      where: { id, orgId },
    })
    if (!config) return res.status(404).json({ success: false, message: '公积金配置版本不存在' })
    if (config.adjustmentDone) return res.status(400).json({ success: false, message: '该版本已执行过公积金基数调整' })

    const employees = await prisma.employee.findMany({
      where: { orgId, status: 'ACTIVE', city: config.city },
      select: { id: true, name: true, department: true, housingFundBase: true, monthlySalary: true },
      orderBy: { name: 'asc' },
    })

    const now = new Date()
    const lastYearStart = `${now.getFullYear() - 1}-01`
    const lastYearEnd = `${now.getFullYear() - 1}-12`

    const lastYearPayslips = await prisma.payslip.findMany({
      where: { orgId, month: { gte: lastYearStart, lte: lastYearEnd } },
      select: { employeeId: true, totalPay: true },
    })

    const empPayslipMap = new Map<string, number[]>()
    for (const p of lastYearPayslips) {
      if (!empPayslipMap.has(p.employeeId)) empPayslipMap.set(p.employeeId, [])
      empPayslipMap.get(p.employeeId)!.push(p.totalPay)
    }

    const items = employees.map((emp) => {
      let monthlyWage = 0
      try { monthlyWage = Number(decrypt(emp.monthlySalary)) } catch { monthlyWage = Number(emp.monthlySalary) || 0 }
      const oldBase = emp.housingFundBase ?? monthlyWage
      const payslips = empPayslipMap.get(emp.id)
      const avgSalary = payslips && payslips.length > 0 ? payslips.reduce((s, v) => s + v, 0) / payslips.length : monthlyWage
      const suggestedBase = Math.min(Math.max(avgSalary, config.baseMin), config.baseMax)
      return {
        employeeId: emp.id,
        name: emp.name,
        department: emp.department,
        oldBase,
        avgSalary,
        monthlyWage,
        suggestedBase,
      }
    })

    res.json({ success: true, data: { items, total: items.length, baseMin: config.baseMin, baseMax: config.baseMax } })
  } catch (err) {
    next(err)
  }
})

// 执行公积金调基
const adjustHousingSchema = z.object({
  items: z.array(z.object({
    employeeId: z.string(),
    newBase: z.number(),
  })),
})

router.post('/housing-config/:id/adjust-apply', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params
    const orgId = req.user!.orgId

    const config = await prisma.housingFundConfig.findFirst({
      where: { id, orgId },
    })
    if (!config) return res.status(404).json({ success: false, message: '公积金配置版本不存在' })
    if (config.adjustmentDone) return res.status(400).json({ success: false, message: '该版本已执行过公积金基数调整' })

    const { items } = adjustHousingSchema.parse(req.body)
    const adjustMonth = config.effectiveFrom
    const prevAdjustMonth = (() => {
      const [y, m] = adjustMonth.split('-').map(Number)
      const d = new Date(y, m - 2, 1)
      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
    })()

    let adjusted = 0
    for (const item of items) {
      const base = Math.min(Math.max(item.newBase, config.baseMin), config.baseMax)

      // 关闭旧记录
      await prisma.employeeHousingFundRecord.updateMany({
        where: { employeeId: item.employeeId, endMonth: null },
        data: { endMonth: prevAdjustMonth },
      })

      // 创建新记录
      await prisma.employeeHousingFundRecord.create({
        data: {
          orgId,
          employeeId: item.employeeId,
          city: config.city,
          startMonth: adjustMonth,
          endMonth: null,
          base,
          changeType: 'ADJUST',
          createdBy: req.user!.id,
        },
      })

      // 同步 Employee 便捷字段
      await prisma.employee.update({
        where: { id: item.employeeId },
        data: { housingFundBase: base, housingFundStartMonth: adjustMonth },
      })
      adjusted++
    }

    await prisma.housingFundConfig.update({
      where: { id },
      data: { adjustmentDone: true },
    })

    res.json({ success: true, data: { adjusted, total: items.length } })
  } catch (err) {
    next(err)
  }
})

// 重置公积金基数调整（撤销本次调整，重新来过）
router.post('/housing-config/:id/reset-adjustment', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { id } = req.params
    const orgId = req.user!.orgId

    const config = await prisma.housingFundConfig.findFirst({
      where: { id, orgId },
    })
    if (!config) return res.status(404).json({ success: false, message: '公积金配置版本不存在' })
    if (!config.adjustmentDone) return res.status(400).json({ success: false, message: '该版本尚未执行过基数调整，无需重置' })

    // 恢复 adjustmentDone 标志
    await prisma.housingFundConfig.update({
      where: { id },
      data: { adjustmentDone: false },
    })

    // 删除该版本创建的所有公积金记录变更
    await prisma.employeeHousingFundRecord.deleteMany({
      where: {
        orgId,
        changeType: 'ADJUST',
        startMonth: config.effectiveFrom,
      },
    })

    // 恢复员工公积金基数为调整前
    const employees = await prisma.employee.findMany({
      where: { orgId, status: 'ACTIVE' },
      select: { id: true },
    })

    for (const emp of employees) {
      const prevRecord = await prisma.employeeHousingFundRecord.findFirst({
        where: { orgId, employeeId: emp.id, startMonth: { lt: config.effectiveFrom } },
        orderBy: { startMonth: 'desc' },
      })
      await prisma.employee.update({
        where: { id: emp.id },
        data: {
          housingFundBase: prevRecord?.base ?? null,
          housingFundStartMonth: prevRecord?.startMonth ?? null,
        },
      })
    }

    res.json({ success: true, message: '公积金基数调整已重置，可以重新调整' })
  } catch (err) {
    next(err)
  }
})

// ========== 月度增减员 ==========

/** 根据基数和社保配置计算各项企业/个人缴费明细 */
function calcSocialDetail(base: number, config: any) {
  const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
  const medMin = config.medicalBaseMin && config.medicalBaseMin > 0 ? config.medicalBaseMin : config.baseMin
  const medMax = config.medicalBaseMax && config.medicalBaseMax > 0 ? config.medicalBaseMax : config.baseMax
  const medicalBase = Math.min(Math.max(base, medMin), medMax)
  const items = [
    { name: '养老', orgRate: config.pensionOrg, empRate: config.pensionEmp, orgAmount: actualBase * config.pensionOrg / 100, empAmount: actualBase * config.pensionEmp / 100 },
    { name: '医疗', orgRate: config.medicalOrg, empRate: config.medicalEmp, orgAmount: medicalBase * config.medicalOrg / 100 + (config.medicalOrgExtra || 0), empAmount: medicalBase * config.medicalEmp / 100 + (config.medicalEmpExtra || 0) },
    { name: '失业', orgRate: config.unemploymentOrg, empRate: config.unemploymentEmp, orgAmount: actualBase * config.unemploymentOrg / 100, empAmount: actualBase * config.unemploymentEmp / 100 },
    { name: '工伤', orgRate: config.injuryOrg, empRate: 0, orgAmount: actualBase * config.injuryOrg / 100, empAmount: 0 },
    { name: '生育', orgRate: config.maternityOrg, empRate: 0, orgAmount: medicalBase * config.maternityOrg / 100, empAmount: 0 },
  ]
  // 附加险种
  if (config.extraInsurances && Array.isArray(config.extraInsurances)) {
    for (const ins of config.extraInsurances as any[]) {
      const insBase = ins.baseType === 'medical' ? medicalBase : ins.baseType === 'fixed' ? 1 : actualBase
      if (ins.baseType === 'fixed' && ins.fixedAmount) {
        items.push({ name: ins.name, orgRate: 0, empRate: 0, orgAmount: ins.fixedAmount, empAmount: ins.empFixedAmount || 0 })
      } else {
        items.push({ name: ins.name, orgRate: ins.orgRate || 0, empRate: ins.empRate || 0, orgAmount: insBase * (ins.orgRate || 0) / 100, empAmount: insBase * (ins.empRate || 0) / 100 })
      }
    }
  }
  const totalOrg = items.reduce((s, i) => s + i.orgAmount, 0)
  const totalEmp = items.reduce((s, i) => s + i.empAmount, 0)
  return { actualBase, medicalBase, items, totalOrg, totalEmp }
}

/** 根据基数和公积金配置计算企业/个人缴费明细 */
function calcHousingDetail(base: number, config: any) {
  const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
  const orgAmount = actualBase * config.housingOrg / 100
  const empAmount = actualBase * config.housingEmp / 100
  return { actualBase, orgAmount, empAmount, total: orgAmount + empAmount }
}

/** 按月份匹配社保配置版本（回退到 SocialYearStandard） */
async function getSocialConfigByMonth(orgId: string, month: string, city?: string) {
  const where: any = { orgId }
  if (city) where.city = city
  let config = await prisma.socialInsuranceConfig.findFirst({
    where: { ...where, effectiveFrom: { lte: month }, OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }] },
    orderBy: { effectiveFrom: 'desc' },
  })
  if (!config) {
    config = await prisma.socialInsuranceConfig.findFirst({ where: { ...where, isCurrent: true } })
  }
  // 回退到 SocialYearStandard（通过默认社保账户关联）
  if (!config) {
    const socialAccount = await prisma.socialAccount.findFirst({
      where: { orgId, type: 'SOCIAL', isDefault: true },
    })
    if (socialAccount) {
      const standard = await prisma.socialYearStandard.findFirst({
        where: {
          accountId: socialAccount.id,
          effectiveFrom: { lte: month },
          OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }],
        },
        orderBy: { effectiveFrom: 'desc' },
      })
      if (!standard) {
        const fallback = await prisma.socialYearStandard.findFirst({
          where: { accountId: socialAccount.id, isCurrent: true },
          orderBy: { effectiveFrom: 'desc' },
        })
        if (fallback) {
          config = {
            city: city || '北京',
            effectiveFrom: fallback.effectiveFrom,
            baseMin: fallback.baseMin,
            baseMax: fallback.baseMax,
            medicalBaseMin: fallback.medicalBaseMin,
            medicalBaseMax: fallback.medicalBaseMax,
            pensionOrg: fallback.pensionOrg,
            pensionEmp: fallback.pensionEmp,
            medicalOrg: fallback.medicalOrg,
            medicalEmp: fallback.medicalEmp,
            medicalOrgExtra: fallback.medicalOrgExtra,
            medicalEmpExtra: fallback.medicalEmpExtra,
            unemploymentOrg: fallback.unemploymentOrg,
            unemploymentEmp: fallback.unemploymentEmp,
            injuryOrg: fallback.injuryOrg,
            maternityOrg: fallback.maternityOrg,
            extraInsurances: fallback.extraInsurances,
          } as any
        }
      } else {
        config = {
          city: city || '北京',
          effectiveFrom: standard.effectiveFrom,
          baseMin: standard.baseMin,
          baseMax: standard.baseMax,
          medicalBaseMin: standard.medicalBaseMin,
          medicalBaseMax: standard.medicalBaseMax,
          pensionOrg: standard.pensionOrg,
          pensionEmp: standard.pensionEmp,
          medicalOrg: standard.medicalOrg,
          medicalEmp: standard.medicalEmp,
          medicalOrgExtra: standard.medicalOrgExtra,
          medicalEmpExtra: standard.medicalEmpExtra,
          unemploymentOrg: standard.unemploymentOrg,
          unemploymentEmp: standard.unemploymentEmp,
          injuryOrg: standard.injuryOrg,
          maternityOrg: standard.maternityOrg,
          extraInsurances: standard.extraInsurances,
        } as any
      }
    }
  }
  return config
}

/** 按月份匹配公积金配置版本（回退到 SocialYearStandard） */
async function getHousingConfigByMonth(orgId: string, month: string, city?: string) {
  const where: any = { orgId }
  if (city) where.city = city
  let config = await prisma.housingFundConfig.findFirst({
    where: { ...where, effectiveFrom: { lte: month }, OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }] },
    orderBy: { effectiveFrom: 'desc' },
  })
  if (!config) {
    config = await prisma.housingFundConfig.findFirst({ where: { ...where, isCurrent: true } })
  }
  // 回退到 SocialYearStandard（通过默认公积金账户关联）
  if (!config) {
    const housingAccount = await prisma.socialAccount.findFirst({
      where: { orgId, type: 'HOUSING', isDefault: true },
    })
    if (housingAccount) {
      const standard = await prisma.socialYearStandard.findFirst({
        where: {
          accountId: housingAccount.id,
          effectiveFrom: { lte: month },
          OR: [{ effectiveTo: null }, { effectiveTo: { gte: month } }],
        },
        orderBy: { effectiveFrom: 'desc' },
      })
      if (!standard) {
        const fallback = await prisma.socialYearStandard.findFirst({
          where: { accountId: housingAccount.id, isCurrent: true },
          orderBy: { effectiveFrom: 'desc' },
        })
        if (fallback) {
          config = {
            city: city || '北京',
            effectiveFrom: fallback.effectiveFrom,
            baseMin: fallback.housingBaseMin || fallback.baseMin,
            baseMax: fallback.housingBaseMax || fallback.baseMax,
            housingOrg: fallback.housingOrg,
            housingEmp: fallback.housingEmp,
          } as any
        }
      } else {
        config = {
          city: city || '北京',
          effectiveFrom: standard.effectiveFrom,
          baseMin: standard.housingBaseMin || standard.baseMin,
          baseMax: standard.housingBaseMax || standard.baseMax,
          housingOrg: standard.housingOrg,
          housingEmp: standard.housingEmp,
        } as any
      }
    }
  }
  return config
}

// 社保月度增减员
router.get('/monthly-changes', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
    const orgId = req.user!.orgId

    // 增员：入职月 == month + 有社保基数 + 无社保记录 + 非劳务/实习协议
    // 查询该月入职的在职员工
    const monthStart = new Date(`${month}-01T00:00:00.000Z`)
    const monthEnd = new Date(monthStart.getFullYear(), monthStart.getMonth() + 1, 1)
    const hiredEmployees = await prisma.employee.findMany({
      where: {
        orgId,
        status: 'ACTIVE',
        hireDate: { gte: monthStart, lt: monthEnd },
        contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } },
      },
      include: {
        contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } },
        socialInsRecords: { where: { endMonth: null }, take: 1 },
      },
    })
    // 过滤掉已有社保记录的（已办理增员）
    const pendingAdditions = hiredEmployees.filter(e => e.socialInsRecords.length === 0)

    // 减员：endMonth == month 且 changeType 为 TERMINATION 或 CITY_CHANGE
    const reductions = await prisma.employeeSocialInsRecord.findMany({
      where: { orgId, endMonth: month, changeType: { in: ['TERMINATION', 'CITY_CHANGE'] }, employee: { contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } } } },
      include: { employee: { select: { name: true, department: true, idCardNumber: true, contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } } } } },
      orderBy: { createdAt: 'asc' },
    })

    // 按城市缓存配置
    const configCache = new Map<string, any>()
    const getConfigForCity = async (city: string) => {
      if (!configCache.has(city)) {
        configCache.set(city, await getSocialConfigByMonth(orgId, month, city))
      }
      return configCache.get(city)
    }

    // 增员：从员工信息构造
    const mapAddition = async (e: any) => {
      const city = e.city || '北京'
      const config = await getConfigForCity(city)
      const base = e.socialInsBase || 0
      const detail = config ? calcSocialDetail(base, config) : null
      return {
        recordId: null,
        employeeId: e.id,
        name: e.name,
        idCardNumber: decryptIdCard(e.idCardNumber),
        department: e.department,
        city,
        base,
        startMonth: month,
        endMonth: null,
        changeType: 'PENDING',
        detail: detail ? {
          items: detail.items,
          totalOrg: detail.totalOrg,
          totalEmp: detail.totalEmp,
          total: detail.totalOrg + detail.totalEmp,
        } : null,
      }
    }

    const mapRecord = async (r: any) => {
      const config = await getConfigForCity(r.city)
      const detail = config ? calcSocialDetail(r.base, config) : null
      return {
        recordId: r.id,
        employeeId: r.employeeId,
        name: r.employee.name,
        idCardNumber: decryptIdCard(r.employee.idCardNumber),
        department: r.employee.department,
        city: r.city,
        base: r.base,
        startMonth: r.startMonth,
        endMonth: r.endMonth,
        changeType: r.changeType,
        detail: detail ? {
          items: detail.items,
          totalOrg: detail.totalOrg,
          totalEmp: detail.totalEmp,
          total: detail.totalOrg + detail.totalEmp,
        } : null,
      }
    }

    // 按城市分组
    const allCities = [...new Set([
      ...pendingAdditions.map((e) => e.city || '北京'),
      ...reductions.map((r) => r.city),
    ])]
    const configs: Record<string, any> = {}
    for (const c of allCities) {
      const cfg = await getConfigForCity(c)
      if (cfg) configs[c] = { city: cfg.city, effectiveFrom: cfg.effectiveFrom, baseMin: cfg.baseMin, baseMax: cfg.baseMax }
    }

    const additionsResult = await Promise.all(pendingAdditions.map(mapAddition))
    console.log(`[monthly-changes] orgId=${orgId} month=${month} hiredCount=${hiredEmployees.length} pendingCount=${pendingAdditions.length} additions=${additionsResult.length}`)
    
    res.set('Cache-Control', 'no-cache, no-store, must-revalidate')
    res.json({
      success: true,
      data: {
        month,
        configs,
        additions: additionsResult,
        reductions: await Promise.all(reductions.map(mapRecord)),
      },
    })
  } catch (err) {
    next(err)
  }
})

// 调试：查看增员列表原始数据
router.get('/debug-pending', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
    const orgId = req.user!.orgId
    const monthStart = new Date(`${month}-01T00:00:00.000Z`)
    const monthEnd = new Date(monthStart.getFullYear(), monthStart.getMonth() + 1, 1)
    const hiredEmployees = await prisma.employee.findMany({
      where: {
        orgId,
        status: 'ACTIVE',
        hireDate: { gte: monthStart, lt: monthEnd },
        contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } },
      },
      include: {
        contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } },
        socialInsRecords: { where: { endMonth: null }, take: 1 },
      },
    })
    const pendingAdditions = hiredEmployees.filter(e => e.socialInsRecords.length === 0)
    res.json({
      success: true,
      data: {
        orgId,
        month,
        monthStart: monthStart.toISOString(),
        monthEnd: monthEnd.toISOString(),
        hiredCount: hiredEmployees.length,
        pendingCount: pendingAdditions.length,
        pending: pendingAdditions.map(e => ({ name: e.name, hireDate: e.hireDate, city: e.city, socialInsBase: e.socialInsBase, contractType: e.contracts[0]?.contractType })),
      },
    })
  } catch (err) {
    next(err)
  }
})

// 公积金月度增减员
router.get('/housing/monthly-changes', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
    const orgId = req.user!.orgId

    // 增员：入职月 == month + 有公积金基数 + 无公积金记录 + 非劳务/实习协议
    const monthStart = new Date(`${month}-01T00:00:00.000Z`)
    const monthEnd = new Date(monthStart.getFullYear(), monthStart.getMonth() + 1, 1)
    const hiredEmployees = await prisma.employee.findMany({
      where: {
        orgId,
        status: 'ACTIVE',
        hireDate: { gte: monthStart, lt: monthEnd },
        contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } },
      },
      include: {
        contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } },
        housingFundRecords: { where: { endMonth: null }, take: 1 },
      },
    })
    // 过滤掉已有公积金记录的（已办理增员）
    const pendingAdditions = hiredEmployees.filter(e => e.housingFundRecords.length === 0)

    const reductions = await prisma.employeeHousingFundRecord.findMany({
      where: { orgId, endMonth: month, changeType: { in: ['TERMINATION', 'CITY_CHANGE'] }, employee: { contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } } } },
      include: { employee: { select: { name: true, department: true, idCardNumber: true, contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } } } } },
      orderBy: { createdAt: 'asc' },
    })

    const configCache = new Map<string, any>()
    const getConfigForCity = async (city: string) => {
      if (!configCache.has(city)) {
        configCache.set(city, await getHousingConfigByMonth(orgId, month, city))
      }
      return configCache.get(city)
    }

    // 增员：从员工信息构造
    const mapAddition = async (e: any) => {
      const city = e.city || '北京'
      const config = await getConfigForCity(city)
      const base = e.housingFundBase || 0
      const detail = config ? calcHousingDetail(base, config) : null
      return {
        recordId: null,
        employeeId: e.id,
        name: e.name,
        idCardNumber: decryptIdCard(e.idCardNumber),
        department: e.department,
        city,
        base,
        startMonth: month,
        endMonth: null,
        changeType: 'PENDING',
        detail: detail ? { orgAmount: detail.orgAmount, empAmount: detail.empAmount, total: detail.total } : null,
      }
    }

    const mapRecord = async (r: any) => {
      const config = await getConfigForCity(r.city)
      const detail = config ? calcHousingDetail(r.base, config) : null
      return {
        recordId: r.id,
        employeeId: r.employeeId,
        name: r.employee.name,
        idCardNumber: decryptIdCard(r.employee.idCardNumber),
        department: r.employee.department,
        city: r.city,
        base: r.base,
        startMonth: r.startMonth,
        endMonth: r.endMonth,
        changeType: r.changeType,
        detail: detail ? { orgAmount: detail.orgAmount, empAmount: detail.empAmount, total: detail.total } : null,
      }
    }

    const allCities = [...new Set([
      ...pendingAdditions.map((e) => e.city || '北京'),
      ...reductions.map((r) => r.city),
    ])]
    const configs: Record<string, any> = {}
    for (const c of allCities) {
      const cfg = await getConfigForCity(c)
      if (cfg) configs[c] = { city: cfg.city, effectiveFrom: cfg.effectiveFrom, baseMin: cfg.baseMin, baseMax: cfg.baseMax, housingOrg: cfg.housingOrg, housingEmp: cfg.housingEmp }
    }

    res.json({
      success: true,
      data: {
        month,
        configs,
        additions: await Promise.all(pendingAdditions.map(mapAddition)),
        reductions: await Promise.all(reductions.map(mapRecord)),
      },
    })
  } catch (err) {
    next(err)
  }
})

// ========== 在职申报 ==========

// 社保在保人员
router.get('/active-declaration', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
    const orgId = req.user!.orgId

    const records = await prisma.employeeSocialInsRecord.findMany({
      where: {
        orgId,
        startMonth: { lte: month },
        OR: [{ endMonth: null }, { endMonth: { gte: month } }],
        employee: { contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } } },
      },
      include: { employee: { select: { name: true, department: true, idCardNumber: true, hireDate: true, contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } } } } },
      orderBy: { createdAt: 'asc' },
    })

    const configCache = new Map<string, any>()
    const getConfigForCity = async (city: string) => {
      if (!configCache.has(city)) {
        configCache.set(city, await getSocialConfigByMonth(orgId, month, city))
      }
      return configCache.get(city)
    }

    const items = await Promise.all(records.map(async (r) => {
      const config = await getConfigForCity(r.city)
      const detail = config ? calcSocialDetail(r.base, config) : null
      return {
        recordId: r.id,
        employeeId: r.employeeId,
        name: r.employee.name,
        idCardNumber: decryptIdCard((r as any).employee.idCardNumber),
        department: (r as any).employee.department,
        city: r.city,
        base: r.base,
        startMonth: r.startMonth,
        endMonth: r.endMonth,
        changeType: r.changeType,
        detail: detail ? {
          items: detail.items,
          totalOrg: detail.totalOrg,
          totalEmp: detail.totalEmp,
          total: detail.totalOrg + detail.totalEmp,
        } : null,
      }
    }))

    const cities = [...new Set(records.map((r) => r.city))]
    const configs: Record<string, any> = {}
    for (const c of cities) {
      const cfg = await getConfigForCity(c)
      if (cfg) configs[c] = { city: cfg.city, effectiveFrom: cfg.effectiveFrom, baseMin: cfg.baseMin, baseMax: cfg.baseMax }
    }

    res.json({
      success: true,
      data: { month, configs, items },
    })
  } catch (err) {
    next(err)
  }
})

// ========== 办理增员（批量创建社保/公积金记录） ==========

// 办理社保增员
router.post('/enroll-social', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const userId = req.user!.id
    const { employeeIds, startMonth } = req.body as { employeeIds: string[]; startMonth: string }

    if (!employeeIds || !employeeIds.length || !startMonth) {
      return res.status(400).json({ success: false, message: '缺少必要参数' })
    }

    let enrolled = 0
    let skipped = 0
    for (const employeeId of employeeIds) {
      // 检查是否已有在保社保记录
      const existing = await prisma.employeeSocialInsRecord.findFirst({
        where: { employeeId, endMonth: null },
      })
      if (existing) { skipped++; continue }

      const emp = await prisma.employee.findFirst({
        where: { id: employeeId, orgId },
        select: { socialInsBase: true, city: true },
      })
      if (!emp) { skipped++; continue }

      await prisma.employeeSocialInsRecord.create({
        data: {
          orgId,
          employeeId,
          startMonth,
          endMonth: null,
          base: emp.socialInsBase || 0,
          changeType: 'ONBOARDING',
          createdBy: userId,
          city: emp.city || '北京',
        },
      })
      // 同步员工便捷字段
      await prisma.employee.update({
        where: { id: employeeId },
        data: { socialInsStartMonth: startMonth, socialInsEndMonth: null },
      })
      enrolled++
    }

    res.json({ success: true, data: { enrolled, skipped } })
  } catch (err) {
    next(err)
  }
})

// 办理公积金增员
router.post('/enroll-housing', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const userId = req.user!.id
    const { employeeIds, startMonth } = req.body as { employeeIds: string[]; startMonth: string }

    if (!employeeIds || !employeeIds.length || !startMonth) {
      return res.status(400).json({ success: false, message: '缺少必要参数' })
    }

    let enrolled = 0
    let skipped = 0
    for (const employeeId of employeeIds) {
      const existing = await prisma.employeeHousingFundRecord.findFirst({
        where: { employeeId, endMonth: null },
      })
      if (existing) { skipped++; continue }

      const emp = await prisma.employee.findFirst({
        where: { id: employeeId, orgId },
        select: { housingFundBase: true, city: true },
      })
      if (!emp) { skipped++; continue }

      await prisma.employeeHousingFundRecord.create({
        data: {
          orgId,
          employeeId,
          startMonth,
          endMonth: null,
          base: emp.housingFundBase || 0,
          changeType: 'ONBOARDING',
          createdBy: userId,
          city: emp.city || '北京',
        },
      })
      await prisma.employee.update({
        where: { id: employeeId },
        data: { housingFundStartMonth: startMonth, housingFundEndMonth: null },
      })
      enrolled++
    }

    res.json({ success: true, data: { enrolled, skipped } })
  } catch (err) {
    next(err)
  }
})

// 公积金在保人员
router.get('/housing/active-declaration', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
    const orgId = req.user!.orgId

    const records = await prisma.employeeHousingFundRecord.findMany({
      where: {
        orgId,
        startMonth: { lte: month },
        OR: [{ endMonth: null }, { endMonth: { gte: month } }],
        employee: { contracts: { some: { contractType: { in: ['FIXED', 'UNFIXED'] } } } },
      },
      include: { employee: { select: { name: true, department: true, idCardNumber: true, hireDate: true, contracts: { orderBy: { createdAt: 'desc' }, take: 1, select: { contractType: true } } } } },
      orderBy: { createdAt: 'asc' },
    })

    const configCache = new Map<string, any>()
    const getConfigForCity = async (city: string) => {
      if (!configCache.has(city)) {
        configCache.set(city, await getHousingConfigByMonth(orgId, month, city))
      }
      return configCache.get(city)
    }

    const items = await Promise.all(records.map(async (r) => {
      const config = await getConfigForCity(r.city)
      const detail = config ? calcHousingDetail(r.base, config) : null
      return {
        recordId: r.id,
        employeeId: r.employeeId,
        name: r.employee.name,
        idCardNumber: decryptIdCard((r as any).employee.idCardNumber),
        department: (r as any).employee.department,
        city: r.city,
        base: r.base,
        startMonth: r.startMonth,
        endMonth: r.endMonth,
        changeType: r.changeType,
        detail: detail ? { orgAmount: detail.orgAmount, empAmount: detail.empAmount, total: detail.total } : null,
      }
    }))

    const cities = [...new Set(records.map((r) => r.city))]
    const configs: Record<string, any> = {}
    for (const c of cities) {
      const cfg = await getConfigForCity(c)
      if (cfg) configs[c] = { city: cfg.city, effectiveFrom: cfg.effectiveFrom, baseMin: cfg.baseMin, baseMax: cfg.baseMax, housingOrg: cfg.housingOrg, housingEmp: cfg.housingEmp }
    }

    res.json({
      success: true,
      data: { month, configs, items },
    })
  } catch (err) {
    next(err)
  }
})

// ========== 月度办理完成（保存快照） ==========

// 列出所有已办理月份（用于办理总览）
router.get('/monthly-process/list', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const records = await prisma.socialMonthlyProcess.findMany({
      where: { orgId },
      orderBy: { month: 'desc' },
      select: { id: true, month: true, type: true, status: true, processedAt: true, processedBy: true },
    })
    res.json({ success: true, data: records })
  } catch (err) {
    next(err)
  }
})

// 查询某月办理状态
router.get('/monthly-process/status', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
    const orgId = req.user!.orgId

    const records = await prisma.socialMonthlyProcess.findMany({
      where: { orgId, month },
    })
    res.json({
      success: true,
      data: {
        month,
        social: records.find((r) => r.type === 'SOCIAL') || null,
        housing: records.find((r) => r.type === 'HOUSING') || null,
      },
    })
  } catch (err) {
    next(err)
  }
})

// 办理完成（保存快照）
router.post('/monthly-process/complete', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { month, type, snapshot } = req.body as { month: string; type: 'SOCIAL' | 'HOUSING'; snapshot: any }
    const orgId = req.user!.orgId

    if (!month || !type || !snapshot) {
      return res.status(400).json({ success: false, message: '缺少必要参数' })
    }

    const existing = await prisma.socialMonthlyProcess.findUnique({
      where: { orgId_month_type: { orgId, month, type } },
    })

    if (existing) {
      // 已存在则更新快照
      const updated = await prisma.socialMonthlyProcess.update({
        where: { id: existing.id },
        data: { snapshot, processedBy: req.user!.id, processedAt: new Date() },
      })
      return res.json({ success: true, data: updated })
    }

    const record = await prisma.socialMonthlyProcess.create({
      data: {
        orgId,
        month,
        type,
        snapshot,
        processedBy: req.user!.id,
        createdBy: req.user!.id,
      },
    })
    res.json({ success: true, data: record })
  } catch (err) {
    next(err)
  }
})

// ========== 记录修正（直接更新 + 审计日志） ==========

// 修正社保记录
router.put('/records/social/:id/correct', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { city, base, startMonth, endMonth, changeType, remark } = req.body as { city?: string; base?: number; startMonth?: string; endMonth?: string; changeType?: string; remark?: string }

    const record = await prisma.employeeSocialInsRecord.findFirst({ where: { id: req.params.id, orgId } })
    if (!record) return res.status(404).json({ success: false, message: '记录不存在' })

    const oldData = { city: record.city, base: record.base, startMonth: record.startMonth, endMonth: record.endMonth, changeType: record.changeType, remark: record.remark }
    const updateData: any = {}
    if (city !== undefined) updateData.city = city
    if (base !== undefined) updateData.base = base
    if (startMonth !== undefined) updateData.startMonth = startMonth
    if (endMonth !== undefined) updateData.endMonth = endMonth || null
    if (changeType !== undefined) updateData.changeType = changeType
    if (remark !== undefined) updateData.remark = remark

    const updated = await prisma.employeeSocialInsRecord.update({ where: { id: req.params.id }, data: updateData })

    // 同步员工便捷字段（如果修正的是当前在保记录）
    if (!updated.endMonth) {
      await prisma.employee.update({
        where: { id: record.employeeId },
        data: {
          ...(city !== undefined ? { city } : {}),
          ...(base !== undefined ? { socialInsBase: base } : {}),
          ...(startMonth !== undefined ? { socialInsStartMonth: startMonth } : {}),
        },
      })
    }

    // 写审计日志
    await prisma.auditLog.create({
      data: {
        orgId,
        userId: req.user!.id,
        action: 'CORRECT',
        entity: 'EmployeeSocialInsRecord',
        entityId: req.params.id,
        detail: { old: oldData, new: updateData, reason: req.body.reason || '数据修正' },
      },
    })

    res.json({ success: true, data: updated })
  } catch (err) {
    next(err)
  }
})

// 修正公积金记录
router.put('/records/housing/:id/correct', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const { city, base, startMonth, endMonth, changeType, remark } = req.body as { city?: string; base?: number; startMonth?: string; endMonth?: string; changeType?: string; remark?: string }

    const record = await prisma.employeeHousingFundRecord.findFirst({ where: { id: req.params.id, orgId } })
    if (!record) return res.status(404).json({ success: false, message: '记录不存在' })

    const oldData = { city: record.city, base: record.base, startMonth: record.startMonth, endMonth: record.endMonth, changeType: record.changeType, remark: record.remark }
    const updateData: any = {}
    if (city !== undefined) updateData.city = city
    if (base !== undefined) updateData.base = base
    if (startMonth !== undefined) updateData.startMonth = startMonth
    if (endMonth !== undefined) updateData.endMonth = endMonth || null
    if (changeType !== undefined) updateData.changeType = changeType
    if (remark !== undefined) updateData.remark = remark

    const updated = await prisma.employeeHousingFundRecord.update({ where: { id: req.params.id }, data: updateData })

    // 同步员工便捷字段（如果修正的是当前在保记录）
    if (!updated.endMonth) {
      await prisma.employee.update({
        where: { id: record.employeeId },
        data: {
          ...(city !== undefined ? { city } : {}),
          ...(base !== undefined ? { housingFundBase: base } : {}),
          ...(startMonth !== undefined ? { housingFundStartMonth: startMonth } : {}),
        },
      })
    }

    // 写审计日志
    await prisma.auditLog.create({
      data: {
        orgId,
        userId: req.user!.id,
        action: 'CORRECT',
        entity: 'EmployeeHousingFundRecord',
        entityId: req.params.id,
        detail: { old: oldData, new: updateData, reason: req.body.reason || '数据修正' },
      },
    })

    res.json({ success: true, data: updated })
  } catch (err) {
    next(err)
  }
})

// ========== 专项附加扣除按月录入 ==========

// 查询员工某月专项附加扣除
router.get('/special-deduction', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { employeeId, month } = req.query
    if (!employeeId || !month) return res.status(400).json({ success: false, message: '缺少 employeeId 或 month' })
    const record = await prisma.specialDeductionRecord.findUnique({
      where: { employeeId_month: { employeeId: employeeId as string, month: month as string } },
    })
    res.json({ success: true, data: record })
  } catch (err) {
    next(err)
  }
})

// 批量查询员工某月专项附加扣除
router.get('/special-deduction/batch', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { month } = req.query
    if (!month) return res.status(400).json({ success: false, message: '缺少 month' })
    const rawRecords = await prisma.specialDeductionRecord.findMany({
      where: { orgId: req.user!.orgId, month: month as string },
      include: { employee: { select: { name: true, department: true, idCardNumber: true } } },
    })
    const records = rawRecords.map((r: any) => ({
      ...r,
      employee: r.employee ? { ...r.employee, idCardNumber: decryptIdCard(r.employee.idCardNumber) } : r.employee,
    }))
    res.json({ success: true, data: records })
  } catch (err) {
    next(err)
  }
})

// 创建/更新专项附加扣除
const upsertDeductionSchema = z.object({
  employeeId: z.string().min(1),
  month: z.string().regex(/^\d{4}-\d{2}$/),
  amount: z.number().min(0).optional(),
  children: z.number().min(0).optional(),
  elderly: z.number().min(0).optional(),
  housing: z.number().min(0).optional(),
  education: z.number().min(0).optional(),
  infant: z.number().min(0).optional(),
  remark: z.string().optional(),
})

router.post('/special-deduction', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const data = upsertDeductionSchema.parse(req.body)
    const orgId = req.user!.orgId
    const amount = data.amount ?? (data.children || 0) + (data.elderly || 0) + (data.housing || 0) + (data.education || 0) + (data.infant || 0)

    const record = await prisma.specialDeductionRecord.upsert({
      where: { employeeId_month: { employeeId: data.employeeId, month: data.month } },
      create: {
        orgId,
        employeeId: data.employeeId,
        month: data.month,
        amount,
        children: data.children || 0,
        elderly: data.elderly || 0,
        housing: data.housing || 0,
        education: data.education || 0,
        infant: data.infant || 0,
        remark: data.remark,
        createdBy: req.user!.id,
      },
      update: {
        amount,
        children: data.children || 0,
        elderly: data.elderly || 0,
        housing: data.housing || 0,
        education: data.education || 0,
        infant: data.infant || 0,
        remark: data.remark,
      },
    })

    // 同步员工便捷字段
    await prisma.employee.update({ where: { id: data.employeeId }, data: { specialDeduction: amount } })

    res.json({ success: true, data: record })
  } catch (err) {
    next(err)
  }
})

// 批量录入专项附加扣除
router.post('/special-deduction/batch', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { month, items } = req.body as { month: string; items: any[] }
    if (!month || !items || !Array.isArray(items)) return res.status(400).json({ success: false, message: '缺少 month 或 items' })
    const orgId = req.user!.orgId
    const result = { total: items.length, updated: 0, errors: [] as string[] }

    for (let i = 0; i < items.length; i++) {
      const item = items[i]
      try {
        const amount = item.amount ?? (item.children || 0) + (item.elderly || 0) + (item.housing || 0) + (item.education || 0) + (item.infant || 0)
        await prisma.specialDeductionRecord.upsert({
          where: { employeeId_month: { employeeId: item.employeeId, month } },
          create: {
            orgId,
            employeeId: item.employeeId,
            month,
            amount,
            children: item.children || 0,
            elderly: item.elderly || 0,
            housing: item.housing || 0,
            education: item.education || 0,
            infant: item.infant || 0,
            remark: item.remark,
            createdBy: req.user!.id,
          },
          update: {
            amount,
            children: item.children || 0,
            elderly: item.elderly || 0,
            housing: item.housing || 0,
            education: item.education || 0,
            infant: item.infant || 0,
            remark: item.remark,
          },
        })
        await prisma.employee.update({ where: { id: item.employeeId }, data: { specialDeduction: amount } })
        result.updated++
      } catch (e: any) {
        result.errors.push(`第${i + 1}行：${e?.message || '录入失败'}`)
      }
    }

    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

// ========== AI 社保政策建议 ==========

const aiSuggestSchema = z.object({
  city: z.string(),
  effectiveFrom: z.string().regex(/^\d{4}-\d{2}$/),
  type: z.enum(['social', 'housing']).default('social'),
})

router.post('/ai-suggest', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { city, effectiveFrom, type } = aiSuggestSchema.parse(req.body)

    const apiKey = process.env.DASHSCOPE_API_KEY || ''
    if (!apiKey) {
      return res.status(400).json({ success: false, error: { code: 'NO_API_KEY', message: 'AI服务未配置' } })
    }

    const client = new OpenAI({ apiKey, baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1', timeout: 30 * 1000, maxRetries: 1 })

    const year = effectiveFrom.split('-')[0]

    const prompt = type === 'social'
      ? `请提供${city}在${year}年度的社保缴费政策。请严格按照以下JSON格式返回，不要包含任何其他文字：

{
  "baseMin": 数字,
  "baseMax": 数字,
  "medicalBaseMin": 数字,
  "medicalBaseMax": 数字,
  "pensionOrg": 数字,
  "pensionEmp": 数字,
  "medicalOrg": 数字,
  "medicalEmp": 数字,
  "unemploymentOrg": 数字,
  "unemploymentEmp": 数字,
  "injuryOrg": 数字,
  "maternityOrg": 数字,
  "extraInsurances": [
    { "name": "险种名称", "baseType": "fixed或pension或medical", "fixedAmount": 数字, "empFixedAmount": 数字, "orgRate": 数字, "empRate": 数字 }
  ]
}

说明：
- baseMin/baseMax: 养老/失业/工伤保险缴费基数上下限
- medicalBaseMin/medicalBaseMax: 医疗/生育保险缴费基数上下限（与养老相同则填相同值）
- 所有比例单位为百分比，如养老企业16%则填16
- extraInsurances: 大病医疗、长期护理险等附加险种，fixed类型用fixedAmount/empFixedAmount（元/月），比例类型用orgRate/empRate（百分比）
- 如果没有附加险种，返回空数组
- 请基于${year}年度${city}的最新社保政策填写`
      : `请提供${city}在${year}年度的住房公积金缴存政策。请严格按照以下JSON格式返回，不要包含任何其他文字：

{
  "baseMin": 数字,
  "baseMax": 数字,
  "housingOrg": 数字,
  "housingEmp": 数字
}

说明：
- baseMin/baseMax: 公积金缴存基数上下限
- housingOrg/housingEmp: 企业和个人缴存比例（百分比），如12%则填12
- 请基于${year}年度${city}的最新公积金政策填写`

    const response = await client.chat.completions.create({
      model: 'qwen-plus',
      messages: [
        { role: 'system', content: '你是社保政策专家，精通中国各城市的社会保险和住房公积金缴费政策。请只返回JSON格式数据，不要包含markdown代码块标记。' },
        { role: 'user', content: prompt },
      ],
      temperature: 0.1,
    })

    const content = response.choices[0]?.message?.content || ''

    // 提取JSON（兼容markdown代码块）
    let jsonStr = content.trim()
    const jsonMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)```/)
    if (jsonMatch) jsonStr = jsonMatch[1].trim()
    // 去除可能的非JSON前后文字
    const firstBrace = jsonStr.indexOf('{')
    const lastBrace = jsonStr.lastIndexOf('}')
    if (firstBrace >= 0 && lastBrace >= 0) jsonStr = jsonStr.substring(firstBrace, lastBrace + 1)

    const suggested = JSON.parse(jsonStr)

    res.json({ success: true, data: suggested })
  } catch (err: any) {
    next(err)
  }
})

// ========== 员工参保信息列表 ==========
router.get('/employee-enrollment', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const orgId = req.user!.orgId
    const keyword = (req.query.keyword as string) || ''
    const department = (req.query.department as string) || ''
    const socialStatus = (req.query.socialStatus as string) || ''   // INSURED | UNINSURED
    const housingStatus = (req.query.housingStatus as string) || '' // INSURED | UNINSURED
    const page = Math.max(1, parseInt(req.query.page as string) || 1)
    const pageSize = Math.min(200, Math.max(1, parseInt(req.query.pageSize as string) || 20))

    // 查询所有在职员工（先全量查，再在内存中按参保状态过滤，最后分页）
    const employees = await prisma.employee.findMany({
      where: {
        orgId,
        status: 'ACTIVE',
        ...(keyword ? { name: { contains: keyword, mode: 'insensitive' } } : {}),
        ...(department ? { department } : {}),
      },
      select: {
        id: true,
        name: true,
        department: true,
        position: true,
        socialInsBase: true,
        housingFundBase: true,
        city: true,
      },
      orderBy: { department: 'asc' },
    })

    const empIds = employees.map(e => e.id)

    // 查询当前有效的社保记录（endMonth 为 null）
    const socialRecords = await prisma.employeeSocialInsRecord.findMany({
      where: { orgId, employeeId: { in: empIds }, endMonth: null },
      select: { employeeId: true, city: true, base: true, startMonth: true, changeType: true },
    })

    // 查询当前有效的公积金记录
    const housingRecords = await prisma.employeeHousingFundRecord.findMany({
      where: { orgId, employeeId: { in: empIds }, endMonth: null },
      select: { employeeId: true, city: true, base: true, startMonth: true, changeType: true },
    })

    const socialMap = new Map(socialRecords.map(r => [r.employeeId, r]))
    const housingMap = new Map(housingRecords.map(r => [r.employeeId, r]))

    let list = employees.map(emp => {
      const social = socialMap.get(emp.id)
      const housing = housingMap.get(emp.id)
      return {
        id: emp.id,
        name: emp.name,
        department: emp.department,
        position: emp.position,
        socialInsBase: social?.base ?? emp.socialInsBase ?? 0,
        socialInsCity: social?.city ?? emp.city ?? '',
        socialInsStart: social?.startMonth ?? '',
        socialInsStatus: social ? 'INSURED' : 'UNINSURED',
        housingFundBase: housing?.base ?? emp.housingFundBase ?? 0,
        housingFundCity: housing?.city ?? emp.city ?? '',
        housingFundStart: housing?.startMonth ?? '',
        housingFundStatus: housing ? 'INSURED' : 'UNINSURED',
      }
    })

    // 按参保状态过滤
    if (socialStatus) list = list.filter(e => e.socialInsStatus === socialStatus)
    if (housingStatus) list = list.filter(e => e.housingFundStatus === housingStatus)

    const total = list.length
    const paged = list.slice((page - 1) * pageSize, page * pageSize)

    res.json({ success: true, data: paged, total, page, pageSize })
  } catch (err) {
    next(err)
  }
})

export default router
