/**
 * Notification Helper Functions
 *
 * These are convenience wrappers around the notify() function
 * to make it easier to send notifications from various parts of the app.
 */

import { notify, type NotifyData } from "./notify"
import { db } from "./db"

// ─── Leave Notifications ──────────────────────────────────────────────────────

export async function notifyLeaveRequestSubmitted(params: {
  leaveRequestId: string
  triggeredByUserId?: string
}) {
  const leaveRequest = await db.leaveRequest.findUnique({
    where: { id: params.leaveRequestId },
    include: {
      employee: {
        select: {
          fullName: true,
          userId: true,
          reportingManagerId: true,
          reportingManager: { select: { userId: true } },
        },
      },
      leaveType: { select: { name: true } },
    },
  })

  if (!leaveRequest) return

  await notify("leave.request.submitted", {
    employeeName: leaveRequest.employee.fullName,
    leaveType: leaveRequest.leaveType.name,
    startDate: leaveRequest.startDate.toISOString().split("T")[0],
    endDate: leaveRequest.endDate.toISOString().split("T")[0],
    duration: leaveRequest.duration,
    employeeUserId: leaveRequest.employee.userId ?? undefined,
    managerId: leaveRequest.employee.reportingManager?.userId ?? undefined,
    triggeredByUserId: params.triggeredByUserId,
  })
}

export async function notifyLeaveRequestApproved(params: {
  leaveRequestId: string
  approverUserId: string
  approverName: string
}) {
  const leaveRequest = await db.leaveRequest.findUnique({
    where: { id: params.leaveRequestId },
    include: {
      employee: { select: { fullName: true, userId: true } },
      leaveType: { select: { name: true } },
    },
  })

  if (!leaveRequest) return

  await notify("leave.request.approved", {
    employeeUserId: leaveRequest.employee.userId ?? undefined,
    leaveType: leaveRequest.leaveType.name,
    startDate: leaveRequest.startDate.toISOString().split("T")[0],
    endDate: leaveRequest.endDate.toISOString().split("T")[0],
    duration: leaveRequest.duration,
    approvedBy: params.approverName,
    triggeredByUserId: params.approverUserId,
  })
}

export async function notifyLeaveRequestRejected(params: {
  leaveRequestId: string
  approverUserId: string
  reason?: string
}) {
  const leaveRequest = await db.leaveRequest.findUnique({
    where: { id: params.leaveRequestId },
    include: {
      employee: { select: { fullName: true, userId: true } },
      leaveType: { select: { name: true } },
    },
  })

  if (!leaveRequest) return

  await notify("leave.request.rejected", {
    employeeUserId: leaveRequest.employee.userId ?? undefined,
    leaveType: leaveRequest.leaveType.name,
    startDate: leaveRequest.startDate.toISOString().split("T")[0],
    endDate: leaveRequest.endDate.toISOString().split("T")[0],
    reason: params.reason,
    triggeredByUserId: params.approverUserId,
  })
}

// ─── Payroll Notifications ────────────────────────────────────────────────────

export async function notifyPayrollSlipPublished(params: {
  payrollId: string
  triggeredByUserId?: string
}) {
  const payroll = await db.payroll.findUnique({
    where: { id: params.payrollId },
    include: {
      employee: { select: { fullName: true, userId: true } },
    },
  })

  if (!payroll || !payroll.employee.userId) return

  await notify("payroll.slip.published", {
    employeeUserId: payroll.employee.userId,
    month: new Date(payroll.year, payroll.month - 1).toLocaleString("default", {
      month: "long",
    }),
    year: payroll.year,
    netPayable: payroll.netPayable.toFixed(3),
    triggeredByUserId: params.triggeredByUserId,
  })
}

export async function notifyPayrollApproved(params: {
  month: number
  year: number
  employeeCount: number
  approverName: string
  approverUserId: string
}) {
  await notify("payroll.approved", {
    month: new Date(params.year, params.month - 1).toLocaleString("default", {
      month: "long",
    }),
    year: params.year,
    employeeCount: params.employeeCount,
    approvedBy: params.approverName,
    triggeredByUserId: params.approverUserId,
  })
}

// ─── Employee Notifications ───────────────────────────────────────────────────

export async function notifyEmployeeCreated(params: {
  employeeId: string
  triggeredByUserId?: string
}) {
  const employee = await db.employee.findUnique({
    where: { id: params.employeeId },
    include: {
      department: { select: { name: true } },
    },
  })

  if (!employee) return

  await notify("employee.created", {
    employeeName: employee.fullName,
    department: employee.department?.name,
    triggeredByUserId: params.triggeredByUserId,
  })
}

export async function notifyDocumentExpiring(params: {
  employeeId: string
  documentType: string
  expiryDate: string
}) {
  const employee = await db.employee.findUnique({
    where: { id: params.employeeId },
    select: { fullName: true },
  })

  if (!employee) return

  await notify("document.expiry.warning", {
    employeeName: employee.fullName,
    documentType: params.documentType,
    expiryDate: params.expiryDate,
  })
}

// ─── Attendance Notifications ─────────────────────────────────────────────────

export async function notifyAbsent(params: {
  employeeId: string
  date: string
}) {
  const employee = await db.employee.findUnique({
    where: { id: params.employeeId },
    include: {
      department: { select: { name: true } },
      reportingManager: { select: { userId: true } },
    },
  })

  if (!employee) return

  await notify("attendance.absent", {
    employeeName: employee.fullName,
    department: employee.department?.name ?? "N/A",
    date: params.date,
    managerId: employee.reportingManager?.userId ?? undefined,
  })
}

export async function notifyLateCheckIn(params: {
  employeeId: string
  checkInTime: string
  expectedTime: string
}) {
  const employee = await db.employee.findUnique({
    where: { id: params.employeeId },
    include: {
      reportingManager: { select: { userId: true } },
    },
  })

  if (!employee) return

  await notify("attendance.late.checkin", {
    employeeName: employee.fullName,
    checkInTime: params.checkInTime,
    expectedTime: params.expectedTime,
    managerId: employee.reportingManager?.userId ?? undefined,
  })
}

export async function notifyMissingCheckout(params: {
  employeeId: string
  date: string
}) {
  const employee = await db.employee.findUnique({
    where: { id: params.employeeId },
    include: {
      reportingManager: { select: { userId: true } },
    },
  })

  if (!employee) return

  await notify("attendance.missing.checkout", {
    employeeName: employee.fullName,
    date: params.date,
    managerId: employee.reportingManager?.userId ?? undefined,
  })
}

// ─── Custom Notification ──────────────────────────────────────────────────────

export async function notifyCustom(params: {
  title: string
  body: string
  recipientUserIds?: string[]
  triggeredByUserId?: string
  audience?: NotifyData["audience"]
  module?: string
}) {
  await notify("custom", {
    customTitle: params.title,
    customBody: params.body,
    triggeredByUserId: params.triggeredByUserId,
    audience: params.audience,
    module: params.module,
  })
}
