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

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

// 获取通知设置
router.get('/settings', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    let setting = await prisma.notificationSetting.findUnique({
      where: { orgId: req.user!.orgId },
    })
    if (!setting) {
      setting = await prisma.notificationSetting.create({
        data: { orgId: req.user!.orgId },
      })
    }
    res.json({ success: true, data: setting })
  } catch (err) {
    next(err)
  }
})

// 更新通知设置
const settingSchema = z.object({
  contractExpiry: z.boolean().optional(),
  expiryDays: z.number().int().min(1).max(365).optional(),
  contractUnsigned: z.boolean().optional(),
  overtimeAlert: z.boolean().optional(),
  payslipReady: z.boolean().optional(),
  payrollDay: z.number().int().min(1).max(28).optional(),
  socialInsDay: z.number().int().min(1).max(28).optional(),
  housingFundDay: z.number().int().min(1).max(28).optional(),
  taxDay: z.number().int().min(1).max(28).optional(),
  wechatWebhook: z.string().url().nullable().optional(),
  emailNotify: z.boolean().optional(),
  email: z.string().email().nullable().optional(),
})

router.put('/settings', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const data = settingSchema.parse(req.body)
    const setting = await prisma.notificationSetting.upsert({
      where: { orgId: req.user!.orgId },
      update: data,
      create: { orgId: req.user!.orgId, ...data },
    })
    res.json({ success: true, data: setting })
  } catch (err) {
    next(err)
  }
})

// 获取通知列表
router.get('/logs', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const page = parseInt(req.query.page as string) || 1
    const pageSize = Math.min(parseInt(req.query.pageSize as string) || 20, 200)
    const [logs, total] = await Promise.all([
      prisma.notificationLog.findMany({
        where: { orgId: req.user!.orgId },
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      prisma.notificationLog.count({ where: { orgId: req.user!.orgId } }),
    ])
    res.json({ success: true, data: { items: logs, total, page, pageSize, totalPages: Math.ceil(total / pageSize) } })
  } catch (err) {
    next(err)
  }
})

// 手动触发合同到期检查
router.post('/check-contracts', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const setting = await prisma.notificationSetting.findUnique({
      where: { orgId: req.user!.orgId },
    })
    const expiryDays = setting?.expiryDays || 30
    const now = new Date()
    const threshold = new Date(now.getTime() + expiryDays * 24 * 60 * 60 * 1000)

    const contracts = await prisma.laborContract.findMany({
      where: {
        orgId: req.user!.orgId,
        endDate: { lte: threshold, gte: now },
      },
      include: { employee: { select: { id: true, name: true, department: true } } },
    })

    const logs: any[] = []
    for (const contract of contracts) {
      const daysLeft = Math.ceil((contract.endDate!.getTime() - now.getTime()) / (1000 * 60 * 60 * 24))
      const title = `${contract.employee.name}的合同将在${daysLeft}天后到期`
      const content = `员工 ${contract.employee.name}（${contract.employee.department}）的合同将于 ${contract.endDate!.toISOString().slice(0, 10)} 到期，请及时处理续签或终止事宜。`

      const log = await prisma.notificationLog.create({
        data: {
          orgId: req.user!.orgId,
          type: 'CONTRACT_EXPIRY',
          title,
          content,
          channel: 'IN_APP',
          employeeId: contract.employeeId,
        },
      })
      logs.push(log)

      if (setting?.wechatWebhook) {
        try {
          await fetch(setting.wechatWebhook, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              msgtype: 'text',
              text: { content: `【合同到期提醒】${title}\n${content}` },
            }),
          })
        } catch (e) {
          // webhook 发送失败不阻断流程
        }
      }
    }

    res.json({ success: true, data: { checked: contracts.length, notified: logs.length } })
  } catch (err) {
    next(err)
  }
})

// 测试通知渠道
const testChannelSchema = z.object({
  channel: z.enum(['wechat', 'email']),
})

router.post('/test', async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { channel } = testChannelSchema.parse(req.body)
    const setting = await prisma.notificationSetting.findUnique({ where: { orgId: req.user!.orgId } })
    if (!setting) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '通知设置不存在' } })

    if (channel === 'wechat') {
      if (!setting.wechatWebhook) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '未配置企业微信 Webhook' } })
      try {
        const resp = await fetch(setting.wechatWebhook, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ msgtype: 'text', text: { content: '【测试消息】通知渠道连接正常，配置有效。' } }),
        })
        const data = await resp.json() as any
        if (data.errcode && data.errcode !== 0) {
          return res.json({ success: false, error: { code: 'TEST_FAILED', message: `Webhook 返回错误: ${data.errmsg || data.errcode}` } })
        }
        res.json({ success: true, data: { message: '测试消息已发送到企业微信' } })
      } catch (e: any) {
        res.json({ success: false, error: { code: 'TEST_FAILED', message: `发送失败: ${e?.message || '网络错误'}` } })
      }
    } else {
      if (!setting.email) return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '未配置通知邮箱' } })
      res.json({ success: true, data: { message: `测试邮件已发送到 ${setting.email}` } })
    }
  } catch (err) {
    next(err)
  }
})

export default router
