import { Router } from 'express'
import bcrypt from 'bcryptjs'
import { authMiddleware, AuthRequest } from '../middleware/auth'
import { auditLog } from '../middleware/auditLog'
import { createEvidence } from '../services/evidence.service'
import { autoCreateEsignRecord } from '../services/esign.service'
import prisma from '../lib/prisma'
import { sha256, decrypt } from '../lib/crypto'
import {
  createEmployeeSchema,
  updateEmployeeSchema,
  batchRenewSchema,
  addContractSchema,
} from '../schemas/contract.schema'
import {
  getEmployees,
  getEmployeeDetail,
  createEmployee,
  rehireEmployee,
  updateEmployee,
  deleteEmployee,
  batchRenew,
  addContract,
} from '../services/contract.service'

const router = Router()

router.get('/', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await getEmployees(req.user!.orgId, {
      page: parseInt(req.query.page as string) || 1,
      pageSize: Math.min(parseInt(req.query.pageSize as string) || 20, 200),
      search: req.query.search as string,
      department: req.query.department as string,
    })
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

/**
 * 轻量级全量员工列表（不分页，仅返回 id/name/department/position/gender/status）
 * 用于特殊状态台账、发薪批次等需要选择全部员工的场景
 * 支持 status 筛选参数，默认返回 ACTIVE
 */
router.get('/all-lite', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const status = req.query.status
      ? String(req.query.status).split(',') as any[]
      : ['ACTIVE', 'RESIGNED'] as any[]
    const department = req.query.department as string | undefined
    const employees = await prisma.employee.findMany({
      where: {
        orgId: req.user!.orgId,
        status: { in: status },
        ...(department && { department }),
      },
      select: { id: true, name: true, department: true, position: true, gender: true, status: true, idCardNumber: true },
      orderBy: { name: 'asc' },
    })
    const data = employees.map((e: any) => ({
      ...e,
      idCardNumber: (() => { try { const v = e.idCardNumber; return v ? (v.includes(':') ? decrypt(v) : v) : null } catch { return null } })(),
    }))
    res.json({ success: true, data })
  } catch (err) {
    next(err)
  }
})

/**
 * 标准员工列表（不分页，供各页面下拉选择、引用等场景）
 * 与 /roster 分离，/roster 专用于花名册分页列表
 * 支持 status、department 筛选
 */
router.get('/list', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const status = req.query.status
      ? String(req.query.status).split(',') as any[]
      : ['ACTIVE'] as any[]
    const department = req.query.department as string | undefined
    const employees = await prisma.employee.findMany({
      where: {
        orgId: req.user!.orgId,
        status: { in: status },
        ...(department && { department }),
      },
      select: { id: true, name: true, department: true, position: true, phone: true, gender: true, status: true, idCardNumber: true },
      orderBy: { name: 'asc' },
    })
    // 解密身份证号，返回完整明文用于前端下拉框区分同名员工
    const employeesWithIdCard = employees.map((e: any) => {
      let idCardNo = ''
      if (e.idCardNumber) {
        try {
          const plain = decrypt(e.idCardNumber)
          if (plain) idCardNo = plain
        } catch {}
      }
      delete e.idCardNumber
      e.idCardNo = idCardNo
      return e
    })
    res.json({ success: true, data: employeesWithIdCard })
  } catch (err) {
    next(err)
  }
})

router.get('/:id', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const employee = await getEmployeeDetail(req.user!.orgId, req.params.id)
    res.json({ success: true, data: employee })
  } catch (err) {
    next(err)
  }
})

// 身份证查重
router.get('/check-id-card', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const idCard = req.query.idCard as string
    if (!idCard || idCard.length < 18) {
      return res.json({ success: true, data: { exists: false } })
    }
    const hash = sha256(idCard)
    const employee = await prisma.employee.findFirst({
      where: { orgId: req.user!.orgId, idCardHash: hash },
      select: { id: true, name: true, department: true, status: true },
    })
    res.json({ success: true, data: { exists: !!employee, employee } })
  } catch (err) {
    next(err)
  }
})

// 手机号查重
router.get('/check-phone', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const phone = req.query.phone as string
    if (!phone || phone.length < 11) {
      return res.json({ success: true, data: { exists: false } })
    }
    // 手机号加密存储，需遍历匹配（量小可接受）
    const employees = await prisma.employee.findMany({
      where: { orgId: req.user!.orgId },
      select: { id: true, name: true, department: true, status: true, phone: true, idCardNumber: true },
    })
    const matched = employees.find(e => {
      try { return e.phone ? decrypt(e.phone) === phone : false } catch { return false }
    })
    res.json({ success: true, data: { exists: !!matched, employee: matched ? { id: matched.id, name: matched.name, department: matched.department, status: matched.status, idCardNumber: (() => { try { return matched.idCardNumber ? (matched.idCardNumber.includes(':') ? decrypt(matched.idCardNumber) : matched.idCardNumber) : null } catch { return null } })() } : undefined } })
  } catch (err) {
    next(err)
  }
})

router.post('/', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = createEmployeeSchema.parse(req.body)
    const result = await createEmployee(req.user!.orgId, req.user!.id, data)
    await auditLog(req, 'CREATE', 'EMPLOYEE', result.id, { name: data.name })
    await createEvidence({
      orgId: req.user!.orgId,
      category: 'ONBOARD',
      refId: result.id,
      employeeId: result.id,
      events: [{ action: '员工入职登记', timestamp: new Date().toISOString(), ip: req.ip, userAgent: req.headers['user-agent'] }],
      createdBy: req.user!.id,
    }).catch(() => {})
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

router.put('/:id', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = updateEmployeeSchema.parse(req.body)
    const result = await updateEmployee(req.user!.orgId, req.params.id, data)
    await auditLog(req, 'UPDATE', 'EMPLOYEE', req.params.id, data)
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

router.post('/:id/rehire', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await rehireEmployee(req.user!.orgId, req.user!.id, req.params.id, req.body)
    await auditLog(req, 'REHIRE', 'EMPLOYEE', req.params.id, { hireDate: req.body.hireDate })
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'CONFLICT') {
      return res.status(409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    if (err?.code === 'VALIDATION_ERROR') {
      return res.status(400).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

router.delete('/:id', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await deleteEmployee(req.user!.orgId, req.params.id)
    const emp = await prisma.employee.findFirst({ where: { id: req.params.id }, select: { name: true, department: true } })
    await auditLog(req, 'DELETE', 'EMPLOYEE', req.params.id, { employeeName: emp?.name || '', department: emp?.department || '' })
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

/**
 * 管理员重置员工密码（重置为手机号后6位）
 * POST /employees/:id/reset-password
 */
router.post('/:id/reset-password', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const employee = await prisma.employee.findFirst({
      where: { id: req.params.id, orgId: req.user!.orgId },
      select: { id: true, phone: true, name: true },
    })
    if (!employee) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在' } })
    }
    // 重置为手机号后6位，无手机号则用 123456
    const defaultPassword = employee.phone ? employee.phone.slice(-6) : '123456'
    const passwordHash = await bcrypt.hash(defaultPassword, 10)
    await prisma.employee.update({ where: { id: employee.id }, data: { passwordHash } })
    await auditLog(req, 'RESET_PASSWORD', 'EMPLOYEE', employee.id, { employeeName: employee.name })
    res.json({ success: true, data: { message: `密码已重置为手机号后6位：${defaultPassword}` } })
  } catch (err) {
    next(err)
  }
})

// 批量续签合规预检
router.post('/contracts/preview-renew', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const { contractIds } = req.body as { contractIds: string[] }
    if (!contractIds || !Array.isArray(contractIds) || contractIds.length === 0) {
      return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 contractIds' } })
    }

    const contracts = await prisma.laborContract.findMany({
      where: { id: { in: contractIds }, orgId: req.user!.orgId },
      include: { employee: true },
      orderBy: { startDate: 'asc' },
    })

    if (contracts.length === 0) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '未找到符合条件的合同' } })
    }

    // 合规检查：按员工分组，检查历史固定期合同次数
    const employeeIds = contracts.map((c) => c.employeeId)
    const allFixedContracts = await prisma.laborContract.findMany({
      where: {
        employeeId: { in: employeeIds },
        orgId: req.user!.orgId,
        contractType: 'FIXED',
      },
      orderBy: { startDate: 'asc' },
    })
    const fixedContractsByEmp = new Map<string, typeof allFixedContracts>()
    for (const c of allFixedContracts) {
      if (!fixedContractsByEmp.has(c.employeeId)) {
        fixedContractsByEmp.set(c.employeeId, [])
      }
      fixedContractsByEmp.get(c.employeeId)!.push(c)
    }

    const results = []
    for (const contract of contracts) {
      const employee = contract.employee
      const empFixedContracts = fixedContractsByEmp.get(contract.employeeId) || []

      // 当前合同是第几次固定期（从1开始计数）
      const currentIndex = empFixedContracts.findIndex((c) => c.id === contract.id)
      const renewalCount = currentIndex + 1

      // 判断是否应签无固定期限：
      // 1. 已连续签订2次以上固定期限合同（第3次应签无固定期限）
      // 2. 员工连续工作满10年
      const shouldBeUnfixed = renewalCount >= 2
      const yearsSinceHire = (Date.now() - new Date(employee.hireDate).getTime()) / (365.25 * 24 * 60 * 60 * 1000)
      const shouldBeUnfixedByTenure = yearsSinceHire >= 10

      let warning: string | null = null
      let suggestion: string | null = null

      if (shouldBeUnfixed || shouldBeUnfixedByTenure) {
        warning = shouldBeUnfixed
          ? `该员工已有 ${renewalCount} 次固定期限合同续签记录（《劳动合同法》第14条），第三次续签应订立无固定期限劳动合同`
          : `该员工在本公司连续工作 ${Math.floor(yearsSinceHire)} 年（《劳动合同法》第14条），应订立无固定期限劳动合同`
        suggestion = '建议与员工协商订立无固定期限劳动合同，以规避法律风险'
      } else {
        suggestion = `可续签固定期限（当前为第 ${renewalCount} 次续签）`
      }

      results.push({
        contractId: contract.id,
        employeeId: contract.employeeId,
        employeeName: employee.name,
        employeeIdCardNumber: (() => { try { const v = employee.idCardNumber; return v ? (v.includes(':') ? decrypt(v) : v) : null } catch { return null } })(),
        department: employee.department,
        currentContractType: contract.contractType,
        renewalCount,
        yearsSinceHire: Math.floor(yearsSinceHire * 10) / 10,
        warning,
        suggestion,
        canRenewFixed: !warning,
      })
    }

    res.json({
      success: true,
      data: {
        total: results.length,
        warnings: results.filter((r) => r.warning).length,
        results,
      },
    })
  } catch (err) {
    next(err)
  }
})

router.post('/contracts/batch-renew', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = batchRenewSchema.parse(req.body)
    const result = await batchRenew(req.user!.orgId, req.user!.id, data.contractIds, data.years)
    await auditLog(req, 'BATCH_RENEW', 'CONTRACT', undefined, { count: data.contractIds.length, years: data.years, contractIds: data.contractIds })
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

router.post('/contracts', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = addContractSchema.parse(req.body)
    const result = await addContract(req.user!.orgId, req.user!.id, data)
    const emp = await prisma.employee.findFirst({ where: { id: data.employeeId }, select: { name: true } })
    await auditLog(req, 'ADD_CONTRACT', 'CONTRACT', result.id, { employeeName: emp?.name || '', employeeId: data.employeeId, contractType: data.contractType, startDate: data.startDate, endDate: data.endDate })
    await createEvidence({
      orgId: req.user!.orgId,
      category: 'CONTRACT_SIGN',
      refId: result.id,
      employeeId: data.employeeId,
      events: [{ action: '合同签订', timestamp: new Date().toISOString(), ip: req.ip, userAgent: req.headers['user-agent'] }],
      createdBy: req.user!.id,
    }).catch(() => {})

    // 注意：电子签署记录由前端根据 signMethod 决定是否创建，避免重复
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

router.delete('/contracts/:contractId', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const contract = await prisma.laborContract.findFirst({
      where: { id: req.params.contractId, orgId: req.user!.orgId },
    })
    if (!contract) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '合同不存在' } })
    }
    // 作废处理：设置结束日期为当前时间，保留记录但不物理删除
    await prisma.laborContract.update({
      where: { id: req.params.contractId },
      data: { endDate: new Date() },
    })
    const emp = await prisma.employee.findFirst({ where: { id: contract.employeeId }, select: { name: true } })
    await auditLog(req, 'VOID_CONTRACT', 'CONTRACT', req.params.contractId, { employeeName: emp?.name || '', employeeId: contract.employeeId, contractType: contract.contractType, startDate: contract.startDate, endDate: contract.endDate })
    res.json({ success: true })
  } catch (err) {
    next(err)
  }
})

// 补充上传合同附件
router.patch('/contracts/:contractId/attachment', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const contract = await prisma.laborContract.findFirst({
      where: { id: req.params.contractId, orgId: req.user!.orgId },
    })
    if (!contract) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '合同不存在' } })
    }
    const { attachmentUrl } = req.body as { attachmentUrl: string }
    await prisma.laborContract.update({
      where: { id: req.params.contractId },
      data: { attachmentUrl: attachmentUrl || null },
    })
    res.json({ success: true })
  } catch (err) {
    next(err)
  }
})

export default router
