// #invoices — AR Task 5 item 3/5. Lists GET /api/c/invoices (already
// ordered overdue-first, then open/partial before paid/void, per
// server/src/invoices.ts's ORDER BY), with a status dropdown and a customer
// picker as filters, and two entry points into InvoiceForm: "New invoice"
// (normal) and "Add older invoice (already in your books)" (document-only —
// design brief's migrated-history entry point).
//
// The customer filter's initial value can arrive pre-set from #customers'
// balance links (see customerFilterHandoff.ts) — consumed once on mount.

import { useEffect, useMemo, useState } from "react";
import { useCompany } from "../lib/company";
import { useApiGet } from "../lib/useApiGet";
import { fmtMoney } from "../lib/money";
import { fmtDate } from "../lib/date";
import { ErrorBanner } from "../components/ErrorBanner";
import type { NavTarget } from "../lib/useHashView";
import { InvoiceForm } from "./InvoiceForm";
import { consumePendingCustomerFilter } from "./customerFilterHandoff";

interface InvoiceListRow {
  invoiceId: string;
  invoiceNo: string | null;
  customerId: string;
  customerName: string;
  invoiceDate: string;
  dueDate: string;
  memo: string | null;
  documentOnly: boolean;
  status: string;
  state: "draft" | "open" | "partial" | "paid" | "void";
  total: string;
  applied: string;
  open: string;
  overdue: boolean;
}

interface InvoiceListResponse {
  total: number;
  invoices: InvoiceListRow[];
}

interface CustomerOption {
  id: string;
  name: string;
}

const STATE_LABEL: Record<InvoiceListRow["state"], string> = {
  draft: "Draft",
  open: "Open",
  partial: "Partly paid",
  paid: "Paid",
  void: "Void",
};

const STATE_CHIP_CLASS: Record<InvoiceListRow["state"], string> = {
  draft: "chip chip-muted",
  open: "chip chip-info",
  partial: "chip chip-warn",
  paid: "chip",
  void: "chip chip-muted",
};

type Mode = { name: "list" } | { name: "create"; documentOnly: boolean };

export function InvoicesScreen({ navigate }: { navigate: (target: NavTarget) => void }) {
  const { selectedCompanyId } = useCompany();
  const [mode, setMode] = useState<Mode>({ name: "list" });
  const [statusFilter, setStatusFilter] = useState<string>("");
  const [customerFilter, setCustomerFilter] = useState<string>("");

  // One-time pickup of a customer filter handed off from #customers (see the
  // file header) — only ever applies on the very first mount.
  useEffect(() => {
    const pending = consumePendingCustomerFilter();
    if (pending) setCustomerFilter(pending);
  }, []);

  const { data: customers } = useApiGet<CustomerOption[]>("/api/c/customers", selectedCompanyId);

  const path = useMemo(() => {
    const params = new URLSearchParams();
    if (statusFilter) params.set("status", statusFilter);
    if (customerFilter) params.set("customerId", customerFilter);
    const qs = params.toString();
    return `/api/c/invoices${qs ? `?${qs}` : ""}`;
  }, [statusFilter, customerFilter]);

  const { data, loading, error, retry } = useApiGet<InvoiceListResponse>(path, selectedCompanyId);

  function goToInvoice(id: string) {
    navigate({ view: "invoice", id });
  }

  return (
    <div className="wrap">
      <header className="top">
        <h1>Invoices</h1>
        {mode.name === "list" && (
          <div style={{ display: "flex", gap: 10 }}>
            <button
              type="button"
              className="btn"
              onClick={() =>
                navigate({
                  view: "receive-payment",
                  params: customerFilter ? { customerId: customerFilter } : {},
                })
              }
            >
              Receive payment
            </button>
            <button type="button" className="btn" onClick={() => setMode({ name: "create", documentOnly: true })}>
              Add older invoice (already in your books)
            </button>
            <button type="button" className="btn" onClick={() => setMode({ name: "create", documentOnly: false })}>
              New invoice
            </button>
          </div>
        )}
      </header>

      {mode.name === "create" && (
        <InvoiceForm
          mode="create"
          documentOnly={mode.documentOnly}
          onCancel={() => setMode({ name: "list" })}
          onSaved={({ invoiceId }) => {
            setMode({ name: "list" });
            goToInvoice(invoiceId);
          }}
        />
      )}

      {mode.name === "list" && (
        <>
          <div className="report-toolbar">
            <label>
              Status
              <select
                className="select-input"
                value={statusFilter}
                onChange={(ev) => setStatusFilter(ev.target.value)}
              >
                <option value="">All</option>
                <option value="draft">Draft</option>
                <option value="open">Open</option>
                <option value="partial">Partly paid</option>
                <option value="paid">Paid</option>
                <option value="void">Void</option>
              </select>
            </label>
            <label>
              Customer
              <select
                className="select-input"
                value={customerFilter}
                onChange={(ev) => setCustomerFilter(ev.target.value)}
              >
                <option value="">All customers</option>
                {(customers ?? []).map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.name}
                  </option>
                ))}
              </select>
            </label>
          </div>

          {error && <ErrorBanner message={error} onRetry={retry} />}
          {loading && !data && <p className="msg-inline">Loading invoices&hellip;</p>}

          {data && data.invoices.length === 0 && (
            <div className="empty-state">No invoices match those filters.</div>
          )}

          {data && data.invoices.length > 0 && (
            <table>
              <thead>
                <tr>
                  <th>Invoice</th>
                  <th>Customer</th>
                  <th>Date</th>
                  <th>Due</th>
                  <th>Status</th>
                  <th className="num">Total</th>
                  <th className="num">Open</th>
                </tr>
              </thead>
              <tbody>
                {data.invoices.map((inv) => (
                  <tr key={inv.invoiceId} style={{ cursor: "pointer" }} onClick={() => goToInvoice(inv.invoiceId)}>
                    <td>{inv.invoiceNo ? `#${inv.invoiceNo}` : "Draft"}</td>
                    <td>{inv.customerName}</td>
                    <td>{fmtDate(inv.invoiceDate)}</td>
                    <td className={inv.overdue ? "invoice-due-overdue" : undefined}>{fmtDate(inv.dueDate)}</td>
                    <td>
                      <span className={STATE_CHIP_CLASS[inv.state]}>{STATE_LABEL[inv.state]}</span>
                      {inv.documentOnly && <span className="badge" style={{ marginLeft: 6 }}>Doc only</span>}
                    </td>
                    <td className="num">{fmtMoney(inv.total)}</td>
                    <td className="num">{fmtMoney(inv.open)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </>
      )}
    </div>
  );
}
