import { Router, Response, NextFunction } from 'express'
import { authMiddleware, AuthRequest } from '../middleware/auth'
import { z } from 'zod'
import {
  batchCreateAttendanceConfirmations,
  getAttendanceConfirmations,
  confirmAttendance,
  getAttendanceStats,
  getShifts,
  createShift,
  updateShift,
  deleteShift,
  getShiftAssignments,
  batchAssignShifts,
  deleteShiftAssignment,
  getDailyAttendance,
  getMonthlyReport,
  getLeaveRecords,
  createLeaveRecord,
  deleteLeaveRecord,
  manualCorrectAttendance,
} from '../services/attendance.service'
import { createEvidence } from '../services/evidence.service'
import prisma from '../lib/prisma'

const router = Router()

/** 获取月度考勤确认列表 */
router.get('/', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = req.query.month as string
    if (!month) {
      return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 month 参数' } })
    }
    const status = req.query.status as string | undefined
    const department = req.query.department as string | undefined
    const data = await getAttendanceConfirmations(req.user!.orgId, month, status, department)
    res.json({ success: true, data })
  } catch (err) {
    next(err)
  }
})

/** 获取考勤确认统计 */
router.get('/stats', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = req.query.month as string
    if (!month) {
      return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 month 参数' } })
    }
    const data = await getAttendanceStats(req.user!.orgId, month)
    res.json({ success: true, data })
  } catch (err) {
    next(err)
  }
})

/** 批量创建考勤确认记录 */
router.post('/batch', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      month: z.string().regex(/^\d{4}-\d{2}$/),
      items: z.array(z.object({
        employeeId: z.string(),
        workDays: z.number().int().min(0),
        weekdayHours: z.number().min(0),
        weekendHours: z.number().min(0),
        holidayHours: z.number().min(0),
        overtimePay: z.number().min(0),
        deductionAmount: z.number().min(0).optional(),
      })),
    })
    const { month, items } = schema.parse(req.body)
    const result = await batchCreateAttendanceConfirmations(req.user!.orgId, req.user!.id, month, items)
    res.json({ success: true, data: result })
  } catch (err) {
    next(err)
  }
})

/** 员工确认考勤（员工端） */
router.post('/confirm', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      employeeId: z.string(),
      month: z.string().regex(/^\d{4}-\d{2}$/),
      disputeNote: z.string().optional(),
    })
    const { employeeId, month, disputeNote } = schema.parse(req.body)
    const ip = req.ip || req.socket.remoteAddress || ''
    const result = await confirmAttendance(req.user!.orgId, employeeId, month, ip, disputeNote)
    await createEvidence({
      orgId: req.user!.orgId,
      category: 'ATTENDANCE',
      refId: result.id,
      employeeId,
      events: [{ action: '考勤确认', timestamp: new Date().toISOString(), ip, userAgent: req.headers['user-agent'], ...(disputeNote ? { location: disputeNote } : {}) }],
      createdBy: req.user!.id,
    }).catch(() => {})
    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)
  }
})

/** HR 批量确认考勤 */
router.post('/batch-confirm', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      month: z.string().regex(/^\d{4}-\d{2}$/),
      ids: z.array(z.string()).optional(),
      all: z.boolean().optional(),
    })
    const { month, ids, all } = schema.parse(req.body)
    const where: any = { orgId: req.user!.orgId, month, status: 'PENDING' }
    if (!all && ids?.length) {
      where.id = { in: ids }
    }
    const result = await prisma.attendanceConfirmation.updateMany({
      where,
      data: { status: 'CONFIRMED', confirmedAt: new Date(), confirmedBy: req.user!.id },
    })
    res.json({ success: true, data: { count: result.count } })
  } catch (err) { next(err) }
})

/** 更新考勤确认的扣款金额 */
router.put('/confirmations/:id/deduction', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { deductionAmount } = req.body
    const record = await prisma.attendanceConfirmation.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 updated = await prisma.attendanceConfirmation.update({
      where: { id: req.params.id },
      data: { deductionAmount: Number(deductionAmount) || 0 },
    })
    res.json({ success: true, data: updated })
  } catch (err) { next(err) }
})

// ========== 班次管理 ==========

router.get('/shifts', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const data = await getShifts(req.user!.orgId)
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

router.post('/shifts', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      name: z.string().min(1),
      startTime: z.string().regex(/^\d{2}:\d{2}$/),
      endTime: z.string().regex(/^\d{2}:\d{2}$/),
      flexibleMinutes: z.number().int().min(0).optional(),
      restMinutes: z.number().int().min(0).optional(),
      color: z.string().optional(),
    })
    const data = await createShift(req.user!.orgId, req.user!.id, schema.parse(req.body))
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

router.put('/shifts/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      name: z.string().min(1).optional(),
      startTime: z.string().regex(/^\d{2}:\d{2}$/).optional(),
      endTime: z.string().regex(/^\d{2}:\d{2}$/).optional(),
      flexibleMinutes: z.number().int().min(0).optional(),
      restMinutes: z.number().int().min(0).optional(),
      color: z.string().optional(),
    })
    const data = await updateShift(req.user!.orgId, req.params.id, schema.parse(req.body))
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

router.delete('/shifts/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    await deleteShift(req.user!.orgId, req.params.id)
    res.json({ success: true })
  } catch (err) { next(err) }
})

// ========== 排班管理 ==========

router.get('/shift-assignments', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const date = req.query.date as string
    if (!date) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 date 参数' } })
    const data = await getShiftAssignments(req.user!.orgId, date)
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

router.post('/shift-assignments/batch', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      items: z.array(z.object({
        employeeId: z.string(),
        shiftId: z.string(),
        date: z.string(),
      })),
    })
    const { items } = schema.parse(req.body)
    const result = await batchAssignShifts(req.user!.orgId, req.user!.id, items)
    res.json({ success: true, data: result })
  } catch (err) { next(err) }
})

router.delete('/shift-assignments/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    await deleteShiftAssignment(req.user!.orgId, req.params.id)
    res.json({ success: true })
  } catch (err) { next(err) }
})

// 设置员工默认班次（长期排班=工作日班次）
router.post('/default-shift', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { employeeId, shiftId } = req.body as { employeeId: string; shiftId: string | null }
    if (!employeeId) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 employeeId' } })

    // 验证 shiftId 存在且属于该 org（shiftId 为 null 时表示取消默认班次）
    if (shiftId) {
      const shift = await prisma.shift.findFirst({ where: { id: shiftId, orgId: req.user!.orgId } })
      if (!shift) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '班次不存在' } })
    }

    await prisma.employee.update({
      where: { id: employeeId },
      data: { defaultShiftId: shiftId || null },
    })
    res.json({ success: true })
  } catch (err) { next(err) }
})

// 批量设置员工默认班次
router.post('/default-shift/batch', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { items } = req.body as { items: { employeeId: string; shiftId: string | null }[] }
    if (!items || !Array.isArray(items)) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 items' } })

    let updated = 0
    for (const item of items) {
      if (item.shiftId) {
        const shift = await prisma.shift.findFirst({ where: { id: item.shiftId, orgId: req.user!.orgId } })
        if (!shift) continue
      }
      await prisma.employee.update({
        where: { id: item.employeeId },
        data: { defaultShiftId: item.shiftId || null },
      })
      updated++
    }
    res.json({ success: true, data: { updated } })
  } catch (err) { next(err) }
})

// ========== 每日出勤 ==========

router.post('/manual-correct', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      employeeId: z.string(),
      date: z.string(),
      checkInTime: z.string().optional(),
      checkOutTime: z.string().optional(),
      status: z.string().optional(),
      remark: z.string().optional(),
    })
    const data = schema.parse(req.body)
    const record = await manualCorrectAttendance(req.user!.orgId, { ...data, createdBy: req.user!.id })
    res.json({ success: true, data: record })
  } catch (err) { next(err) }
})

router.get('/daily', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const date = req.query.date as string
    if (!date) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 date 参数' } })
    const data = await getDailyAttendance(req.user!.orgId, date)
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

// ========== 月度出勤报表 ==========

router.get('/monthly-report', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const month = req.query.month as string
    if (!month) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 month 参数' } })
    const data = await getMonthlyReport(req.user!.orgId, month)
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

// ========== 休假记录 ==========

router.get('/leaves', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const employeeId = req.query.employeeId as string | undefined
    const data = await getLeaveRecords(req.user!.orgId, employeeId)
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

router.post('/leaves', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const schema = z.object({
      employeeId: z.string(),
      leaveType: z.enum(['SICK', 'PERSONAL', 'ANNUAL', 'MATERNITY', 'OTHER']),
      startDate: z.string(),
      endDate: z.string(),
      days: z.number().min(0),
      reason: z.string().optional(),
      remark: z.string().optional(),
    })
    const data = await createLeaveRecord(req.user!.orgId, req.user!.id, schema.parse(req.body))
    res.json({ success: true, data })
  } catch (err) { next(err) }
})

router.delete('/leaves/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    await deleteLeaveRecord(req.user!.orgId, req.params.id)
    res.json({ success: true })
  } catch (err) { next(err) }
})

// ========== 考勤发布 ==========

// 发布考勤表
router.post('/publish', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { month, title } = req.body
    if (!month) {
      return res.status(400).json({ success: false, error: { code: 'MISSING_MONTH', message: '请选择月份' } })
    }
    // 检查是否已发布且未取消
    const existing = await (prisma as any).attendancePublish.findFirst({
      where: { orgId: req.user!.orgId, month, status: 'PUBLISHED' },
    })
    if (existing) {
      return res.status(400).json({ success: false, error: { code: 'ALREADY_PUBLISHED', message: `${month}月考勤表已发布` } })
    }
    // 如果有已取消的记录，删除后重新创建
    const cancelled = await (prisma as any).attendancePublish.findFirst({
      where: { orgId: req.user!.orgId, month, status: 'CANCELLED' },
    })
    if (cancelled) {
      await (prisma as any).attendancePublish.delete({ where: { id: cancelled.id } })
    }
    const record = await (prisma as any).attendancePublish.create({
      data: {
        orgId: req.user!.orgId,
        month,
        title: title || `${month}月考勤表`,
        createdBy: req.user!.id,
      },
    })
    res.json({ success: true, data: record })
  } catch (err) {
    next(err)
  }
})

// 发布记录列表
router.get('/publish-records', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const records = await (prisma as any).attendancePublish.findMany({
      where: { orgId: req.user!.orgId },
      orderBy: { createdAt: 'desc' },
    })
    res.json({ success: true, data: records })
  } catch (err) {
    next(err)
  }
})

// 取消发布
router.post('/publish/:id/cancel', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const record = await (prisma as any).attendancePublish.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 !== 'PUBLISHED') {
      return res.status(400).json({ success: false, error: { code: 'NOT_PUBLISHED', message: '仅已发布状态可取消' } })
    }
    const updated = await (prisma as any).attendancePublish.update({
      where: { id: record.id },
      data: { status: 'CANCELLED' },
    })
    res.json({ success: true, data: updated })
  } catch (err) {
    next(err)
  }
})

export default router
