import { Router } from 'express'
import { authMiddleware, AuthRequest } from '../middleware/auth'
import { auditLog } from '../middleware/auditLog'
import { terminationChecklistSchema, resignationSchema, batchTerminatePreviewSchema, batchTerminateSchema, createTerminationDraftSchema, updateTerminationDraftSchema } from '../schemas/termination.schema'
import { createTermination, createResignation, revokeTermination, getTerminations, getChecklistForReason, assessRisk, batchTerminatePreview, batchTerminate, createDraft, updateDraft, submitForApproval, approveTermination, rejectTermination, executeTermination, cancelTermination, getDrafts, getTerminationDetail, getDefaultHandoverItems, validateTerminationStep } from '../services/termination.service'
import prisma from '../lib/prisma'
import { createEvidence, appendEvidence } from '../services/evidence.service'
import multer from 'multer'
import path from 'path'
import fs from 'fs'

const router = Router()

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

router.get('/checklist/:reason', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const employeeId = req.query.employeeId as string
    let employee: any = undefined

    if (employeeId) {
      const emp = await prisma.employee.findFirst({
        where: { id: employeeId, orgId: req.user!.orgId },
        include: {
          trainingRecords: true,
        },
      })
      if (emp) {
        employee = {
          isInMedicalPeriod: emp.isInMedicalPeriod,
          trainingRecords: emp.trainingRecords,
        }
      }
    }

    // 获取组织所在城市，用于地区差异化合规检查（如北京通知工会程序）
    const org = await prisma.organization.findUnique({ where: { id: req.user!.orgId }, select: { city: true } })
    const orgCity = org?.city || undefined

    const checklist = getChecklistForReason(req.params.reason, employee, orgCity)
    res.json({ success: true, data: checklist })
  } catch (err) {
    next(err)
  }
})

router.get('/assess/:employeeId', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const employee = await prisma.employee.findFirst({ where: { id: req.params.employeeId, orgId: req.user!.orgId } })
    if (!employee) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在' } })
    }
    const assessment = assessRisk(employee, req.query.reason as string || '')
    res.json({ success: true, data: assessment })
  } catch (err) {
    next(err)
  }
})

router.post('/', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = terminationChecklistSchema.parse(req.body)
    const result = await createTermination(req.user!.orgId, req.user!.id, data)
    await auditLog(req, 'TERMINATE', 'EMPLOYEE', data.employeeId, { reason: data.reason })
    await createEvidence({
      orgId: req.user!.orgId,
      category: 'TERMINATION',
      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(() => {})
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

router.post('/resignation', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const { employeeId, terminationDate, resignationReason, remark } = resignationSchema.parse(req.body)
    const result = await createResignation(req.user!.orgId, req.user!.id, { employeeId, terminationDate, resignationReason, remark })
    await auditLog(req, 'RESIGN', 'EMPLOYEE', employeeId, { resignationReason })
    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 } })
    }
    next(err)
  }
})

router.delete('/:id/revoke', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await revokeTermination(req.user!.orgId, req.params.id)
    const termRecord = await prisma.terminationRecord.findFirst({ where: { id: req.params.id }, select: { employeeId: true, reason: true, type: true } })
    const emp = termRecord ? await prisma.employee.findFirst({ where: { id: termRecord.employeeId }, select: { name: true } }) : null
    await auditLog(req, 'REVOKE_TERMINATION', 'TERMINATION_RECORD', req.params.id, {
      employeeName: emp?.name || '',
      reason: termRecord?.reason || '',
      type: termRecord?.type || '',
    })
    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 === 'NOT_FOUND') {
      return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 批量解聘预检
router.post('/batch/preview', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const { items } = batchTerminatePreviewSchema.parse(req.body)
    const results = await batchTerminatePreview(req.user!.orgId, items)
    res.json({ success: true, data: { total: results.length, warnings: results.filter(r => r.warnings.length > 0).length, results } })
  } catch (err) {
    next(err)
  }
})

// 批量解聘执行
router.post('/batch', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const { items } = batchTerminateSchema.parse(req.body)
    const result = await batchTerminate(req.user!.orgId, req.user!.id, items)
    for (const id of result.success) {
      await auditLog(req, 'TERMINATE', 'EMPLOYEE', id, { batch: true })
    }
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

// ============================================================
// 解聘流程状态机 API
// ============================================================

// 获取草稿/流程列表
router.get('/drafts', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const status = req.query.status as string | undefined
    const search = req.query.search as string | undefined
    const department = req.query.department as string | undefined
    const page = parseInt(req.query.page as string) || 1
    const pageSize = Math.min(parseInt(req.query.pageSize as string) || 20, 200)
    const result = await getDrafts(req.user!.orgId, status, search, department, page, pageSize)
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

// 获取单条记录详情
router.get('/detail/:id', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await getTerminationDetail(req.user!.orgId, req.params.id)
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'NOT_FOUND') {
      return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 获取默认工作交接清单模板
router.get('/handover-template', authMiddleware, async (req: AuthRequest, res) => {
  res.json({ success: true, data: getDefaultHandoverItems() })
})

// 创建草稿
router.post('/draft', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = createTerminationDraftSchema.parse(req.body)
    const result = await createDraft(req.user!.orgId, req.user!.id, data)
    const emp = await prisma.employee.findFirst({ where: { id: data.employeeId }, select: { name: true, department: true } })
    await auditLog(req, 'CREATE_DRAFT', 'TERMINATION_RECORD', result.id, {
      employeeName: emp?.name || '',
      department: emp?.department || '',
      reason: data.reason || '',
      type: data.type || 'TERMINATION',
      terminationDate: data.terminationDate || '',
      compensation: data.compensation || 0,
    })
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'NOT_FOUND') {
      return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 更新草稿
router.put('/draft/:id', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const data = updateTerminationDraftSchema.parse(req.body)
    const result = await updateDraft(req.user!.orgId, req.params.id, req.user!.id, data)
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'CONFLICT' || err?.code === 'NOT_FOUND') {
      return res.status(err.code === 'NOT_FOUND' ? 404 : 409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 提交审批
router.post('/draft/:id/submit', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await submitForApproval(req.user!.orgId, req.params.id, req.user!.id)
    const termRecord = await prisma.terminationRecord.findFirst({ where: { id: req.params.id }, select: { employeeId: true, reason: true, type: true } })
    const emp = termRecord ? await prisma.employee.findFirst({ where: { id: termRecord.employeeId }, select: { name: true } }) : null
    await auditLog(req, 'SUBMIT_TERMINATION', 'TERMINATION_RECORD', req.params.id, {
      employeeName: emp?.name || '',
      reason: termRecord?.reason || '',
      type: termRecord?.type || '',
    })
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'CONFLICT' || err?.code === 'NOT_FOUND') {
      return res.status(err.code === 'NOT_FOUND' ? 404 : 409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 审批通过
router.post('/draft/:id/approve', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const { comment } = req.body
    const result = await approveTermination(req.user!.orgId, req.params.id, req.user!.id, comment || '')
    const termRecord = await prisma.terminationRecord.findFirst({ where: { id: req.params.id }, select: { employeeId: true, reason: true } })
    const emp = termRecord ? await prisma.employee.findFirst({ where: { id: termRecord.employeeId }, select: { name: true } }) : null
    await auditLog(req, 'APPROVE_TERMINATION', 'TERMINATION_RECORD', req.params.id, {
      employeeName: emp?.name || '',
      reason: termRecord?.reason || '',
      comment: comment || '',
    })
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'CONFLICT' || err?.code === 'NOT_FOUND') {
      return res.status(err.code === 'NOT_FOUND' ? 404 : 409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 审批驳回
router.post('/draft/:id/reject', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const { comment } = req.body
    const result = await rejectTermination(req.user!.orgId, req.params.id, req.user!.id, comment || '')
    const termRecord = await prisma.terminationRecord.findFirst({ where: { id: req.params.id }, select: { employeeId: true, reason: true } })
    const emp = termRecord ? await prisma.employee.findFirst({ where: { id: termRecord.employeeId }, select: { name: true } }) : null
    await auditLog(req, 'REJECT_TERMINATION', 'TERMINATION_RECORD', req.params.id, {
      employeeName: emp?.name || '',
      reason: termRecord?.reason || '',
      comment: comment || '',
    })
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'CONFLICT' || err?.code === 'NOT_FOUND') {
      return res.status(err.code === 'NOT_FOUND' ? 404 : 409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 执行解聘
router.post('/draft/:id/execute', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await executeTermination(req.user!.orgId, req.params.id, req.user!.id)
    const termRecord = await prisma.terminationRecord.findFirst({ where: { id: req.params.id }, select: { employeeId: true, reason: true, type: true, terminationDate: true, compensation: true } })
    const emp = termRecord ? await prisma.employee.findFirst({ where: { id: termRecord.employeeId }, select: { name: true, department: true } }) : null
    await auditLog(req, 'EXECUTE_TERMINATION', 'TERMINATION_RECORD', req.params.id, {
      employeeName: emp?.name || '',
      department: emp?.department || '',
      reason: termRecord?.reason || '',
      type: termRecord?.type || '',
      terminationDate: termRecord?.terminationDate?.toISOString().slice(0, 10) || '',
      compensation: termRecord?.compensation || 0,
    })
    await createEvidence({
      orgId: req.user!.orgId,
      category: 'TERMINATION',
      refId: req.params.id,
      employeeId: (result as any)?.employeeId,
      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: any) {
    if (err?.code === 'CONFLICT' || err?.code === 'NOT_FOUND') {
      return res.status(err.code === 'NOT_FOUND' ? 404 : 409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 撤销
router.post('/draft/:id/cancel', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const result = await cancelTermination(req.user!.orgId, req.params.id, req.user!.id)
    const termRecord = await prisma.terminationRecord.findFirst({ where: { id: req.params.id }, select: { employeeId: true, reason: true, type: true } })
    const emp = termRecord ? await prisma.employee.findFirst({ where: { id: termRecord.employeeId }, select: { name: true } }) : null
    await auditLog(req, 'CANCEL_TERMINATION', 'TERMINATION_RECORD', req.params.id, {
      employeeName: emp?.name || '',
      reason: termRecord?.reason || '',
      type: termRecord?.type || '',
    })
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'CONFLICT' || err?.code === 'NOT_FOUND') {
      return res.status(err.code === 'NOT_FOUND' ? 404 : 409).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 步骤前置校验
router.get('/draft/:id/validate-step', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const step = parseInt(req.query.step as string) || 1
    const result = await validateTerminationStep(req.user!.orgId, req.params.id, step)
    res.json({ success: true, data: result })
  } catch (err: any) {
    if (err?.code === 'NOT_FOUND') {
      return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
    }
    next(err)
  }
})

// 删除草稿（仅允许 DRAFT 和 CANCELLED 状态）
router.delete('/draft/:id', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const record = await prisma.terminationRecord.findFirst({
      where: { id: req.params.id, orgId: req.user!.orgId },
    })
    if (!record) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '记录不存在' } })
    }
    if (record.status !== 'DRAFT' && record.status !== 'CANCELLED') {
      return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '仅草稿或已撤销的记录可以删除' } })
    }
    await prisma.terminationRecord.delete({ where: { id: req.params.id } })
    await auditLog(req, 'DELETE_DRAFT', 'TERMINATION_RECORD', req.params.id, { employeeId: record.employeeId })
    res.json({ success: true })
  } catch (err) {
    next(err)
  }
})

// ========== 工会回执上传（北京地区单方解除证据链） ==========

// 工会回执文件上传目录
const unionReceiptDir = path.join(process.cwd(), 'uploads', 'union-receipt')
if (!fs.existsSync(unionReceiptDir)) fs.mkdirSync(unionReceiptDir, { recursive: true })

const unionReceiptUpload = multer({
  storage: multer.diskStorage({
    destination: unionReceiptDir,
    filename: (_req, file, cb) => {
      const ext = path.extname(file.originalname)
      cb(null, `${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ext}`)
    },
  }),
  limits: { fileSize: 10 * 1024 * 1024 },
  fileFilter: (_req, file, cb) => {
    const allowed = ['.jpg', '.jpeg', '.png', '.pdf', '.bmp']
    const ext = path.extname(file.originalname).toLowerCase()
    if (allowed.includes(ext)) cb(null, true)
    else cb(new Error('仅支持 JPG/PNG/PDF/BMP 格式'))
  },
})

/**
 * 上传工会回执文件
 * 北京地区单方解除劳动合同，工会收到通知后出具的书面回执扫描件
 */
router.post('/draft/:id/union-receipt/upload', authMiddleware, unionReceiptUpload.single('file'), async (req: AuthRequest, res, next) => {
  try {
    if (!req.file) {
      return res.status(400).json({ success: false, error: { code: 'NO_FILE', message: '请选择文件' } })
    }
    const record = await prisma.terminationRecord.findFirst({
      where: { id: req.params.id, orgId: req.user!.orgId },
    })
    if (!record) {
      fs.unlinkSync(req.file.path)
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '解聘记录不存在' } })
    }
    const fileUrl = `/uploads/union-receipt/${req.file.filename}`
    res.json({ success: true, data: { fileName: req.file.originalname, fileUrl, fileSize: req.file.size } })
  } catch (err) {
    next(err)
  }
})

/**
 * 保存工会回执信息（文件URL + 回执编号 + 工会意见）到草稿，并追加到证据链
 */
router.post('/draft/:id/union-receipt', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const record = await prisma.terminationRecord.findFirst({
      where: { id: req.params.id, orgId: req.user!.orgId },
    })
    if (!record) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '解聘记录不存在' } })
    }

    const { receiptNo, unionName, receiptDate, fileUrl, fileName, unionOpinion } = req.body

    // 将工会回执信息保存到草稿的 checklistOverrides 中
    const checklistOverrides: any = (record.checklistOverrides as any) || {}
    checklistOverrides['union_receipt'] = {
      checked: true,
      overrideReason: '已收到工会书面回执',
      receiptNo,
      unionName,
      receiptDate,
      fileUrl,
      fileName,
      unionOpinion,
    }
    // 同步标记 notify_union 已完成
    if (!checklistOverrides['notify_union']) {
      checklistOverrides['notify_union'] = {
        checked: true,
        overrideReason: '已通知工会并收到回执',
      }
    }

    await prisma.terminationRecord.update({
      where: { id: record.id },
      data: { checklistOverrides },
    })

    // 追加到证据链
    await appendEvidence(
      req.user!.orgId,
      // 查找该解聘记录对应的证据链
      (await prisma.evidenceChain.findFirst({
        where: { orgId: req.user!.orgId, category: 'TERMINATION', refId: record.id },
      }))?.id || '',
      {
        action: '工会书面回执已收到',
        timestamp: new Date().toISOString(),
        ip: req.ip,
        userAgent: req.headers['user-agent'] as string,
        location: `回执编号：${receiptNo || '无'}，工会：${unionName || '未填写'}，回执日期：${receiptDate || '未填写'}`,
      }
    ).catch(() => {
      // 证据链可能不存在（草稿阶段未创建），创建新的证据链
      return createEvidence({
        orgId: req.user!.orgId,
        category: 'TERMINATION',
        refId: record.id,
        employeeId: record.employeeId,
        events: [{
          action: '工会书面回执已收到',
          timestamp: new Date().toISOString(),
          ip: req.ip,
          userAgent: req.headers['user-agent'] as string,
          location: `回执编号：${receiptNo || '无'}，工会：${unionName || '未填写'}，回执日期：${receiptDate || '未填写'}`,
        }],
        createdBy: req.user!.id,
      })
    })

    await auditLog(req, 'UNION_RECEIPT', 'TERMINATION_RECORD', record.id, { receiptNo, unionName, fileUrl })

    res.json({ success: true, data: { receiptNo, unionName, receiptDate, fileUrl, fileName, unionOpinion } })
  } catch (err) {
    next(err)
  }
})

/**
 * 获取工会回执信息
 */
router.get('/draft/:id/union-receipt', authMiddleware, async (req: AuthRequest, res, next) => {
  try {
    const record = await prisma.terminationRecord.findFirst({
      where: { id: req.params.id, orgId: req.user!.orgId },
    })
    if (!record) {
      return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '解聘记录不存在' } })
    }
    const checklistOverrides: any = (record.checklistOverrides as any) || {}
    const unionReceipt = checklistOverrides['union_receipt'] || null
    res.json({ success: true, data: unionReceipt })
  } catch (err) {
    next(err)
  }
})

export default router
