"use server";

import { auth } from "@/auth";
import { db } from "@/lib/db";
import { canPerformAction } from "@/lib/po-state-machine";
import { notify } from "@/lib/notifier";
import { revalidatePath } from "next/cache";

export async function confirmReceipt({
  poId,
  notes,
  deliveries,
}: {
  poId: string;
  notes?: string;
  /**
   * Per-line delivery quantities for this receipt event.
   * Key = line item id, value = quantity delivered now (not cumulative).
   * If omitted or empty, all items are treated as fully delivered.
   */
  deliveries?: Record<string, number>;
}): Promise<{ ok: true; partial: boolean } | { error: string }> {
  const session = await auth();
  if (!session?.user) return { error: "Unauthorized" };

  const po = await db.purchaseOrder.findUnique({
    where: { id: poId },
    include: {
      submitter: true,
      lineItems: true,
      vessel: { include: { site: true } },
    },
  });
  if (!po) return { error: "PO not found" };

  const isAllowedStatus =
    po.status === "PAID_DELIVERED" || po.status === "PARTIALLY_CLOSED";
  if (!isAllowedStatus) {
    return { error: "You cannot confirm receipt on this PO in its current state." };
  }
  if (
    !canPerformAction(po.status, "confirm_receipt", session.user.role) &&
    !canPerformAction(po.status, "confirm_partial_receipt", session.user.role)
  ) {
    return { error: "You do not have permission to confirm receipt on this PO." };
  }
  if (po.submitterId !== session.user.id && session.user.role !== "SUPERUSER") {
    return { error: "You can only confirm receipt on your own purchase orders." };
  }

  // Compute the updated deliveredQuantity for each line item
  const lineUpdates = po.lineItems.map((li) => {
    const prevDelivered = Number(li.deliveredQuantity ?? 0);
    const nowDelivered = deliveries ? (deliveries[li.id] ?? 0) : Number(li.quantity);
    const totalDelivered = prevDelivered + nowDelivered;
    const ordered = Number(li.quantity);
    return {
      id: li.id,
      productId: li.productId,
      quantity: ordered,
      deliveredQuantity: Math.min(totalDelivered, ordered),
      nowDelivered: Math.min(nowDelivered, ordered - prevDelivered),
    };
  });

  // Determine if all items are now fully delivered
  const allDelivered = lineUpdates.every((u) => u.deliveredQuantity >= u.quantity);
  const newStatus = allDelivered ? "CLOSED" : "PARTIALLY_CLOSED";
  const isPartial = !allDelivered;

  // Persist delivery quantities
  await Promise.all(
    lineUpdates.map((u) =>
      db.pOLineItem.update({
        where: { id: u.id },
        data: { deliveredQuantity: u.deliveredQuantity },
      })
    )
  );

  // Update PO status and log action
  await db.purchaseOrder.update({
    where: { id: poId },
    data: {
      status: newStatus,
      closedAt: allDelivered ? new Date() : undefined,
      receipt: notes
        ? { create: { storageKey: "", fileName: "no-file", notes } }
        : undefined,
      actions: {
        create: {
          actionType: isPartial ? "PARTIAL_RECEIPT_CONFIRMED" : "RECEIPT_CONFIRMED",
          actorId: session.user.id,
          note: notes ?? null,
          metadata: isPartial
            ? {
                deliveries: lineUpdates.map((u) => ({
                  lineItemId: u.id,
                  deliveredNow: u.nowDelivered,
                  totalDelivered: u.deliveredQuantity,
                  ordered: u.quantity,
                })),
              }
            : undefined,
        },
      },
    },
  });

  // Auto-update inventory for delivered quantities
  const siteId =
    (po as typeof po & { siteId?: string | null }).siteId ??
    po.vessel?.site?.id ??
    null;

  if (siteId) {
    for (const u of lineUpdates) {
      if (!u.productId || u.nowDelivered <= 0) continue;
      await db.itemInventory.upsert({
        where: { productId_siteId: { productId: u.productId, siteId } },
        update: { quantity: { increment: u.nowDelivered } },
        create: { productId: u.productId, siteId, quantity: u.nowDelivered },
      });
    }
    revalidatePath(`/admin/sites/${siteId}`);
  }

  // Notify on full close only
  if (allDelivered) {
    const [managers, accounts] = await Promise.all([
      db.user.findMany({ where: { role: "MANAGER", isActive: true } }),
      db.user.findMany({ where: { role: "ACCOUNTS", isActive: true } }),
    ]);
    await notify({ event: "RECEIPT_CONFIRMED", po, recipients: [...managers, ...accounts] });
  }

  revalidatePath(`/po/${poId}`);
  revalidatePath("/dashboard");
  revalidatePath("/my-orders");
  return { ok: true, partial: isPartial };
}
