"use client";

import { use } from "react";
import Link from "next/link";
import { useOrderDetail } from "@/lib/hooks";
import { tidyMerchant } from "@/lib/merchant-label";

/**
 * One order: what it was, what happened to it, and what paid for it.
 *
 * The lifecycle timeline IS the tracking UI. tracking_url is NULL on all 7,608
 * spine rows and on all 11,092 order_event payloads, because the shared HTML
 * renderer strips anchor hrefs before extraction ever sees them (board 208).
 * Do not build a tracking widget against a field nothing populates.
 */

/** What the classifier thought the source document was — see the list page. */
const KIND_LABEL: Record<string, string> = {
  courier_tracking: "delivery notice",
  invoice_receipt: "invoice",
  subscription: "subscription",
  booking: "booking",
  account_notice: "account notice",
};

const EVENT_LABEL: Record<string, string> = {
  placed: "Order placed",
  shipped: "Dispatched",
  out_for_delivery: "Out for delivery",
  delivered: "Delivered",
  cancelled: "Cancelled",
  returned: "Returned",
  refunded: "Refunded",
};

const dateFmt = new Intl.DateTimeFormat("en-AU", { day: "numeric", month: "short", year: "numeric" });

function fmtMoney(amount: string | null | undefined, currency: string) {
  if (amount === null || amount === undefined) return null;
  const n = Number(amount);
  if (!Number.isFinite(n)) return null;
  try {
    return new Intl.NumberFormat("en-AU", { style: "currency", currency, minimumFractionDigits: 2 }).format(n);
  } catch {
    return `${n.toFixed(2)} ${currency}`;
  }
}

function Panel({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <section>
      <h3 className="font-mono text-[10.5px] uppercase tracking-widest text-zinc-500 font-normal pb-2 mb-3 border-b border-zinc-800">
        {title}
      </h3>
      {children}
    </section>
  );
}

export default function OrderDetailPage({ params }: { params: Promise<{ entityKey: string }> }) {
  const { entityKey } = use(params);
  const key = decodeURIComponent(entityKey);
  const { data: o, isLoading, error } = useOrderDetail(key);

  if (isLoading) return <div className="p-6 text-zinc-500 text-sm">Loading order…</div>;
  if (error || !o) {
    // A missing order and a broken query are different problems and must not
    // share a sentence. Only a 404 means "no such order"; anything else is this
    // page failing, and saying so is what sends the next person to the server
    // log instead of to the spine.
    const status = (error as (Error & { status?: number }) | null)?.status;
    return (
      <div className="max-w-[1180px] mx-auto">
        <Link href="/orders" className="font-mono text-[11.5px] text-indigo-400">← All orders</Link>
        {status === 404 ? (
          <p className="mt-6 text-zinc-400 text-sm">That order could not be found.</p>
        ) : (
          <p className="mt-6 text-zinc-400 text-sm">
            This order could not be loaded{status ? ` (server error ${status})` : ""}. The order exists —
            something in this page failed. Check the finance-app log.
          </p>
        )}
      </div>
    );
  }

  const gross = Number(o.gross_total ?? o.order_total ?? NaN);
  const refund = Number(o.refunded_amount ?? NaN);
  const partial = Number.isFinite(gross) && Number.isFinite(refund) && refund > 0 && refund < gross;
  const linkedTotal = o.transactions.reduce((a, t) => a + Math.abs(Number(t.amount) || 0), 0);

  return (
    <div className="max-w-[1180px] mx-auto">
      <Link href="/orders" className="font-mono text-[11.5px] text-indigo-400 hover:text-indigo-300">← All orders</Link>

      {/* A settled rail row must never look like an ordinary order — that is
          how a human counts the same purchase twice. */}
      {/* Board 211 — same shape as the settled-rail banner above: a real
          document with a real figure that is not a purchase. Saying which
          payments it restates is the point; the total alone reads as a
          single large order. */}
      {o.summarises_period && (
        <div className="mt-4 bg-zinc-900 border-l-2 border-amber-600 px-4 py-3">
          <span className="block font-mono text-[10px] uppercase tracking-widest text-amber-500 mb-1">
            Annual summary, not a purchase
          </span>
          <span className="text-[12.5px] text-zinc-300">
            This receipt restates payments already made across the year — the
            monthly debits are in the ledger under their own dates. It is kept
            for reference and excluded from spend totals.
          </span>
        </div>
      )}

      {o.is_settled_duplicate && (
        <div className="mt-4 bg-zinc-900 border-l-2 border-indigo-600 px-4 py-3">
          <span className="block font-mono text-[10px] uppercase tracking-widest text-indigo-500 mb-1">
            Payment record, not a separate purchase
          </span>
          <span className="text-[12.5px] text-zinc-300">
            This restates another order and is deliberately excluded from spend totals.
          </span>
        </div>
      )}

      <header className="border-b border-zinc-800 pb-5 mt-4 mb-6">
        <div className="font-mono text-[11.5px] text-zinc-400 tabular-nums">
          {o.platform}
          {o.order_reference && !o.order_reference.startsWith("msg-") && <> · order {o.order_reference}</>}
          {o.ordered_at && <> · {dateFmt.format(new Date(o.ordered_at))}</>}
        </div>
        <h2 className="font-display text-[27px] leading-tight text-zinc-50 my-3 max-w-[26ch] text-balance">
          {/* canonical_name is the ORDER title ("DJI Air 3 Fly More Combo") and
              is left alone; only the display_name fallback is a merchant name
              and wants tidying. */}
          {o.canonical_name || tidyMerchant(o.display_name ?? "") || "Order"}
        </h2>
        <div className="flex gap-2 flex-wrap mb-3">
          {o.content_class && KIND_LABEL[o.content_class] && (
            <span className="font-mono text-[10px] uppercase tracking-wider text-zinc-400 border border-zinc-700 rounded-sm px-2 py-0.5">
              {KIND_LABEL[o.content_class]}
            </span>
          )}
          {o.cadence_days && (
            <span className="font-mono text-[10px] uppercase tracking-wider text-indigo-400 border border-indigo-800 rounded-sm px-2 py-0.5">
              recurring · every ~{o.cadence_days} days
              {o.order_count ? ` · ${o.order_count} orders` : ""}
            </span>
          )}
        </div>
        <div className="flex gap-6 flex-wrap font-mono text-[11.5px] text-zinc-400 tabular-nums">
          <div>
            <span className="block text-[10px] uppercase tracking-widest text-zinc-500 mb-0.5">
              {partial ? "Charged" : "Total"}
            </span>
            {fmtMoney(o.gross_total ?? o.order_total, o.currency) ?? <span className="italic text-zinc-500">not stated</span>}
          </div>
          {partial && (
            <div>
              <span className="block text-[10px] uppercase tracking-widest text-zinc-500 mb-0.5">Refunded</span>
              <span className="text-indigo-400">−{fmtMoney(o.refunded_amount, o.currency)}</span>
            </div>
          )}
          <div>
            <span className="block text-[10px] uppercase tracking-widest text-zinc-500 mb-0.5">Status</span>
            {o.status.replace(/_/g, " ")}
          </div>
          {o.merchant_name && (
            <div>
              <span className="block text-[10px] uppercase tracking-widest text-zinc-500 mb-0.5">Merchant</span>
              {/* Board 212: the list has tidied this since it shipped and the
                  detail page did not, so following a row through showed
                  "Apple" becoming "Apple Pty Ltd." Presentational only —
                  merges nothing, and Amazon.in stays Amazon.in. */}
              {tidyMerchant(o.merchant_name)}
            </div>
          )}
        </div>
      </header>

      <div className="grid gap-7 lg:grid-cols-[1.15fr_1fr]">
        <div className="flex flex-col gap-7">
          <Panel title="Lifecycle">
            {/* Ordinal markers are legitimate HERE — the events genuinely are a
                sequence and order carries meaning. They are absent from the
                list, where they would only decorate. */}
            <ol className="list-none m-0 p-0">
              {o.events.map((e, i) => (
                <li key={e.fact_id} className="grid grid-cols-[26px_92px_1fr_auto] gap-3 items-baseline py-2 border-b border-zinc-800/60">
                  <span className="font-mono text-[10.5px] text-indigo-600 tabular-nums">{String(i + 1).padStart(2, "0")}</span>
                  <span className="font-mono text-[11.5px] text-zinc-400 tabular-nums">
                    {e.effective_at ? dateFmt.format(new Date(e.effective_at)) : "—"}
                  </span>
                  <span className="text-[13px] text-zinc-100">
                    {EVENT_LABEL[e.event_kind ?? ""] ?? e.event_kind ?? "Event"}
                  </span>
                  <span className="font-mono text-[11.5px] text-zinc-500 tabular-nums">
                    {fmtMoney(e.amount, e.currency ?? o.currency) ?? "—"}
                  </span>
                </li>
              ))}
              {!o.events.length && <li className="py-2 text-[13px] text-zinc-500">No lifecycle events recorded.</li>}
            </ol>
          </Panel>

          <Panel title={`Contents${o.line_items.length ? ` — ${o.line_items.length}` : ""}`}>
            {o.line_items.length ? (
              <ul className="list-none m-0 p-0">
                {o.line_items.map((li, i) => (
                  <li key={i} className="flex justify-between gap-4 py-2 border-b border-zinc-800/60 text-[13px]">
                    <span className="text-zinc-100">
                      {li.description}
                      {li.quantity ? <span className="font-mono text-[11px] text-zinc-500 ml-2">×{li.quantity}</span> : null}
                    </span>
                    <span className="font-mono text-[12.5px] text-zinc-300 tabular-nums whitespace-nowrap">
                      {fmtMoney(li.amount != null ? String(li.amount) : null, o.currency) ?? ""}
                    </span>
                  </li>
                ))}
              </ul>
            ) : (
              <p className="text-[13px] text-zinc-500 italic m-0">No itemised list on this receipt.</p>
            )}
          </Panel>
        </div>

        <div className="flex flex-col gap-7">
          <Panel title={o.transactions.length ? `Payments — ${o.transactions.length} charge${o.transactions.length > 1 ? "s" : ""}` : "Payments"}>
            {o.transactions.length ? (
              <>
                <ul className="list-none m-0 p-0">
                  {o.transactions.map((t) => (
                    <li key={t.transaction_id} className="grid grid-cols-[1fr_auto] gap-3 items-baseline py-2 border-b border-zinc-800/60">
                      <span className="font-mono text-[12px] text-zinc-300">
                        {t.description}
                        <small className="block text-[10.5px] text-zinc-500">
                          {/* Board 205. Four identical "Afterpay" rows are
                              indistinguishable without their position, and
                              indistinguishable rows are what made this order
                              look like four purchases. */}
                          {t.leg_kind === "instalment" && t.leg_index && t.leg_count
                            ? `Instalment ${t.leg_index} of ${t.leg_count} · `
                            : t.leg_kind === "shipment"
                              ? "Shipment · "
                              : ""}
                          {dateFmt.format(new Date(t.transaction_date))} · txn {t.transaction_id}
                        </small>
                      </span>
                      <span className="font-mono text-[13px] text-zinc-50 tabular-nums">
                        {fmtMoney(String(Math.abs(Number(t.amount))), o.currency)}
                      </span>
                    </li>
                  ))}
                </ul>
                <div className="flex justify-between items-baseline pt-3 font-mono text-xs">
                  <span className="uppercase tracking-widest text-[10px] text-zinc-500">Accounted for</span>
                  <span className="text-indigo-300 text-sm tabular-nums">
                    {fmtMoney(String(linkedTotal), o.currency)}
                    {o.gross_total && <span className="text-zinc-500"> of {fmtMoney(o.gross_total, o.currency)}</span>}
                  </span>
                </div>
              </>
            ) : (
              <p className="text-[13px] text-zinc-500 m-0 leading-relaxed">
                No transaction linked yet. The ledger is statement-fed, so a recent purchase has
                nothing to match against until its card statement is imported — often a few weeks.
                Charges only; refunds and fees are not linked in this phase.
              </p>
            )}
          </Panel>

          {o.siblings.length > 0 && (
            <Panel title="Also recorded as">
              <ul className="list-none m-0 p-0">
                {o.siblings.map((s) => (
                  <li key={s.entity_key} className="py-2 border-b border-zinc-800/60">
                    <Link href={`/orders/${encodeURIComponent(s.entity_key)}`}
                          className="text-[13px] text-zinc-100 hover:text-indigo-300">
                      {s.canonical_name || s.entity_key}
                    </Link>
                    <span className="block font-mono text-[11px] text-zinc-500 tabular-nums">
                      {s.relation === "settled_by"
                        ? "paid via this record"
                        : "this record pays for that order"}
                      {" · "}{s.platform}
                      {s.order_total && <> · {fmtMoney(s.order_total, s.currency)}</>}
                    </span>
                  </li>
                ))}
              </ul>
            </Panel>
          )}

          <Panel title="Provenance">
            <dl className="grid grid-cols-[auto_1fr] gap-x-4 gap-y-2 font-mono text-[11.5px] m-0">
              <dt className="text-zinc-500">Key</dt>
              <dd className="text-zinc-300 m-0 break-all">{o.entity_key}</dd>
              <dt className="text-zinc-500">Reference</dt>
              <dd className="text-zinc-300 m-0">
                {o.reference_source === "message_id_fallback"
                  ? <span className="text-indigo-500">none printed — cannot merge with siblings</span>
                  : (o.order_reference ?? "—")}
              </dd>
              <dt className="text-zinc-500">Lane</dt>
              <dd className="text-zinc-300 m-0">{o.lane}</dd>
              <dt className="text-zinc-500">Trust</dt>
              <dd className="text-zinc-300 m-0">{o.source_trust ?? "—"}</dd>
            </dl>
          </Panel>
        </div>
      </div>
    </div>
  );
}
