/* Customers — the companies on the other side of the money.

   Commit model: INSTANT on the list and the record (putting an account on hold
   or resuming it applies immediately and raises an undo toast; closing one is
   irreversible and opens a confirm dialog). /customers/new is its own route and
   is STAGED, because a customer is more than three fields.

   Data state: populated on both. The list's no-results branch is the filter's,
   and its action clears the filter rather than offering a new customer.

   Every figure here is a sum over the array it names in metrics.js: a
   customer's volume is their succeeded payments, what is held back is their own
   open disputes, and neither is stored on the customer record. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter, CardAction,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell,
    Button, Badge, Select, Alert, AlertTitle, AlertDescription,
    Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
    Field, FieldLabel, FieldDescription, FieldError, Input, RadioGroup, Separator, Avatar,
  } = window.OriginDesignSystem_7c998b;

  const ownerOf = (data, customer) => data.members.find((m) => m.id === customer.ownerId) || { id: null, name: "Unassigned", avatar: null, role: "" };

  /* ── The list ─────────────────────────────────────────────────────────── */

  function CustomersScreen({ data, now, onNavigate, onCustomerTransition }) {
    const [query, setQuery] = React.useState("");
    const [status, setStatus] = React.useState("all");
    const customers = customersByVolume(data.customers, data.payments);

    /* Scope-free: the text filter and the status filter narrow the list only
       (AGENTS §5.3), so the figures above read the whole customer array and the
       footer states what the table is showing. */
    const live = customers.filter((c) => c.status === "live");
    const notTrading = customers.filter((c) => c.status === "on_hold" || c.status === "suspended");
    const withDispute = customers.filter((c) => CUSTOMER_FLAGS.hasOpenDispute(c, data.disputes));
    const reserved = withDispute.reduce((total, c) => total + customerReserved(data.disputes, c), 0);

    const shown = customers.filter((c) => {
      const q = query.trim().toLowerCase();
      if (status !== "all" && c.status !== status) return false;
      if (!q) return true;
      return (c.name + " " + c.contact.name + " " + c.contact.email + " " + c.country).toLowerCase().indexOf(q) > -1;
    });
    const dirty = query.trim() !== "" || status !== "all";

    return (
      <div className="fd-page">
        <PageHeader
          path="/customers"
          title="Customers"
          actions={<span className="fd-actions__row"><ExportMenu scope="All customers" onExport={() => {}} /><Button size="sm" onClick={() => onNavigate("/customers/new")}><Icon name="plus" />New customer</Button></span>}
        />

        <div className="fd-metrics">
          <MetricTile icon="building-2" label="Customers" value={formatCount(customers.length)} qualifier={live.length + " live, " + notTrading.length + " on hold or suspended, " + customers.filter((c) => c.status === "closed").length + " closed"} />
          <MetricTile icon="trending-up" label="Volume, all time" value={formatMoney(customers.reduce((t, c) => t + customerVolume(data.payments, c), 0))} qualifier={succeededPayments(data.payments).length + " succeeded payments across every account"} />
          <MetricTile icon="shield-alert" label="Held back against disputes" value={formatMoney(reserved)} qualifier={withDispute.length ? withDispute.length + " " + (withDispute.length === 1 ? "account has" : "accounts have") + " an open dispute" : "No account has an open dispute"} />
          <MetricTile icon="moon" label="Dormant" value={formatCount(customers.filter((c) => CUSTOMER_FLAGS.isDormant(c, data.payments, now)).length)} qualifier="Nothing has arrived from them in 45 days" />
        </div>

        <Card>
          <CardHeader>
            <CardTitle>Every account</CardTitle>
            <CardDescription>Ordered by what they have brought in, not by name.</CardDescription>
          </CardHeader>
          <CardPanel>
            <FilterBar
              query={query}
              onQuery={setQuery}
              placeholder="Search customers, contacts…"
              dirty={dirty}
              onClear={() => { setQuery(""); setStatus("all"); }}
              selects={[{
                id: "status",
                label: "Status",
                value: status,
                onChange: setStatus,
                items: [{ value: "all", label: "All statuses (" + CUSTOMER_STATUS.length + ")" }].concat(CUSTOMER_STATUS.map((s) => ({ value: s.id, label: s.label }))),
              }]}
            />
          </CardPanel>
          {shown.length ? (
            <div className="fd-card-table">
              <Table variant="card">
                <TableHeader>
                  <TableRow>
                    <TableHead>Customer</TableHead>
                    <TableHead className="fd-drop-md">Owner</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead className="fd-num">Volume</TableHead>
                    <TableHead className="fd-num fd-drop-lg">Last payment</TableHead>
                    <TableHead className="fd-actions-head">Action</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {shown.map((customer) => {
                    const owner = ownerOf(data, customer);
                    const last = customerLastPaymentAt(data.payments, customer);
                    const closed = customer.status === "closed";
                    return (
                      <TableRow key={customer.id} className={closed ? "fd-row--recessed" : ""}>
                        <TableCell>
                          <span className="fd-record">
                            <button type="button" className="fd-link fd-record__name" onClick={() => onNavigate(recordRoute({ type: "customer", id: customer.id }))}>{customer.name}</button>
                            <span className="fd-record__meta">{customer.contact.name} · {customer.country}</span>
                          </span>
                        </TableCell>
                        <TableCell className="fd-drop-md">
                          <span className="fd-holder"><Face person={owner} size={24} />{owner.name}</span>
                        </TableCell>
                        <TableCell>
                          <span className="fd-status">
                            <StatusBadge values={CUSTOMER_STATUS} value={customer.status} />
                            {CUSTOMER_FLAGS.hasOpenDispute(customer, data.disputes) ? <Badge size="sm" variant="warning">Open dispute</Badge> : null}
                          </span>
                        </TableCell>
                        <TableCell className="fd-num fd-amount">{formatMoney(customerVolume(data.payments, customer))}</TableCell>
                        <TableCell className="fd-num fd-muted fd-drop-lg" title={last ? formatAbsolute(last) : undefined}>{last ? formatWhen(last, now) : "Never"}</TableCell>
                        <TableCell className="fd-actions">
                          <RowActions transitions={customerTransitions(customer)} onRun={(t) => onCustomerTransition(customer, t)} label={"Actions for " + customer.name} />
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </div>
          ) : (
            <CardPanel>
              <Empty>
                <EmptyHeader>
                  <EmptyMedia variant="icon"><Icon name="building-2" size={18} /></EmptyMedia>
                  <EmptyTitle>No account matches this filter</EmptyTitle>
                  <EmptyDescription>{customers.length} customers are on the desk; none of them match what you have narrowed to.</EmptyDescription>
                </EmptyHeader>
                <EmptyContent>
                  <Button onClick={() => { setQuery(""); setStatus("all"); }}>Clear filters</Button>
                </EmptyContent>
              </Empty>
            </CardPanel>
          )}
          <CardFooter className="fd-card-footer">
            <span className="fd-footnote">Showing {shown.length} of {customers.length} customers. A closed account is recessed: nothing can move to or from it.</span>
          </CardFooter>
        </Card>
      </div>
    );
  }

  /* ── One account ──────────────────────────────────────────────────────── */

  function CustomerScreen({ data, now, customerId, onNavigate, onCustomerTransition, onPaymentTransition, onPostComment }) {
    const customer = customerById(data.customers, customerId);
    const owner = ownerOf(data, customer);
    const payments = paymentsFor(data.payments, customer).slice().sort((a, b) => b.createdAt - a.createdAt);
    const payouts = payoutsFor(data.payouts, customer).slice().sort((a, b) => b.requestedAt - a.requestedAt);
    const disputes = disputesFor(data.disputes, customer);
    const open = openDisputes(disputes);
    const volume = customerVolume(data.payments, customer);
    const last = customerLastPaymentAt(data.payments, customer);

    return (
      <div className="fd-page">
        <PageHeader
          path="/customers/:id"
          params={{ id: customer.id }}
          title={customer.name}
          actions={<Transitions transitions={customerTransitions(customer)} onRun={(t) => onCustomerTransition(customer, t)} size="default" />}
        />

        {customer.status === "on_hold" ? (
          <Alert variant="warning">
            <AlertTitle>Payouts are paused on this account</AlertTitle>
            <AlertDescription>
              {open.length
                ? "We paused them ourselves while " + open.length + " " + (open.length === 1 ? "dispute runs" : "disputes run") + " — " + formatMoney(customerReserved(data.disputes, customer)) + " is held back against the balance. Money still arrives from them; nothing leaves."
                : "We paused them ourselves. Money still arrives from them; nothing leaves until somebody resumes it."}
            </AlertDescription>
          </Alert>
        ) : customer.status === "suspended" ? (
          <Alert variant="error">
            <AlertTitle>Suspended by risk</AlertTitle>
            <AlertDescription>Nothing moves to or from this account. The last payout came back from their bank, and new details have to be confirmed in writing before it can be resumed.</AlertDescription>
          </Alert>
        ) : customer.status === "closed" ? (
          <Alert variant="info">
            <AlertTitle>Closed account</AlertTitle>
            <AlertDescription>The records below are kept for the ledger. Nothing more can be taken or sent, and a closed account cannot be reopened — a new one has to be onboarded.</AlertDescription>
          </Alert>
        ) : null}

        <div className="fd-metrics">
          <MetricTile icon="trending-up" label="Volume, all time" value={formatMoney(volume)} qualifier={succeededPayments(payments).length + " succeeded of " + payments.length + " payments taken from them"} />
          <MetricTile icon="arrow-up-right" label="Paid out to them" value={formatMoney(customerPaidOut(data.payouts, customer))} qualifier={payouts.filter((p) => p.status === "paid").length + " of " + payouts.length + " payouts have landed"} />
          <MetricTile icon="shield-alert" label="Held back" value={formatMoney(customerReserved(data.disputes, customer))} qualifier={open.length ? open.length + " open " + (open.length === 1 ? "dispute" : "disputes") + " of " + disputes.length + " ever" : "Nothing of theirs is disputed"} />
          <MetricTile icon="clock" label="Last payment" value={last ? formatWhen(last, now) : "Never"} qualifier={CUSTOMER_FLAGS.isDormant(customer, data.payments, now) ? "Dormant — nothing in 45 days" : "Trading normally"} />
        </div>

        <div className="fd-columns">
          <div className="fd-col">
            <Card>
              <CardHeader>
                <CardTitle>Payments from {customer.name}</CardTitle>
                <CardDescription>{formatMoney(volume)} of it succeeded. Newest first.</CardDescription>
              </CardHeader>
              {payments.length ? (
                <div className="fd-card-table">
                  <Table variant="card">
                    <TableHeader>
                      <TableRow>
                        <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">Taken</TableHead>
                        <TableHead className="fd-actions-head">Action</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {payments.map((payment) => (
                        <TableRow key={payment.id}>
                          <TableCell><code>{payment.id}</code>{payment.failureReason ? <span className="fd-sub">{payment.failureReason}</span> : null}</TableCell>
                          <TableCell className="fd-drop-md fd-muted">{labelOf(PAYMENT_METHODS, payment.method)}</TableCell>
                          <TableCell><StatusBadge values={PAYMENT_STATUS} value={payment.status} /></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>
              ) : (
                <CardPanel><span className="fd-footnote">Nothing has been taken from this account yet.</span></CardPanel>
              )}
              <CardFooter className="fd-card-footer">
                <span className="fd-footnote">{payments.length} payments, {succeededPayments(payments).length} of them succeeded.</span>
                <Button variant="ghost" size="sm" onClick={() => onNavigate("/payments")}>All payments<Icon name="arrow-right" /></Button>
              </CardFooter>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>Payouts to their bank</CardTitle>
                <CardDescription>{customer.payoutAccount ? "Landing in " + customer.payoutAccount + "." : "No bank account on file, so nothing can be sent yet."}</CardDescription>
              </CardHeader>
              {payouts.length ? (
                <div className="fd-card-table">
                  <Table variant="card">
                    <TableHeader>
                      <TableRow>
                        <TableHead>Payout</TableHead>
                        <TableHead>Status</TableHead>
                        <TableHead className="fd-num">Amount</TableHead>
                        <TableHead className="fd-num fd-drop-md">Requested</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {payouts.map((payout) => (
                        <TableRow key={payout.id} className={PAYOUT_FLAGS.isApprovable(payout, data.approver) ? "" : "fd-row--recessed"}>
                          <TableCell><code>{payout.id}</code>{payout.blockedBy ? <span className="fd-sub">Held by {payout.blockedBy.team} — {payout.blockedBy.reason}</span> : null}</TableCell>
                          <TableCell><StatusBadge values={PAYOUT_STATUS} value={payout.status} /></TableCell>
                          <TableCell className="fd-num fd-amount">{formatMoney(payout.amount)}</TableCell>
                          <TableCell className="fd-num fd-muted fd-drop-md" title={formatAbsolute(payout.requestedAt)}>{formatWhen(payout.requestedAt, now)}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </div>
              ) : (
                <CardPanel><span className="fd-footnote">Nothing has been sent to this account.</span></CardPanel>
              )}
              <CardFooter className="fd-card-footer">
                <span className="fd-footnote">{payouts.length} payouts · approving and rejecting them happens on the payouts queue.</span>
                <Button variant="ghost" size="sm" onClick={() => onNavigate("/payouts")}>Payout queue<Icon name="arrow-right" /></Button>
              </CardFooter>
            </Card>
          </div>

          <div className="fd-col">
            <Card className="fd-card">
              <CardHeader>
                <CardTitle>The account</CardTitle>
                <CardDescription>Onboarded {formatDay(customer.since)}.</CardDescription>
                <CardAction><StatusBadge values={CUSTOMER_STATUS} value={customer.status} /></CardAction>
              </CardHeader>
              <CardPanel className="fd-stack">
                <span className="fd-holder">
                  <Face person={owner} size={32} />
                  <span className="fd-record">
                    <span className="fd-record__name">{owner.name}</span>
                    <span className="fd-record__meta">Owns this account · {owner.role}</span>
                  </span>
                </span>
                <dl className="fd-defs">
                  <div><dt>Contact</dt><dd>{customer.contact.name}</dd></div>
                  <div><dt>Email</dt><dd>{customer.contact.email}</dd></div>
                  <div><dt>Country</dt><dd>{customer.country}</dd></div>
                  <div><dt>Settlement currency</dt><dd>{customer.currency}</dd></div>
                  <div><dt>Payout account</dt><dd>{customer.payoutAccount ? <span className="fd-pan">{customer.payoutAccount}</span> : "None on file"}</dd></div>
                  <div className="fd-defs__total"><dt>Volume, all time</dt><dd>{formatMoney(volume)}</dd></div>
                </dl>
              </CardPanel>
              <CardFooter className="fd-card-footer">
                <Button variant="outline" size="sm" onClick={() => onNavigate(recordRoute({ type: "member", id: owner.id }))}>Open {owner.name.split(" ")[0]}'s page<Icon name="arrow-right" /></Button>
              </CardFooter>
            </Card>

            {disputes.length ? (
              <Card className="fd-card">
                <CardHeader>
                  <CardTitle>Disputes</CardTitle>
                  <CardDescription>{formatMoney(customerReserved(data.disputes, customer))} of theirs is held back against the {open.length} still open.</CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="fd-picklist">
                    {disputes.map((dispute) => (
                      <button type="button" className="fd-pick" key={dispute.id} onClick={() => onNavigate(recordRoute({ type: "dispute", id: dispute.id }))}>
                        <span className="fd-list__main">
                          <span className="fd-record__name">{dispute.reason}</span>
                          <span className="fd-record__meta"><code>{dispute.id}</code></span>
                        </span>
                        <span className="fd-list__side">
                          <span className="fd-amount">{formatMoney(dispute.amount)}</span>
                          <span className="fd-clock">{dispute.evidenceDueAt ? formatCountdown(dispute.evidenceDueAt, now) : "With the network"}</span>
                        </span>
                        <span className="fd-pick__foot"><StatusBadge values={DISPUTE_STATUS} value={dispute.status} /></span>
                      </button>
                    ))}
                  </div>
                </CardPanel>
              </Card>
            ) : null}

            <ThreadCard
              record={{ type: "customer", id: customer.id }}
              data={data}
              signedInId={MERIDIAN_SIGNED_IN}
              now={now}
              onPost={onPostComment}
              description={"What the desk knows about " + customer.name + " that the records do not say. Mention somebody to put it in their queue."}
            />
          </div>
        </div>
      </div>
    );
  }

  /* ── Onboarding one ───────────────────────────────────────────────────── */

  function NewCustomerScreen({ data, onCreate, onNavigate }) {
    const blank = { name: "", contactName: "", contactEmail: "", country: "United States", ownerId: MERIDIAN_SIGNED_IN, payoutAccount: "" };
    const [draft, setDraft] = React.useState(blank);
    const [submitted, setSubmitted] = React.useState(false);
    const set = (fields) => setDraft((d) => Object.assign({}, d, fields));
    const dirty = JSON.stringify(draft) !== JSON.stringify(blank);
    const errors = {};
    if (draft.name.trim().length < 3) errors.name = "Enter the company's name — at least three characters.";
    if (data.customers.some((c) => c.name.toLowerCase() === draft.name.trim().toLowerCase())) errors.name = "That account already exists on the desk.";
    if (!draft.contactName.trim()) errors.contactName = "Somebody there has to own the relationship.";
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(draft.contactEmail)) errors.contactEmail = "Enter a valid email address.";
    if (draft.payoutAccount && !/^\d{4}$/.test(draft.payoutAccount.trim())) errors.payoutAccount = "The last four digits, or leave it empty.";
    const valid = Object.keys(errors).length === 0;
    const owner = data.members.find((m) => m.id === draft.ownerId);

    return (
      <div className="fd-page">
        <PageHeader path="/customers/new" title="New customer" />
        <div className="fd-columns">
          <div className="fd-col">
            <Card>
              <CardHeader>
                <CardTitle>Onboard an account</CardTitle>
                <CardDescription>They can be charged as soon as this is saved. A bank account is only needed before the first payout.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="fd-fields">
                  <Field>
                    <FieldLabel htmlFor="fd-cus-name">Company name</FieldLabel>
                    <Input id="fd-cus-name" value={draft.name} placeholder="Harborview Freight" invalid={submitted && !!errors.name} onChange={(e) => set({ name: e.target.value })} />
                    {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : <FieldDescription>Exactly as it should read on their statement and on every payout.</FieldDescription>}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="fd-cus-contact">Contact</FieldLabel>
                    <Input id="fd-cus-contact" value={draft.contactName} placeholder="Ruth Callan" invalid={submitted && !!errors.contactName} onChange={(e) => set({ contactName: e.target.value })} />
                    {submitted && errors.contactName ? <FieldError>{errors.contactName}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="fd-cus-email">Contact email</FieldLabel>
                    <Input id="fd-cus-email" type="email" value={draft.contactEmail} placeholder="ruth@harborview.example" invalid={submitted && !!errors.contactEmail} onChange={(e) => set({ contactEmail: e.target.value })} />
                    {submitted && errors.contactEmail ? <FieldError>{errors.contactEmail}</FieldError> : <FieldDescription>Where disputes and payout notices are sent.</FieldDescription>}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="fd-cus-country">Country</FieldLabel>
                    <Input id="fd-cus-country" value={draft.country} onChange={(e) => set({ country: e.target.value })} />
                    <FieldDescription>Settlement is in {MERIDIAN_WORKSPACE.name}'s currency either way.</FieldDescription>
                  </Field>
                  <Field>
                    <FieldLabel>Who owns the account</FieldLabel>
                    <RadioGroup name="fd-cus-owner" value={draft.ownerId} onValueChange={(id) => set({ ownerId: id })}
                      items={data.members.map((m) => ({ value: m.id, label: m.name + " — " + m.role }))} />
                    <FieldDescription>Their name is on every note and every payout decision for this account.</FieldDescription>
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="fd-cus-account">Payout account, last four digits</FieldLabel>
                    <Input id="fd-cus-account" inputMode="numeric" value={draft.payoutAccount} placeholder="4417" invalid={submitted && !!errors.payoutAccount} onChange={(e) => set({ payoutAccount: e.target.value })} />
                    {submitted && errors.payoutAccount ? <FieldError>{errors.payoutAccount}</FieldError> : <FieldDescription>Optional. Without it, no payout can be raised to them.</FieldDescription>}
                  </Field>
                </div>
              </CardPanel>
            </Card>
          </div>

          <div className="fd-col">
            <Card className="fd-card">
              <CardHeader>
                <CardTitle>What this creates</CardTitle>
                <CardDescription>Read from the form as you fill it in.</CardDescription>
              </CardHeader>
              <CardPanel className="fd-stack">
                <span className="fd-holder">
                  <Face person={owner} size={32} />
                  <span className="fd-record">
                    <span className="fd-record__name">{draft.name.trim() || "A new account"}</span>
                    <span className="fd-record__meta">Owned by {owner.name} · {draft.country || "no country yet"}</span>
                  </span>
                </span>
                <Separator />
                <dl className="fd-defs">
                  <div><dt>Status on save</dt><dd><StatusBadge values={CUSTOMER_STATUS} value="live" /></dd></div>
                  <div><dt>Can be charged</dt><dd>Straight away</dd></div>
                  <div><dt>Can be paid out</dt><dd>{draft.payoutAccount.trim() ? "Yes, into •••• " + draft.payoutAccount.trim() : "Not until a bank account is added"}</dd></div>
                  <div className="fd-defs__total"><dt>Accounts on the desk</dt><dd>{data.customers.length} → {data.customers.length + 1}</dd></div>
                </dl>
              </CardPanel>
            </Card>
          </div>
        </div>

        <FormBar
          dirty={dirty}
          note={dirty ? "Nothing exists until this is saved." : "Fill the form in and the account is created on save."}
          onCancel={() => { setDraft(blank); setSubmitted(false); onNavigate("/customers"); }}
          onSave={() => { setSubmitted(true); if (valid) onCreate(draft); }}
          label="New customer"
        />
      </div>
    );
  }

  Object.assign(window, { CustomersScreen, CustomerScreen, NewCustomerScreen });
})();
