/* Stratum Leads — Operations Console. Wallet & Billing: the platform-wide
   Strata ledger and failed-payment queue. Financial ops only — ticket and
   account detail live on their own pages; this one only links out to them. */

/* Design-system components — each Babel script has its own scope, so every
   ops-*.jsx file must destructure what it needs from the namespace. */
const { NavItem, IconButton, WalletPill, Tabs, LeadCard, Button, Field, Card, Metric, StatusChip, TierBadge, ContactQuality, ProgressBar, StrataAmount, Checkbox, Switch, Avatar, AvatarStack, SegmentedControl, GateCard, EmptyState, Toast } = window.StratumLeadsDesignSystem_6367ed;

const { I, fmtStrata, fmtSigned, getCustomer, Spinner, IconRefreshCw, IconTrendArrow } = window.OpsShared;
const FINANCE = window.STRATUM_OPS.FINANCE;
const NOW_TS = window.STRATUM_OPS.NOW_TS;
const DAY_MS = 86400000;
const fmtUSD = (n) => "$" + fmtStrata(n);

const DATE_WINDOWS = [
{ value: "day", label: "Day" },
{ value: "week", label: "Week" },
{ value: "month", label: "Month" },
{ value: "year", label: "Year" },
{ value: "ytd", label: "YTD" }];


function windowStartMs(key) {
  const d = new Date(NOW_TS);
  if (key === "day") return NOW_TS - DAY_MS;
  if (key === "week") return NOW_TS - 7 * DAY_MS;
  if (key === "month") return NOW_TS - 30 * DAY_MS;
  if (key === "year") return NOW_TS - 365 * DAY_MS;
  if (key === "ytd") return new Date(d.getFullYear(), 0, 1).getTime();
  return 0;
}
function downloadCsv(filename, rows) {
  const csv = rows.map((row) => row.map((v) => {
    const s = String(v ?? "");
    return /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
  }).join(",")).join("\n");
  const blob = new Blob([csv], { type: "text/csv" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;a.download = filename;
  document.body.appendChild(a);a.click();document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 2000);
}

const LEDGER_TYPE_LABEL = { reload: "Reload", spend: "Bid spend", refund: "Refund", credit: "Support credit", chargeback: "Chargeback", debit: "Debit / correction" };
const LEDGER_TYPE_TONE = { reload: "info", spend: "neutral", refund: "success", credit: "violet", chargeback: "danger", debit: "warning" };

/* ---- lightweight customer picker used only for "New Adjustment" ---- */
function CustomerPicker({ customers, onPick }) {
  const [query, setQuery] = React.useState("");
  const [open, setOpen] = React.useState(false);
  const q = query.trim().toLowerCase();
  const matches = q.length > 0 ? customers.filter((c) => c.name.toLowerCase().includes(q) || c.id.toLowerCase().includes(q)).slice(0, 6) : [];
  return (
    <div style={{ position: "relative", width: 260 }}>
      <Field icon={I("search")} placeholder="Find a customer to adjust..." value={query} onChange={(e) => {setQuery(e.target.value);setOpen(true);}} onFocus={() => setOpen(true)} onBlur={() => setTimeout(() => setOpen(false), 150)} />
      {open && matches.length > 0 &&
      <div style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, right: 0, background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--radius-sm)", boxShadow: "var(--shadow-md)", zIndex: 30, maxHeight: 240, overflowY: "auto" }}>
          {matches.map((c) =>
        <button key={c.id} onMouseDown={() => {onPick(c.id);setQuery("");setOpen(false);}} style={{ display: "block", width: "100%", textAlign: "left", padding: "10px 12px", border: "none", borderBottom: "1px solid var(--border-subtle)", background: "transparent", cursor: "pointer" }}>
              <strong style={{ fontSize: 13, display: "block" }}>{c.name}</strong>
              <span style={{ fontSize: 11, color: "var(--text-muted)" }}>{c.id}</span>
            </button>
        )}
        </div>
      }
    </div>);

}

function LedgerRow({ r, onOpenCustomer }) {
  const cust = getCustomer(r.customerId);
  return (
    <div style={{ display: "grid", gridTemplateColumns: "110px 1.3fr 110px 100px 100px 90px", gap: 12, alignItems: "center", padding: "11px 16px", borderBottom: "1px solid var(--border-subtle)", fontSize: 13 }}>
      <span style={{ fontSize: 11.5, color: "var(--text-muted)", fontFamily: "var(--font-mono)" }}>{r.createdAt}</span>
      <span style={{ minWidth: 0 }}>
        <button onClick={() => onOpenCustomer(r.customerId)} style={{ border: "none", background: "transparent", padding: 0, cursor: "pointer", color: "var(--text)", fontWeight: 700, fontSize: 13 }}>{cust?.name || r.customerId}</button>
        <span style={{ display: "block", fontSize: 11.5, color: "var(--text-muted)" }}>{r.note}</span>
      </span>
      <StatusChip tone={LEDGER_TYPE_TONE[r.type]}>{LEDGER_TYPE_LABEL[r.type]}</StatusChip>
      <span style={{ fontFamily: "var(--font-mono)", fontWeight: 700, color: r.amount < 0 ? "var(--danger)" : "var(--success)" }}>{fmtSigned(r.amount)}</span>
      <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-muted)" }}>{fmtStrata(r.balanceAfter)}</span>
      <StatusChip tone={r.status === "succeeded" ? "success" : r.status === "failed" ? "danger" : "warning"}>{r.status}</StatusChip>
    </div>);

}

function LedgerTab({ ledger, onOpenCustomer }) {
  const [type, setType] = React.useState("all");
  const [query, setQuery] = React.useState("");
  const q = query.trim().toLowerCase();
  const rows = ledger.
  filter((r) => type === "all" || r.type === type).
  filter((r) => {
    if (q === "") return true;
    const cust = getCustomer(r.customerId);
    return r.id.toLowerCase().includes(q) || cust && cust.name.toLowerCase().includes(q) || r.note.toLowerCase().includes(q);
  });

  return (
    <div>
      <div style={{ display: "flex", gap: 10, marginBottom: 14, flexWrap: "wrap" }}>
        <Field as="select" value={type} onChange={(e) => setType(e.target.value)} style={{ width: 200 }}>
          <option value="all">All types</option>
          {Object.keys(LEDGER_TYPE_LABEL).map((t) => <option key={t} value={t}>{LEDGER_TYPE_LABEL[t]}</option>)}
        </Field>
        <div style={{ width: 260 }}><Field icon={I("search")} placeholder="Search customer or note..." value={query} onChange={(e) => setQuery(e.target.value)} /></div>
      </div>
      <div style={{ border: "1px solid var(--border)", borderRadius: "var(--radius-md)", background: "var(--surface)", overflow: "hidden" }}>
        <div style={{ display: "grid", gridTemplateColumns: "110px 1.3fr 110px 100px 100px 90px", gap: 12, padding: "10px 16px", fontSize: 11, fontWeight: 800, textTransform: "uppercase", letterSpacing: "0.03em", color: "var(--text-subtle)", borderBottom: "1px solid var(--border)" }}>
          <span>Date</span><span>Customer / note</span><span>Type</span><span>Amount</span><span>Balance</span><span>Status</span>
        </div>
        {rows.length === 0 ? <EmptyState icon="list" title="No transactions match" /> : rows.map((r) => <LedgerRow key={r.id} r={r} onOpenCustomer={onOpenCustomer} />)}
      </div>
    </div>);

}

function FailedPaymentsTab({ ledger, onRetryCharge, onOpenAdjustWallet, onOpenCustomer }) {
  const rows = ledger.filter((r) => r.status === "failed");
  const [retryingId, setRetryingId] = React.useState(null);

  const retry = (id) => {
    setRetryingId(id);
    setTimeout(() => {onRetryCharge(id);setRetryingId(null);}, 1100);
  };

  return (
    <div style={{ border: "1px solid var(--border)", borderRadius: "var(--radius-md)", background: "var(--surface)", overflow: "hidden" }}>
      {rows.length === 0 ?
      <EmptyState icon="check-circle-2" title="No failed payments" message="Every reload and charge is currently succeeding." /> :

      rows.map((r, i) => {
        const cust = getCustomer(r.customerId);
        const retrying = retryingId === r.id;
        return (
          <div key={r.id} style={{ display: "grid", gridTemplateColumns: "1fr auto auto auto auto", gap: 14, alignItems: "center", padding: "14px 16px", borderTop: i === 0 ? "none" : "1px solid var(--border-subtle)" }}>
              <span style={{ minWidth: 0 }}>
                <button onClick={() => onOpenCustomer(r.customerId)} style={{ border: "none", background: "transparent", padding: 0, cursor: "pointer", fontWeight: 700, fontSize: 13.5, color: "var(--text)", display: "block" }}>{cust?.name || r.customerId}</button>
                <span style={{ fontSize: 12, color: "var(--text-muted)" }}>{r.note}</span>
              </span>
              <StrataAmount amount={r.amount} size="sm" />
              <span style={{ fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap" }}>{r.createdAt}</span>
              <Button size="sm" variant="secondary" disabled={retrying} icon={retrying ? <Spinner size={13} /> : <IconRefreshCw size={13} />} onClick={() => retry(r.id)}>{retrying ? "Retrying…" : "Retry Charge"}</Button>
              <Button size="sm" variant="secondary" icon={I("wallet-cards", { width: 13 })} onClick={() => onOpenAdjustWallet({ customerId: r.customerId })}>Manual Credit</Button>
            </div>);

      })
      }
    </div>);

}

function TransferRow({ t }) {
  const inbound = t.direction === "in";
  return (
    <div style={{ display: "grid", gridTemplateColumns: "100px 1.4fr 90px 130px 110px", gap: 12, alignItems: "center", padding: "11px 16px", borderBottom: "1px solid var(--border-subtle)", fontSize: 13 }}>
      <span style={{ fontSize: 11.5, color: "var(--text-muted)", fontFamily: "var(--font-mono)" }}>{t.date}</span>
      <span style={{ fontWeight: 600 }}>{t.source}</span>
      <StatusChip tone={inbound ? "success" : "neutral"}>{inbound ? "In" : "Out"}</StatusChip>
      <span style={{ fontFamily: "var(--font-mono)", fontWeight: 700, color: inbound ? "var(--success)" : "var(--text)" }}>{inbound ? "+" : "\u2212"}{fmtUSD(t.amount)}</span>
      <StatusChip tone={t.status === "completed" ? "success" : t.status === "requested" ? "warning" : "neutral"}>{t.status}</StatusChip>
    </div>);

}

function MoneyRow({ icon, label, value, sub, tone = "in" }) {
  return (
    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "9px 0", borderBottom: "1px solid var(--border-subtle)" }}>
      <span style={{ display: "flex", alignItems: "center", gap: 9, fontSize: 13, color: "var(--text)" }}>
        <span style={{ width: 26, height: 26, flexShrink: 0, display: "grid", placeItems: "center", borderRadius: "50%", background: tone === "in" ? "var(--success-soft)" : tone === "out" ? "var(--danger-soft)" : "var(--warning-soft)", color: tone === "in" ? "var(--success)" : tone === "out" ? "var(--danger)" : "var(--warning)" }}>{icon}</span>
        <span>{label}{sub && <span style={{ display: "block", fontSize: 11, color: "var(--text-muted)", fontWeight: 500 }}>{sub}</span>}</span>
      </span>
      <span style={{ fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 13.5, whiteSpace: "nowrap" }}>{value}</span>
    </div>);

}

function FinanceOverviewTab({ customers, ledger }) {
  const [period, setPeriod] = React.useState("month");
  const [sortKey, setSortKey] = React.useState("ts");
  const [sortDir, setSortDir] = React.useState("desc");
  React.useEffect(refresh, [period, sortKey, sortDir]);

  const since = windowStartMs(period);
  const periodLabel = (DATE_WINDOWS.find((w) => w.value === period) || {}).label || period;

  // Point-in-time balances are NOT filtered by the date window — only flows are.
  const circulation = customers.reduce((s, c) => s + c.wallet.available, 0);

  const reloadVolume = ledger.filter((r) => r.type === "reload" && r.status === "succeeded" && r.ts >= since).reduce((s, r) => s + r.amount, 0);
  const creditsIssued = ledger.filter((r) => (r.type === "credit" || r.type === "refund") && r.status === "succeeded" && r.ts >= since).reduce((s, r) => s + r.amount, 0);
  const subscriptionRevenue = customers.flatMap((c) => c.invoices).filter((i) => i.status === "paid" && i.ts >= since).reduce((s, i) => s + i.amount, 0);
  const newAccounts = customers.filter((c) => Math.min(new Date(c.createdAt).getTime(), NOW_TS) >= since).length;
  const periodTransfers = FINANCE.transfers.filter((t) => t.ts >= since);
  const transferredIn = periodTransfers.filter((t) => t.direction === "in" && t.status === "completed").reduce((s, t) => s + t.amount, 0);
  const transferredOut = periodTransfers.filter((t) => t.direction === "out" && t.status === "completed").reduce((s, t) => s + t.amount, 0);
  const pendingOut = periodTransfers.filter((t) => t.direction === "out" && t.status === "requested").reduce((s, t) => s + t.amount, 0);

  const sortedTransfers = [...periodTransfers].sort((a, b) => {
    let av = a[sortKey],bv = b[sortKey];
    if (sortKey === "source") {av = a.source.toLowerCase();bv = b.source.toLowerCase();}
    if (av < bv) return sortDir === "asc" ? -1 : 1;
    if (av > bv) return sortDir === "asc" ? 1 : -1;
    return 0;
  });

  const toggleSort = (key) => {
    if (sortKey === key) setSortDir((d) => d === "asc" ? "desc" : "asc");else {setSortKey(key);setSortDir("desc");}
  };
  const sortIcon = (key) => sortKey === key ? <IconTrendArrow dir={sortDir === "asc" ? "up" : "down"} size={11} /> : null;
  const exportCsv = () => {
    const rows = [["Date", "Description", "Direction", "Amount (USD)", "Status"]];
    sortedTransfers.forEach((t) => rows.push([new Date(t.ts).toISOString().slice(0, 10), t.source, t.direction, t.amount.toFixed(2), t.status]));
    downloadCsv(`stratum-bank-transfers-${period}.csv`, rows);
  };

  const moneyIn = subscriptionRevenue + transferredIn;
  const netUsd = moneyIn - transferredOut;
  const COLS = "100px 1.4fr 90px 130px 110px";

  return (
    <div style={{ display: "grid", gap: 20 }}>
      <div style={{ display: "flex", alignItems: "stretch", justifyContent: "space-between", gap: 14, flexWrap: "wrap" }}>
        <Card title={FINANCE.bankAccount.name} note={`${FINANCE.bankAccount.bank} \u2022\u2022\u2022\u2022 ${FINANCE.bankAccount.last4}`} style={{ flex: "1 1 260px" }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: "var(--text-3xl)", fontWeight: "var(--weight-extrabold)", letterSpacing: "var(--tracking-tight)" }}>{fmtUSD(FINANCE.bankAccount.balance)}</div>
          <div style={{ fontSize: 12, color: "var(--text-muted)", marginTop: 4 }}>Operating balance as of {FINANCE.bankAccount.asOf}{" — a snapshot, not affected by the date window"}</div>
        </Card>
        <Card title="Net cash flow" note={periodLabel} style={{ flex: "1 1 220px" }}>
          <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: "var(--text-3xl)", fontWeight: "var(--weight-extrabold)", letterSpacing: "var(--tracking-tight)", color: netUsd >= 0 ? "var(--success)" : "var(--danger)" }}>{netUsd >= 0 ? "+" : "\u2212"}{fmtUSD(Math.abs(netUsd))}</span>
            <IconTrendArrow dir={netUsd >= 0 ? "up" : "down"} size={16} style={{ color: netUsd >= 0 ? "var(--success)" : "var(--danger)" }} />
          </div>
          <div style={{ fontSize: 12, color: "var(--text-muted)", marginTop: 4 }}>Money in minus money out, this period</div>
        </Card>
        <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", justifyContent: "center", gap: 6, flex: "0 0 auto" }}>
          <span style={{ fontSize: 11, fontWeight: 800, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--text-subtle)" }}>Showing</span>
          <SegmentedControl value={period} onChange={setPeriod} options={DATE_WINDOWS} />
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
        <Card title="Money in" note={periodLabel} style={{ background: "var(--success-soft)", boxShadow: "none" }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: "var(--text-2xl)", fontWeight: "var(--weight-extrabold)", color: "var(--success)", marginBottom: 6 }}>{fmtUSD(moneyIn)}</div>
          <MoneyRow tone="in" icon={I("receipt", { width: 13 })} label="Subscription charges collected" value={fmtUSD(subscriptionRevenue)} />
          <MoneyRow tone="in" icon={I("landmark", { width: 13 })} label="Settled from processor" value={fmtUSD(transferredIn)} />
        </Card>
        <Card title="Money out" note={periodLabel} style={{ background: "var(--danger-soft)", boxShadow: "none" }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: "var(--text-2xl)", fontWeight: "var(--weight-extrabold)", color: "var(--danger)", marginBottom: 6 }}>{fmtUSD(transferredOut)}</div>
          <MoneyRow tone="out" icon={I("arrow-up-right", { width: 13 })} label="Payouts & vendor transfers" value={fmtUSD(transferredOut)} />
          <MoneyRow tone="pending" icon={I("clock", { width: 13 })} label="Requested, not yet transferred" value={fmtUSD(pendingOut)} sub={pendingOut > 0 ? "Awaiting bank confirmation" : null} />
        </Card>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(170px,1fr))", gap: 12 }}>
        <Metric icon={I("coins")} value={fmtStrata(circulation)} label="Strata in circulation (now)" accent="violet" style={{ boxShadow: "none", background: "var(--surface-subtle)" }} />
        <Metric icon={I("arrow-down-to-line")} value={fmtStrata(reloadVolume)} label={`Wallet loads \u2014 ${periodLabel}`} accent="cyan" style={{ boxShadow: "none", background: "var(--surface-subtle)" }} />
        <Metric icon={I("badge-check")} value={fmtStrata(creditsIssued)} label={`Credits & refunds \u2014 ${periodLabel}`} accent="green" style={{ boxShadow: "none", background: "var(--surface-subtle)" }} />
        <Metric icon={I("user-plus")} value={newAccounts} label={`New accounts \u2014 ${periodLabel}`} accent="violet" style={{ boxShadow: "none", background: "var(--surface-subtle)" }} />
      </div>

      <Card title="Bank transfers" note={`${sortedTransfers.length} in ${periodLabel.toLowerCase()} \u2014 settlements in, payouts out`} actions={
      <Button size="sm" variant="secondary" icon={I("download", { width: 13 })} onClick={exportCsv} disabled={sortedTransfers.length === 0}>Export CSV</Button>
      }>
        <div style={{ display: "grid", gridTemplateColumns: COLS, gap: 12, padding: "0 16px 10px", fontSize: 11, fontWeight: 800, textTransform: "uppercase", letterSpacing: "0.03em", color: "var(--text-subtle)", borderBottom: "1px solid var(--border)" }}>
          {[["ts", "Date"], ["source", "Description"], ["direction", "Direction"], ["amount", "Amount"], ["status", "Status"]].map(([key, label]) =>
          <button key={key} onClick={() => toggleSort(key)} style={{ display: "flex", alignItems: "center", gap: 4, border: "none", background: "transparent", padding: 0, cursor: "pointer", font: "inherit", color: "inherit", textTransform: "inherit", letterSpacing: "inherit" }}>{label}{sortIcon(key)}</button>
          )}
        </div>
        <div style={{ margin: "0 -16px" }}>
          {sortedTransfers.length === 0 ?
          <div style={{ padding: "28px 16px" }}><EmptyState icon="landmark" title="No transfers in this window" message="Try a wider date range." /></div> :

          sortedTransfers.map((t) => <TransferRow key={t.id} t={t} />)
          }
        </div>
      </Card>
    </div>);

}

function WalletOpsPage({ ledger, customers, onOpenAdjustWallet, onRetryCharge, onOpenCustomer }) {
  const [tab, setTab] = React.useState("overview");
  const failedCount = ledger.filter((r) => r.status === "failed").length;
  React.useEffect(refresh, [tab]);

  return (
    <div style={{ padding: 24, width: "100%", maxWidth: "var(--page-max)" }}>
      <PageHeader eyebrow="Financial Operations" title="Wallet & Billing" description="Company-wide financial summary, the Strata ledger across every account, and failed payments that need a retry or manual credit." actions={
      <CustomerPicker customers={customers} onPick={(id) => onOpenAdjustWallet({ customerId: id })} />
      } />

      <div style={{ marginBottom: 18 }}>
        <Tabs value={tab} onChange={setTab} tabs={[{ value: "overview", label: "Overview" }, { value: "ledger", label: "Ledger" }, { value: "failed", label: "Failed Payments", count: failedCount }]} />
      </div>

      {tab === "overview" && <FinanceOverviewTab customers={customers} ledger={ledger} />}
      {tab === "ledger" && <LedgerTab ledger={ledger} onOpenCustomer={onOpenCustomer} />}
      {tab === "failed" && <FailedPaymentsTab ledger={ledger} onRetryCharge={onRetryCharge} onOpenAdjustWallet={onOpenAdjustWallet} onOpenCustomer={onOpenCustomer} />}
    </div>);

}

Object.assign(window, { OpsWalletOps: { WalletOpsPage } });
