/**
 * 提成奖金服务
 * 管理按月提成奖金/扣款的 CRUD 和批量导入
 */
import prisma from '../lib/prisma'
import { decrypt, sha256 } from '../lib/crypto'

/**
 * 按月查询提成奖金列表
 */
export async function listByMonth(orgId: string, month: string) {
  const records = await prisma.commissionBonus.findMany({
    where: { orgId, month },
    include: {
      employee: {
        select: { id: true, name: true, department: true, idCardHash: true, idCardNumber: true },
      },
    },
    orderBy: [{ employee: { department: 'asc' } }, { employee: { name: 'asc' } }],
  })
  return records.map(r => ({
    ...r,
    employee: r.employee ? {
      ...r.employee,
      idCardNumber: (() => { try { const v = r.employee.idCardNumber; return v ? (v.includes(':') ? decrypt(v) : v) : null } catch { return null } })(),
    } : r.employee,
  }))
}

/**
 * 按月汇总统计
 */
export async function summaryByMonth(orgId: string, month: string) {
  const records = await prisma.commissionBonus.findMany({
    where: { orgId, month },
    select: { amount: true },
  })
  const totalBonus = records.filter((r) => r.amount > 0).reduce((s, r) => s + r.amount, 0)
  const totalDeduction = records.filter((r) => r.amount < 0).reduce((s, r) => s + Math.abs(r.amount), 0)
  return {
    count: records.length,
    totalBonus,
    totalDeduction,
    netAmount: totalBonus - totalDeduction,
  }
}

/**
 * 创建单条提成奖金
 */
export async function create(orgId: string, userId: string, data: {
  employeeId: string
  month: string
  amount: number
  remark?: string
}) {
  const emp = await prisma.employee.findFirst({ where: { id: data.employeeId, orgId } })
  if (!emp) throw { code: 'NOT_FOUND', message: '员工不存在' }

  // 唯一约束冲突时更新（upsert）
  return prisma.commissionBonus.upsert({
    where: { orgId_employeeId_month: { orgId, employeeId: data.employeeId, month: data.month } },
    create: {
      orgId,
      employeeId: data.employeeId,
      month: data.month,
      amount: data.amount,
      remark: data.remark || null,
      createdBy: userId,
    },
    update: {
      amount: data.amount,
      remark: data.remark || null,
    },
  })
}

/**
 * 更新单条
 */
export async function update(orgId: string, id: string, data: { amount?: number; remark?: string }) {
  const existing = await prisma.commissionBonus.findFirst({ where: { id, orgId } })
  if (!existing) throw { code: 'NOT_FOUND', message: '提成奖金记录不存在' }

  return prisma.commissionBonus.update({
    where: { id },
    data: {
      ...(data.amount !== undefined && { amount: data.amount }),
      ...(data.remark !== undefined && { remark: data.remark }),
    },
  })
}

/**
 * 删除单条
 */
export async function remove(orgId: string, id: string) {
  const existing = await prisma.commissionBonus.findFirst({ where: { id, orgId } })
  if (!existing) throw { code: 'NOT_FOUND', message: '提成奖金记录不存在' }

  await prisma.commissionBonus.delete({ where: { id } })
}

/**
 * 批量导入（按月）
 * @param rows 行数据：{ employeeName?, idCardNumber?, amount, remark? }
 * @param month 月份 YYYY-MM
 * @returns { created, updated, skipped, errors }
 */
export async function batchImport(
  orgId: string,
  userId: string,
  month: string,
  rows: { employeeName?: string; idCardNumber?: string; amount: number; remark?: string }[],
) {
  let created = 0
  let updated = 0
  const errors: { row: number; message: string }[] = []

  // 预加载该月所有在职员工用于匹配
  const employees = await prisma.employee.findMany({
    where: { orgId, status: 'ACTIVE' },
    select: { id: true, name: true, idCardNumber: true, idCardHash: true, department: true },
  })

  for (let i = 0; i < rows.length; i++) {
    const row = rows[i]
    try {
      // 匹配员工：优先证件号码，其次姓名
      let emp: typeof employees[number] | undefined
      if (row.idCardNumber) {
        const hash = sha256(row.idCardNumber)
        emp = employees.find((e) => e.idCardHash === hash)
      }
      if (!emp && row.employeeName) {
        const matches = employees.filter((e) => e.name === row.employeeName)
        if (matches.length === 1) emp = matches[0]
        else if (matches.length > 1) {
          errors.push({ row: i + 2, message: `姓名"${row.employeeName}"匹配到多个员工，请用证件号码` })
          continue
        }
      }

      if (!emp) {
        errors.push({ row: i + 2, message: `未匹配到员工：${row.employeeName || row.idCardNumber || '行'}` })
        continue
      }

      // upsert
      const existing = await prisma.commissionBonus.findUnique({
        where: { orgId_employeeId_month: { orgId, employeeId: emp.id, month } },
      })
      await prisma.commissionBonus.upsert({
        where: { orgId_employeeId_month: { orgId, employeeId: emp.id, month } },
        create: {
          orgId,
          employeeId: emp.id,
          month,
          amount: row.amount,
          remark: row.remark || null,
          createdBy: userId,
        },
        update: {
          amount: row.amount,
          remark: row.remark || null,
        },
      })
      if (existing) updated++
      else created++
    } catch (err: any) {
      errors.push({ row: i + 2, message: err.message || '处理失败' })
    }
  }

  return { created, updated, skipped: errors.length, errors }
}

/**
 * 按月 + 员工 ID 列表查询提成奖金（供薪资批次"获取提成奖金"使用）
 * @returns Map<employeeId, amount>
 */
export async function getBonusByMonthAndEmployeeIds(
  orgId: string,
  month: string,
  employeeIds: string[],
): Promise<Map<string, { amount: number; remark: string | null }>> {
  if (employeeIds.length === 0) return new Map()
  const records = await prisma.commissionBonus.findMany({
    where: { orgId, month, employeeId: { in: employeeIds } },
    select: { employeeId: true, amount: true, remark: true },
  })
  return new Map(records.map((r) => [r.employeeId, { amount: r.amount, remark: r.remark }]))
}
