import { Resend } from "resend";
import { db } from "@/lib/db";
import type { PurchaseOrder, User } from "@prisma/client";

const isDev = process.env.NODE_ENV === "development";
const resend = isDev ? null : new Resend(process.env.RESEND_API_KEY);
const FROM = `${process.env.EMAIL_FROM_NAME ?? "PPMS"} <${process.env.EMAIL_FROM ?? "noreply@ppms.pelagiamarine.com"}>`;

export type NotificationEvent =
  | "PO_SUBMITTED"
  | "PO_APPROVED"
  | "PO_APPROVED_WITH_NOTE"
  | "PO_REJECTED"
  | "EDITS_REQUESTED"
  | "VENDOR_ID_REQUESTED"
  | "VENDOR_ID_PROVIDED"
  | "PAYMENT_PROCESSING"
  | "PAYMENT_SENT"
  | "RECEIPT_CONFIRMED";

interface NotifyParams {
  event: NotificationEvent;
  po: PurchaseOrder & { submitter: User };
  recipients: User[];
  note?: string;
}

export async function notify({ event, po, recipients, note }: NotifyParams) {
  const subject = buildSubject(event, po.poNumber);
  if (!subject) return;

  await Promise.allSettled(
    recipients.map(async (recipient) => {
      const body = buildInAppBody(event, po, recipient);
      const link = buildInAppLink(event, po, recipient);

      let status = "sent";
      if (isDev) {
        console.log(
          `\n📧 [DEV EMAIL] To: ${recipient.email}\n   Subject: ${subject}\n   Body: ${buildEmailBody(event, po, note)}\n`
        );
      } else {
        try {
          const { error } = await resend!.emails.send({
            from: FROM,
            to: recipient.email,
            subject,
            html: buildHtml(event, po, recipient, note),
          });
          if (error) status = "failed";
        } catch {
          status = "failed";
        }
      }

      await db.notification.create({
        data: { subject, body, link, status, poId: po.id, userId: recipient.id },
      });
    })
  );
}

// ── In-app message ────────────────────────────────────────────────────────────

function buildInAppBody(
  event: NotificationEvent,
  po: PurchaseOrder & { submitter: User },
  recipient: User
): string {
  const pn = po.poNumber;
  const submitter = po.submitter.name;

  switch (event) {
    case "PO_SUBMITTED":
      return recipient.id === po.submitterId
        ? `${pn} submitted for review`
        : `${submitter} submitted ${pn} for your review`;

    case "PO_APPROVED":
    case "PO_APPROVED_WITH_NOTE":
      return recipient.id === po.submitterId
        ? `${pn} approved`
        : `${pn} approved — ready for payment`;

    case "PO_REJECTED":
      return `${pn} rejected`;

    case "EDITS_REQUESTED":
      return `Edits requested on ${pn}`;

    case "VENDOR_ID_REQUESTED":
      return `Vendor ID needed before ${pn} can be approved`;

    case "VENDOR_ID_PROVIDED":
      return `Vendor ID provided for ${pn} — ready to review`;

    case "PAYMENT_PROCESSING":
      return `Payment processing for ${pn}`;

    case "PAYMENT_SENT":
      return `Payment confirmed for ${pn} — please confirm receipt`;

    case "RECEIPT_CONFIRMED":
      return `Receipt confirmed — ${pn} closed`;

    default:
      return `Update on ${pn}`;
  }
}

function buildInAppLink(
  event: NotificationEvent,
  po: PurchaseOrder & { submitter: User },
  recipient: User
): string {
  const isManager   = recipient.role === "MANAGER" || recipient.role === "SUPERUSER";
  const isAccounts  = recipient.role === "ACCOUNTS";
  const isSubmitter = recipient.id === po.submitterId;

  switch (event) {
    // Manager needs to act on the approval queue
    case "PO_SUBMITTED":
    case "VENDOR_ID_PROVIDED":
      return isManager ? `/approvals/${po.id}` : `/po/${po.id}`;

    // Accounts needs to process payment; everyone else sees the PO
    case "PO_APPROVED":
    case "PO_APPROVED_WITH_NOTE":
      return isAccounts ? `/payments` : `/po/${po.id}`;

    // Submitter needs to open the edit form
    case "EDITS_REQUESTED":
      return isSubmitter ? `/po/${po.id}/edit` : `/po/${po.id}`;

    // Submitter needs to confirm receipt
    case "PAYMENT_SENT":
      return isSubmitter ? `/po/${po.id}/receipt` : `/po/${po.id}`;

    default:
      return `/po/${po.id}`;
  }
}

// ── Email subject ─────────────────────────────────────────────────────────────

function buildSubject(event: NotificationEvent, poNumber: string): string | null {
  const base = `PO ${poNumber}`;
  const map: Record<NotificationEvent, string> = {
    PO_SUBMITTED: `${base} submitted for review`,
    PO_APPROVED: `${base} has been approved`,
    PO_APPROVED_WITH_NOTE: `${base} has been approved`,
    PO_REJECTED: `${base} has been rejected`,
    EDITS_REQUESTED: `Edits requested on ${base}`,
    VENDOR_ID_REQUESTED: `Vendor ID needed for ${base}`,
    VENDOR_ID_PROVIDED: `Vendor ID provided for ${base}`,
    PAYMENT_PROCESSING: `Payment initiated for ${base}`,
    PAYMENT_SENT: `Payment confirmed for ${base}`,
    RECEIPT_CONFIRMED: `Receipt confirmed — ${base} closed`,
  };
  return map[event] ?? null;
}

// ── Email HTML ────────────────────────────────────────────────────────────────

function buildHtml(
  event: NotificationEvent,
  po: PurchaseOrder & { submitter: User },
  recipient: User,
  note?: string
): string {
  return `
<!DOCTYPE html>
<html>
<body style="font-family:Inter,sans-serif;max-width:560px;margin:0 auto;padding:32px 24px;color:#111827;">
  <div style="border-bottom:2px solid #2563eb;padding-bottom:12px;margin-bottom:24px;">
    <span style="font-size:20px;font-weight:700;color:#1d4ed8;">PPMS</span>
  </div>
  <p style="margin:0 0 16px;">Hi ${recipient.name},</p>
  <p style="margin:0 0 24px;">${buildEmailBody(event, po, note)}</p>
  <div style="background:#f3f4f6;border-radius:8px;padding:16px;font-size:13px;color:#374151;">
    <strong>PO Number:</strong> ${po.poNumber}<br/>
    <strong>Title:</strong> ${po.title}<br/>
    <strong>Submitted by:</strong> ${po.submitter.name}
  </div>
  <p style="margin-top:32px;font-size:12px;color:#9ca3af;">
    You received this message because you are a stakeholder on this purchase order.
  </p>
</body>
</html>`;
}

function buildEmailBody(
  event: NotificationEvent,
  po: PurchaseOrder & { submitter: User },
  note?: string
): string {
  const noteHtml = note
    ? `<br/><br/><em style="color:#374151;">"${note}"</em>`
    : "";

  switch (event) {
    case "PO_SUBMITTED":
      return `<strong>${po.submitter.name}</strong> has submitted purchase order <strong>${po.poNumber}</strong> for your review.`;
    case "PO_APPROVED":
    case "PO_APPROVED_WITH_NOTE":
      return `Your purchase order <strong>${po.poNumber}</strong> has been <span style="color:#16a34a;font-weight:600;">approved</span>.${noteHtml}`;
    case "PO_REJECTED":
      return `Your purchase order <strong>${po.poNumber}</strong> has been <span style="color:#dc2626;font-weight:600;">rejected</span>.${noteHtml}`;
    case "EDITS_REQUESTED":
      return `Edits have been requested on <strong>${po.poNumber}</strong>. Please update the order and resubmit.${noteHtml}`;
    case "VENDOR_ID_REQUESTED":
      return `A vendor ID is required before <strong>${po.poNumber}</strong> can be approved.`;
    case "VENDOR_ID_PROVIDED":
      return `The vendor ID has been provided for <strong>${po.poNumber}</strong>. It is ready for your review.`;
    case "PAYMENT_PROCESSING":
      return `Payment is being processed for <strong>${po.poNumber}</strong>.`;
    case "PAYMENT_SENT":
      return `Payment has been confirmed for <strong>${po.poNumber}</strong>. Please confirm delivery/receipt when the goods arrive.`;
    case "RECEIPT_CONFIRMED":
      return `Receipt has been confirmed for <strong>${po.poNumber}</strong>. The order is now closed.`;
    default:
      return `There has been an update on purchase order ${po.poNumber}.`;
  }
}
