// Reseller portal — Invoices. Pulled live from Xero (see
// GET /api/portal/invoices) — Xero is the source of truth here, so this
// page is a flat, read-only list straight from the response with no
// separate detail-fetch needed (every field the list needs is already
// in XeroInvoiceSummary). Two non-error empty states have to be handled
// gracefully:
//   - `connected: false` — Solo hasn't connected Xero yet at all.
//   - `connected: true, invoices: []` — Xero is connected but this
//     company has no mapped Xero contact yet (happens automatically the
//     first time one of its orders is pushed to Xero).
// Neither of these is a "something's broken" state for the reseller —
// both render as a calm, explanatory empty note, not an error banner.

const INVOICE_STATUS_LABELS_PORTAL = {
  DRAFT: "Draft", SUBMITTED: "Submitted", AUTHORISED: "Authorised",
  PAID: "Paid", VOIDED: "Voided", DELETED: "Deleted",
};
const INVOICE_STATUS_COLORS_PORTAL = {
  DRAFT: "var(--pt-fg-dim)",
  SUBMITTED: "var(--pt-status-po-requested)",
  AUTHORISED: "var(--pt-link)",
  PAID: "var(--pt-status-accepted)",
  VOIDED: "var(--pt-status-rejected)",
  DELETED: "var(--pt-status-rejected)",
};

function ResellerInvoicesPage({ onNavigate }) {
  const [state, setState] = useState({ status: "loading", user: null, company: null, isSoloStaff: false });
  const [companies, setCompanies] = useState([]);
  const [invoices, setInvoices] = useState({ status: "loading", connected: false, items: [], error: "" });

  const loadInvoices = () => {
    setInvoices((i) => ({ ...i, status: "loading" }));
    fetch("/api/portal/invoices", { credentials: "same-origin" })
      .then(async (r) => {
        const data = await r.json().catch(() => ({}));
        return { ok: r.ok, data };
      })
      .then(({ data }) => setInvoices({
        status: "ready",
        connected: !!data.connected,
        items: data.invoices || [],
        error: data.error || "",
      }))
      .catch(() => setInvoices({ status: "ready", connected: false, items: [], error: "" }));
  };

  const loadMe = (onDone) => {
    fetch("/api/portal/me", { credentials: "same-origin" })
      .then(async (r) => {
        if (!r.ok) throw new Error("not signed in");
        return r.json();
      })
      .then((data) => {
        setState({ status: "ready", user: data.user, company: data.company, isSoloStaff: !!data.isSoloStaff });
        if (data.isSoloStaff) {
          fetch("/api/portal/companies", { credentials: "same-origin" })
            .then((r) => (r.ok ? r.json() : { companies: [] }))
            .then((d) => setCompanies(d.companies || []))
            .catch(() => setCompanies([]));
        }
        if (onDone) onDone();
      })
      .catch(() => onNavigate("reseller-login"));
  };

  const handleSwitchCompany = (companyId) => {
    fetch("/api/portal/switch-company", {
      method: "POST", credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ companyId }),
    })
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then(() => loadMe(loadInvoices))
      .catch(() => { /* switch failed silently */ });
  };

  useEffect(() => {
    loadMe();
    loadInvoices();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  if (state.status === "loading") {
    return <section style={{ background: "var(--pt-bg)", minHeight: "calc(100vh - 88px)" }} />;
  }

  const { user, company, isSoloStaff } = state;

  return (
    <ResellerShell
      page="portal-invoices" onNavigate={onNavigate}
      userName={user.name} companyName={company.name}
      isSoloStaff={isSoloStaff} companies={companies}
      currentCompanyId={company.id} onSwitchCompany={handleSwitchCompany}
      subtitle="Reseller portal"
      title="Invoices."
    >
      <p style={{
        fontFamily: "var(--font-body)", fontSize: 14,
        color: "var(--pt-fg-dim)", margin: "-16px 0 36px",
      }}>
        Synced live from Solo's accounting system.
      </p>

      {invoices.status === "loading" ? (
        <div style={{ fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-faint2)" }}>Loading\u2026</div>
      ) : !invoices.connected ? (
        <div style={{
          background: "var(--pt-surface)", border: "1px solid var(--pt-border)",
          padding: "22px 24px", fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-dimmer)",
        }}>
          Invoicing isn't connected yet — check back soon, or raise a support ticket if you're expecting to see something here.
        </div>
      ) : invoices.error ? (
        <div style={{
          background: "var(--pt-error-bg)", border: "1px solid var(--pt-error-border)",
          color: "var(--pt-error-text)", padding: "16px 18px",
          fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
        }}>
          Couldn't load your invoices right now — try again shortly, or raise a support ticket.
        </div>
      ) : invoices.items.length === 0 ? (
        <div style={{
          background: "var(--pt-surface)", border: "1px solid var(--pt-border)",
          padding: "22px 24px", fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-dimmer)",
        }}>
          No invoices yet — these appear here once Solo has raised one against your account.
        </div>
      ) : (
        <div style={{
          background: "var(--pt-surface)", border: "1px solid var(--pt-border)", overflowX: "auto",
        }}>
          <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: "var(--font-body)" }}>
            <thead>
              <tr style={{ borderBottom: "1px solid var(--pt-border-2)" }}>
                <PriceTh>Invoice #</PriceTh>
                <PriceTh>Status</PriceTh>
                <PriceTh>Date</PriceTh>
                <PriceTh>Due</PriceTh>
                <PriceTh right>Total</PriceTh>
                <PriceTh right>Paid</PriceTh>
                <PriceTh right>Due amount</PriceTh>
              </tr>
            </thead>
            <tbody>
              {invoices.items.map((inv) => (
                <tr key={inv.invoiceId} data-testid={`portal-invoice-row-${inv.invoiceId}`} style={{ borderBottom: "1px solid var(--pt-surface-3)" }}>
                  <td style={{ padding: "14px 18px", fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-2)" }}>{inv.invoiceNumber || "\u2014"}</td>
                  <td style={{ padding: "14px 18px" }}>
                    <span style={{
                      color: INVOICE_STATUS_COLORS_PORTAL[inv.status] || "var(--pt-fg-dim)",
                      textTransform: "uppercase", letterSpacing: "0.06em", fontSize: 11.5,
                      fontFamily: "var(--font-body)",
                    }}>{INVOICE_STATUS_LABELS_PORTAL[inv.status] || inv.status}</span>
                  </td>
                  <td style={{ padding: "14px 18px", fontFamily: "var(--font-body)", fontSize: 13, color: "var(--pt-fg-dim)" }}>{(inv.date || "").slice(0, 10)}</td>
                  <td style={{ padding: "14px 18px", fontFamily: "var(--font-body)", fontSize: 13, color: "var(--pt-fg-dim)" }}>{(inv.dueDate || "").slice(0, 10)}</td>
                  <td style={{ padding: "14px 18px", textAlign: "right", fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-2)", fontWeight: 500 }}>{portalMoney(inv.total, inv.currency)}</td>
                  <td style={{ padding: "14px 18px", textAlign: "right", fontFamily: "var(--font-body)", fontSize: 13.5, color: "var(--pt-fg-dim)" }}>{portalMoney(inv.amountPaid, inv.currency)}</td>
                  <td style={{ padding: "14px 18px", textAlign: "right", fontFamily: "var(--font-body)", fontSize: 13.5, color: inv.amountDue > 0 ? "var(--pt-warn-text)" : "var(--pt-fg-dim)" }}>{portalMoney(inv.amountDue, inv.currency)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </ResellerShell>
  );
}

Object.assign(window, { ResellerInvoicesPage });
