import { db } from "@/lib/db";
import type { Role } from "@prisma/client";

// ── Session factory ──────────────────────────────────────────────────────────

export function makeSession(userId: string, role: Role, name = "Test User") {
  return {
    user: { id: userId, name, email: `${role.toLowerCase()}@test.local`, role },
    expires: new Date(Date.now() + 86_400_000).toISOString(),
  };
}

// ── Seeded user lookup (from prisma/seed.ts) ─────────────────────────────────

export async function getSeedUser(email: string) {
  const user = await db.user.findUniqueOrThrow({ where: { email } });
  return user;
}

export async function getSeedVessel(name: string) {
  const v = await db.vessel.findFirstOrThrow({ where: { name } });
  return v;
}

export async function getSeedAccount(code: string) {
  const a = await db.account.findUniqueOrThrow({ where: { code } });
  return a;
}

export async function getSeedVendor(name: string) {
  const v = await db.vendor.findFirstOrThrow({ where: { name } });
  return v;
}

// ── FormData builder ─────────────────────────────────────────────────────────

export function fd(fields: Record<string, string>): FormData {
  const form = new FormData();
  for (const [k, v] of Object.entries(fields)) form.set(k, v);
  return form;
}

// Lines items appended to an existing FormData
export function appendLineItem(
  form: FormData,
  idx: number,
  item: { description: string; quantity: number; unit: string; unitPrice: number; gstRate?: number }
) {
  form.set(`lineItems[${idx}].name`, item.description);
  form.set(`lineItems[${idx}].quantity`, String(item.quantity));
  form.set(`lineItems[${idx}].unit`, item.unit);
  form.set(`lineItems[${idx}].unitPrice`, String(item.unitPrice));
  form.set(`lineItems[${idx}].gstRate`, String(item.gstRate ?? 0.18));
}

export function makePoForm(overrides: {
  title?: string;
  vesselId: string;
  accountId: string;
  vendorId?: string;
  intent?: "draft" | "submit" | "resubmit";
  lineItems?: Array<{ description: string; quantity: number; unit: string; unitPrice: number; gstRate?: number }>;
}): FormData {
  const form = new FormData();
  form.set("title", overrides.title ?? "Test PO");
  form.set("vesselId", overrides.vesselId);
  form.set("accountId", overrides.accountId);
  form.set("intent", overrides.intent ?? "draft");
  if (overrides.vendorId) form.set("vendorId", overrides.vendorId);
  const items = overrides.lineItems ?? [
    { description: "Test Item", quantity: 10, unit: "pc", unitPrice: 100 },
  ];
  items.forEach((item, i) => appendLineItem(form, i, item));
  return form;
}

// ── Cleanup helpers ──────────────────────────────────────────────────────────

// POAction and Receipt have no onDelete: Cascade, so their rows must be removed
// before the PO. (POLineItem / PODocument cascade automatically.)
async function deletePosByIds(ids: string[]) {
  if (ids.length === 0) return;
  await db.pOAction.deleteMany({ where: { poId: { in: ids } } });
  await db.receipt.deleteMany({ where: { poId: { in: ids } } });
  await db.purchaseOrder.deleteMany({ where: { id: { in: ids } } });
}

export async function deletePo(poId: string) {
  await deletePosByIds([poId]).catch(() => {});
}

export async function deletePosByTitle(titlePrefix: string) {
  const pos = await db.purchaseOrder.findMany({
    where: { title: { startsWith: titlePrefix } },
    select: { id: true },
  });
  await deletePosByIds(pos.map((p) => p.id));
}
