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"}>`;
const APP_URL = (process.env.NEXTAUTH_URL ?? "https://portal.pelagiamarine.com").replace(/\/$/, "");

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

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

type EnrichedPo = PurchaseOrder & {
  submitter: User;
  vendor: { name: string } | null;
  vessel: { name: string } | null;
  account: { name: string; code: string } | null;
  lineItems: {
    name: string;
    quantity: import("@prisma/client").Prisma.Decimal;
    unit: string;
    unitPrice: import("@prisma/client").Prisma.Decimal;
    gstRate: import("@prisma/client").Prisma.Decimal | null;
  }[];
};

function fmt(n: number): string {
  return new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR", maximumFractionDigits: 2 }).format(n);
}

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

  // Fetch full PO once so all emails in this batch get line items / vendor / vessel
  const enriched = await db.purchaseOrder.findUnique({
    where: { id: po.id },
    include: {
      submitter: true,
      vendor: { select: { name: true } },
      vessel: { select: { name: true } },
      account: { select: { name: true, code: true } },
      lineItems: { orderBy: { sortOrder: "asc" }, select: { name: true, quantity: true, unit: true, unitPrice: true, gstRate: true } },
    },
  }) as EnrichedPo | null;

  const richPo: EnrichedPo = enriched ?? { ...po, vendor: null, vessel: null, account: null, lineItems: [] };

  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   Link: ${APP_URL}${link}\n`
        );
      } else {
        try {
          const { error } = await resend!.emails.send({
            from: FROM,
            to: recipient.email,
            subject,
            html: buildHtml(event, richPo, 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 "PO_CANCELLED":
      return `${pn} has been cancelled`;

    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`;

    case "PARTIAL_RECEIPT_CONFIRMED":
      return `Partial receipt confirmed on ${pn} — items still outstanding`;

    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) {
    case "PO_SUBMITTED":
    case "VENDOR_ID_PROVIDED":
      return isManager ? `/approvals/${po.id}` : `/po/${po.id}`;

    case "PO_APPROVED":
    case "PO_APPROVED_WITH_NOTE":
      return isAccounts ? `/payments` : `/po/${po.id}`;

    case "EDITS_REQUESTED":
      return isSubmitter ? `/po/${po.id}/edit` : `/po/${po.id}`;

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

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

// ── Email action label (button text) ──────────────────────────────────────────

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

  switch (event) {
    case "PO_SUBMITTED":
    case "VENDOR_ID_PROVIDED":
      return isManager ? "Review Purchase Order" : "View Purchase Order";
    case "PO_APPROVED":
    case "PO_APPROVED_WITH_NOTE":
      return isAccounts ? "Process Payment" : "View Purchase Order";
    case "PO_REJECTED":
      return "View Purchase Order";
    case "EDITS_REQUESTED":
      return isSubmitter ? "Edit Purchase Order" : "View Purchase Order";
    case "VENDOR_ID_REQUESTED":
      return "Provide Vendor ID";
    case "PAYMENT_PROCESSING":
      return "View Purchase Order";
    case "PAYMENT_SENT":
      return isSubmitter ? "Confirm Receipt" : "View Purchase Order";
    case "RECEIPT_CONFIRMED":
    case "PARTIAL_RECEIPT_CONFIRMED":
      return "View Purchase Order";
    default:
      return "View Purchase Order";
  }
}

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

function buildSubject(event: NotificationEvent, poNumber: string): string | null {
  const base = `Purchase Order ${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`,
    PO_CANCELLED:           `${base} has been cancelled`,
    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`,
    PARTIAL_RECEIPT_CONFIRMED:    `Partial receipt confirmed for ${base}`,
  };
  return map[event] ?? null;
}

// ── Email body text ───────────────────────────────────────────────────────────

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 "PO_CANCELLED":
      return `Purchase order <strong>${po.poNumber}</strong> has been <span style="color:#dc2626;font-weight:600;">cancelled</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.`;
    case "PARTIAL_RECEIPT_CONFIRMED":
      return `A partial delivery has been confirmed for <strong>${po.poNumber}</strong>. Some items are still outstanding.`;
    default:
      return `There has been an update on purchase order ${po.poNumber}.`;
  }
}

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

function buildHtml(
  event: NotificationEvent,
  po: EnrichedPo,
  recipient: User,
  note?: string
): string {
  const actionPath  = buildInAppLink(event, po, recipient);
  const actionUrl   = `${APP_URL}${actionPath}`;
  const actionLabel = buildActionLabel(event, recipient, po);
  const bodyText    = buildEmailBody(event, po, note);

  const totalAmount = Number(po.totalAmount);

  // ── PO summary card ────────────────────────────────────────────────────────
  const summaryRows = [
    ["Purchase Order", `<span style="font-family:monospace;">${po.poNumber}</span>`],
    ["Title", po.title],
    ["Submitted by", po.submitter.name],
    po.vendor   ? ["Vendor",     po.vendor.name]                     : null,
    po.vessel   ? ["Vessel",     po.vessel.name]                     : null,
    po.account  ? ["Cost Centre", `${po.account.name} (${po.account.code})`] : null,
    ["Total Amount", `<strong>${fmt(totalAmount)}</strong>`],
  ]
    .filter(Boolean)
    .map(
      (row) =>
        `<tr>
          <td style="padding:4px 12px 4px 0;font-size:13px;color:#6b7280;white-space:nowrap;vertical-align:top;">${row![0]}</td>
          <td style="padding:4px 0;font-size:13px;color:#111827;">${row![1]}</td>
        </tr>`
    )
    .join("");

  // ── Line items table ───────────────────────────────────────────────────────
  const lineItemRows = po.lineItems
    .map((li) => {
      const qty      = Number(li.quantity);
      const price    = Number(li.unitPrice);
      const gst      = Number(li.gstRate ?? 0.18);
      const lineTotal = qty * price * (1 + gst);
      return `<tr style="border-bottom:1px solid #f3f4f6;">
        <td style="padding:7px 8px 7px 0;font-size:13px;color:#111827;">${li.name}</td>
        <td style="padding:7px 4px;font-size:13px;color:#374151;text-align:right;white-space:nowrap;">${qty} ${li.unit}</td>
        <td style="padding:7px 4px;font-size:13px;color:#374151;text-align:right;white-space:nowrap;">${fmt(price)}</td>
        <td style="padding:7px 0 7px 4px;font-size:13px;color:#374151;text-align:right;white-space:nowrap;">${Math.round(gst * 100)}%</td>
        <td style="padding:7px 0 7px 4px;font-size:13px;color:#111827;font-weight:600;text-align:right;white-space:nowrap;">${fmt(lineTotal)}</td>
      </tr>`;
    })
    .join("");

  const lineItemsSection = po.lineItems.length > 0
    ? `<div style="margin-top:24px;">
        <p style="margin:0 0 8px;font-size:13px;font-weight:600;color:#374151;text-transform:uppercase;letter-spacing:0.05em;">Line Items</p>
        <table style="width:100%;border-collapse:collapse;border-top:1px solid #e5e7eb;">
          <thead>
            <tr style="background:#f9fafb;">
              <th style="padding:6px 8px 6px 0;font-size:12px;font-weight:600;color:#6b7280;text-align:left;">Item</th>
              <th style="padding:6px 4px;font-size:12px;font-weight:600;color:#6b7280;text-align:right;">Qty</th>
              <th style="padding:6px 4px;font-size:12px;font-weight:600;color:#6b7280;text-align:right;">Unit Price</th>
              <th style="padding:6px 4px;font-size:12px;font-weight:600;color:#6b7280;text-align:right;">GST</th>
              <th style="padding:6px 0 6px 4px;font-size:12px;font-weight:600;color:#6b7280;text-align:right;">Total</th>
            </tr>
          </thead>
          <tbody>${lineItemRows}</tbody>
          <tfoot>
            <tr style="border-top:2px solid #e5e7eb;">
              <td colspan="4" style="padding:8px 4px 0 0;font-size:13px;font-weight:700;color:#111827;text-align:right;">Grand Total</td>
              <td style="padding:8px 0 0 4px;font-size:14px;font-weight:700;color:#1d4ed8;text-align:right;">${fmt(totalAmount)}</td>
            </tr>
          </tfoot>
        </table>
      </div>`
    : "";

  return `<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=device-width,initial-scale=1"/></head>
<body style="margin:0;padding:0;background:#f9fafb;font-family:Inter,-apple-system,sans-serif;">
  <table width="100%" cellpadding="0" cellspacing="0" style="background:#f9fafb;padding:32px 16px;">
    <tr><td align="center">
      <table width="560" cellpadding="0" cellspacing="0" style="max-width:560px;width:100%;background:#ffffff;border-radius:12px;border:1px solid #e5e7eb;overflow:hidden;">

        <!-- Header -->
        <tr><td style="background:#1d4ed8;padding:20px 32px;">
          <span style="font-size:22px;font-weight:700;color:#ffffff;letter-spacing:-0.5px;">PPMS</span>
          <span style="font-size:13px;color:#93c5fd;margin-left:10px;">Pelagia Marine</span>
        </td></tr>

        <!-- Body -->
        <tr><td style="padding:32px;">
          <p style="margin:0 0 20px;font-size:15px;color:#111827;">Hi ${recipient.name},</p>
          <p style="margin:0 0 24px;font-size:15px;color:#374151;line-height:1.6;">${bodyText}</p>

          <!-- Action button -->
          <table cellpadding="0" cellspacing="0" style="margin-bottom:32px;">
            <tr><td style="background:#2563eb;border-radius:8px;">
              <a href="${actionUrl}" style="display:inline-block;padding:12px 24px;font-size:14px;font-weight:600;color:#ffffff;text-decoration:none;">${actionLabel} →</a>
            </td></tr>
          </table>

          <!-- PO summary -->
          <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:16px 20px;margin-bottom:4px;">
            <p style="margin:0 0 10px;font-size:12px;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:0.06em;">Purchase Order Details</p>
            <table cellpadding="0" cellspacing="0" style="width:100%;">
              ${summaryRows}
            </table>
          </div>

          ${lineItemsSection}

        </td></tr>

        <!-- Footer -->
        <tr><td style="background:#f8fafc;border-top:1px solid #e5e7eb;padding:16px 32px;text-align:center;">
          <p style="margin:0;font-size:12px;color:#9ca3af;">
            You received this because you are a stakeholder on this purchase order.
          </p>
        </td></tr>

      </table>
    </td></tr>
  </table>
</body>
</html>`;
}
