/* Payments — the money coming in.
   Commit model: INSTANT. Capture and retry apply and raise an undo toast;
   refund is irreversible and opens a confirm dialog.
   Data state: one branch — populated, or the no-results branch when the filters
   match nothing. The tabs and the filters narrow the list only; there are no
   figures above them to move.
   List architecture, as every list screen in this product has it: filter bar,
   bulk action bar, table, stated count. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell,
    Tabs, TabsList, TabsTab, Checkbox, Button, Badge,
    Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
  } = window.OriginDesignSystem_7c998b;

  function PaymentsScreen({ data, now, onNavigate, onPaymentTransition, pushToast }) {
    const [query, setQuery] = React.useState("");
    const [method, setMethod] = React.useState("all");
    const [status, setStatus] = React.useState("all");
    const [tab, setTab] = React.useState("all");
    const [selected, setSelected] = React.useState([]);
    /* One fixed window for the chart, stated in words: this screen has no scope
       control, so the chart is not moved by the filters below it (§5.3). */
    const CHART_DAYS = 30;
    const chartPayments = paymentsInPeriod(data.payments, CHART_DAYS, now);
    const chartBuckets = volumeByDay(chartPayments, now, CHART_DAYS);

    const attention = data.payments.filter((p) => PAYMENT_FLAGS.needsAttention(p, data.disputes));
    const scoped = tab === "attention" ? attention : data.payments;
    const filtered = scoped.filter((p) => {
      if (query && (p.id + " " + p.customer).toLowerCase().indexOf(query.toLowerCase()) === -1) return false;
      if (method !== "all" && p.method !== method) return false;
      if (status !== "all" && p.status !== status) return false;
      return true;
    });
    const dirty = query !== "" || method !== "all" || status !== "all";
    const clear = () => { setQuery(""); setMethod("all"); setStatus("all"); };
    const toggle = (id) => setSelected((l) => (l.indexOf(id) > -1 ? l.filter((x) => x !== id) : l.concat([id])));
    const allPicked = filtered.length > 0 && filtered.every((p) => selected.indexOf(p.id) > -1);
    const picked = data.payments.filter((p) => selected.indexOf(p.id) > -1);

    return (
      <div className="fd-page">
        <PageHeader path="/payments" title="Payments" actions={<span className="fd-actions__row"><ExportMenu scope={"All " + data.payments.length + " payments"} onExport={(format) => pushToast({ title: "Export started", description: data.payments.length + " payments · " + format })} /><Button size="sm" onClick={() => onNavigate("/payments/new")}><Icon name="plus" />New payment</Button></span>} />

        <Card className="fd-card">
          <CardHeader>
            <CardTitle>Net volume by day</CardTitle>
            <CardDescription>{formatMoney(netVolume(chartPayments))} across the last {CHART_DAYS} days — every payment in the workspace, not the filtered rows below.</CardDescription>
          </CardHeader>
          <CardPanel>
            <DayChart
              buckets={chartBuckets}
              series={[{ key: "amount", label: "Net volume", rows: [{ key: "rows", noun: "payment" }] }]}
              format={formatMoney}
              label="Net volume a day"
              note={settledAttempts(chartPayments).length + " payments with an outcome in the window; " + failedPayments(chartPayments).length + " failed and sit outside every bar."}
            />
          </CardPanel>
        </Card>

        <FilterBar
          query={query} onQuery={setQuery} placeholder="Search by payment or customer" dirty={dirty} onClear={clear}
          selects={[
            { id: "method", label: "Method", value: method, onChange: setMethod, items: [{ value: "all", label: "Every method" }].concat(PAYMENT_METHODS.map((m) => ({ value: m.value, label: m.label }))) },
            { id: "status", label: "Status", value: status, onChange: setStatus, items: [{ value: "all", label: "Every status" }].concat(PAYMENT_STATUS.map((s) => ({ value: s.id, label: s.label }))) },
          ]}
        />

        <BulkBar
          count={picked.length}
          note={formatMoney(sumBy(picked, "amount")) + " across the selection."}
          onClear={() => setSelected([])}
        >
          <Button variant="outline" size="sm" onClick={() => { pushToast({ title: "Export started", description: picked.length + " payments · CSV — we'll email it to " + MERIDIAN_USER.name.split(" ")[0].toLowerCase() + "@northwind.example" }); setSelected([]); }}>Export selected</Button>
        </BulkBar>

        <Card>
          <CardHeader>
            <CardTitle>Every payment</CardTitle>
            <CardDescription>Newest first. The action column carries the one transition the payment's status allows.</CardDescription>
          </CardHeader>
          <div className="fd-card-tabs">
            <Tabs value={tab} onValueChange={(next) => { setTab(next); setSelected([]); }}>
              <TabsList variant="underline">
                <TabsTab value="all">All<span className="fd-tab-count">{data.payments.length}</span></TabsTab>
                <TabsTab value="attention">Needs attention<span className="fd-tab-count">{attention.length}</span></TabsTab>
              </TabsList>
            </Tabs>
          </div>
          {filtered.length === 0 ? (
            <CardPanel>
              <Empty>
                <EmptyHeader>
                  <EmptyMedia variant="icon"><Icon name="search-x" size={18} /></EmptyMedia>
                  <EmptyTitle>No payments match those filters</EmptyTitle>
                  <EmptyDescription>Nothing in {tab === "attention" ? "the failed-or-disputed list" : "this workspace"} matches. Widen the filters and try again.</EmptyDescription>
                </EmptyHeader>
                <EmptyContent><Button onClick={clear}>Clear filters</Button></EmptyContent>
              </Empty>
            </CardPanel>
          ) : (
            <div className="fd-card-table">
              <Table variant="card">
                <TableHeader>
                  <TableRow>
                    <TableHead style={{ width: "2.5rem" }}>
                      <Checkbox checked={allPicked} indeterminate={!allPicked && filtered.some((p) => selected.indexOf(p.id) > -1)}
                        aria-label="Select every payment shown" onCheckedChange={(checked) => setSelected(checked ? filtered.map((p) => p.id) : [])} />
                    </TableHead>
                    <TableHead>Payment</TableHead>
                    <TableHead className="fd-drop-md">Method</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead className="fd-num">Amount</TableHead>
                    <TableHead className="fd-num fd-drop-lg">Created</TableHead>
                    <TableHead className="fd-actions-head">Action</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {filtered.map((payment) => {
                    const dispute = data.disputes.find((d) => d.paymentId === payment.id && DISPUTE_FLAGS.isOpen(d));
                    return (
                      <TableRow key={payment.id}>
                        <TableCell><Checkbox checked={selected.indexOf(payment.id) > -1} aria-label={"Select " + payment.id} onCheckedChange={() => toggle(payment.id)} /></TableCell>
                        <TableCell>
                          <span className="fd-record">
                            <span className="fd-record__name">{payment.customer}</span>
                            <span className="fd-record__meta"><code>{payment.id}</code></span>
                          </span>
                        </TableCell>
                        <TableCell className="fd-drop-md">{labelOf(PAYMENT_METHODS, payment.method)}</TableCell>
                        <TableCell>
                          <span className="fd-status">
                            <StatusBadge values={PAYMENT_STATUS} value={payment.status} />
                            {dispute ? <button type="button" className="fd-link" onClick={() => onNavigate("/disputes/" + dispute.id)}><Badge size="sm" variant="warning">Disputed</Badge></button> : null}
                          </span>
                          {payment.failureReason ? <span className="fd-sub">{payment.failureReason}</span> : null}
                        </TableCell>
                        <TableCell className="fd-num fd-amount">{formatMoney(payment.amount)}</TableCell>
                        <TableCell className="fd-num fd-muted fd-drop-lg" title={formatAbsolute(payment.createdAt)}>{formatWhen(payment.createdAt, now)}</TableCell>
                        <TableCell className="fd-actions">
                          <RowActions transitions={paymentTransitions(payment)} onRun={(t) => onPaymentTransition(payment, t)} label={"Actions for " + payment.id} />
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </div>
          )}
          <CardFooter className="fd-card-footer">
            <span className="fd-footnote">Showing {filtered.length} of {data.payments.length} payments{tab === "attention" ? ", from the " + attention.length + " that failed or are disputed" : ""}.</span>
            <span className="fd-footnote">{formatMoney(netVolume(filtered))} net across the rows shown.</span>
          </CardFooter>
        </Card>
      </div>
    );
  }

  Object.assign(window, { PaymentsScreen });
})();
