/**
 * Runtime fixture lookups for the staging verification suite.
 *
 * PO ids in `pelagia_test` change on every daily refresh, so specs must not hard-code
 * them. These helpers anchor each spec on a real row that currently exists in the
 * staging DB (read-only), keeping the suite stable across refreshes. They use the
 * SAME `DATABASE_URL` the Playwright run is given (the SSH tunnel to pelagia_test).
 *
 * This is test *setup* only — every assertion still runs against the live UI.
 */
import { PrismaClient } from "@prisma/client";

let _db: PrismaClient | null = null;
export function db(): PrismaClient {
  if (!_db) _db = new PrismaClient();
  return _db;
}
export async function closeDb() {
  if (_db) await _db.$disconnect();
  _db = null;
}

// Mirrors lib/utils.ts POST_APPROVAL_STATUSES — the statuses that count as "approved
// and beyond" for spend/approval trackers (issues #12, #32, #50).
export const POST_APPROVAL_STATUSES = [
  "MGR_APPROVED",
  "SENT_FOR_PAYMENT",
  "PARTIALLY_PAID",
  "PAID_DELIVERED",
  "PARTIALLY_CLOSED",
  "CLOSED",
] as const;

/** First day of the current month in local time (matches the dashboard query). */
export function startOfMonth(now = new Date()): Date {
  return new Date(now.getFullYear(), now.getMonth(), 1);
}

/** Mirror of lib/utils.ts formatDate → e.g. "Jun 11, 2026". */
export function formatDate(date: Date | string): string {
  return new Intl.DateTimeFormat("en-US", { year: "numeric", month: "short", day: "numeric" }).format(
    new Date(date),
  );
}

export async function approvedPo() {
  return db().purchaseOrder.findFirst({
    where: { status: { in: [...POST_APPROVAL_STATUSES] }, approvedAt: { not: null } },
    orderBy: { approvedAt: "desc" },
    select: { id: true, poNumber: true, status: true, approvedAt: true, poDate: true },
  });
}

/**
 * An approved-or-later PO with NO explicit poDate, so its detail "PO Date" must fall
 * back to the approval date — the exact case issue #5 is about.
 */
export async function approvedPoNoPoDate() {
  return db().purchaseOrder.findFirst({
    where: { status: { in: [...POST_APPROVAL_STATUSES] }, approvedAt: { not: null }, poDate: null },
    orderBy: { approvedAt: "desc" },
    select: { id: true, poNumber: true, status: true, approvedAt: true },
  });
}

export async function closedPo() {
  return db().purchaseOrder.findFirst({
    where: { status: "CLOSED" },
    select: { id: true, poNumber: true },
  });
}

/** An approved-or-later PO whose vendor has a contact email (issue #14). */
export async function poWithVendorEmail() {
  return db().purchaseOrder.findFirst({
    where: {
      status: { in: [...POST_APPROVAL_STATUSES] },
      vendor: { contacts: { some: { email: { not: null } } } },
    },
    select: { id: true, poNumber: true, status: true },
  });
}

/** A PO that has at least one line item with a non-empty description (issue #8). */
export async function poWithLineItemDescription() {
  const li = await db().pOLineItem.findFirst({
    where: { description: { not: null }, AND: [{ description: { not: "" } }] },
    select: { description: true, po: { select: { id: true, poNumber: true, status: true } } },
  });
  return li ? { ...li.po, description: li.description as string } : null;
}

/** All CLOSED PO numbers, to assert the manager sees the full closed set (issue #6). */
export async function closedPoNumbers() {
  const rows = await db().purchaseOrder.findMany({
    where: { status: "CLOSED" },
    select: { poNumber: true },
  });
  return rows.map((r) => r.poNumber);
}

/** A PO that has at least one uploaded document, to exercise attachment grouping (#10). */
export async function poWithDocuments() {
  const doc = await db().pODocument.findFirst({
    select: { po: { select: { id: true, poNumber: true } } },
  });
  return doc?.po ?? null;
}

export async function totalPoCount() {
  return db().purchaseOrder.count();
}

/** Count of POs approved in the current month, regardless of current status (issues #12/#32). */
export async function approvedThisMonthCount() {
  return db().purchaseOrder.count({
    where: { status: { in: [...POST_APPROVAL_STATUSES] }, approvedAt: { gte: startOfMonth() } },
  });
}

/** A vendor that has a non-null vendorId code, for search-by-code specs (#57/#109). */
export async function vendorWithCode() {
  return db().vendor.findFirst({
    where: { vendorId: { not: null } },
    select: { name: true, vendorId: true },
  });
}
