// Transactions register — Task 2 of
// docs/superpowers/plans/2026-08-02-switch-from-anywhere.md (spec Part A of
// docs/superpowers/specs/2026-08-02-switch-from-anywhere-design.md).
//
// One screen, two modes, driven by GET /api/c/register (server/src/register.ts):
//   - All activity (default): one row per posted entry, newest first.
//   - Account register (an account is picked): that account's lines, signed
//     in the account's natural direction, plus the running Balance column the
//     API computes at query time (never stored — CLAUDE.md §3.4).
//
// Everything is server-side: every filter change refetches page 1; "Load
// more" walks the API's keyset cursor (stable across identical dates, so no
// dupes/skips between pages). Text-ish filters (search, amounts) debounce
// briefly so typing doesn't fire a request per keystroke.
//
// §9: no debit/credit language anywhere by default. The ONE sanctioned
// accountant garnish is the "Show debits and credits" toggle, OFF by default,
// visible only in account-register mode, persisted per session
// (sessionStorage — same best-effort pattern as EntryDetail's banner flag).
//
// Row click drills to the SAME entry detail reports use (#/entry/:id). Rows
// that came from a document additionally offer "Open invoice/bill/payment"
// via the API's sourceLink, wired to the existing #invoice/:id-style routes.
// (statement-line sourceLinks get no extra link: the workbench route needs a
// statement id, not a line id — the entry drill-through still works.)

import { useEffect, useMemo, useRef, useState } from "react";
import { useCompany } from "../lib/company";
import { useApiGet } from "../lib/useApiGet";
import { apiGet, ApiError } from "../lib/api";
import { fmtDate, yearRange } from "../lib/date";
import { fmtMoney } from "../lib/money";
import { ErrorBanner } from "../components/ErrorBanner";
import { SearchablePicker, type PickerGroup } from "../components/SearchablePicker";
import type { ApiAccount } from "../accounts/subtypes";
import { accountPickerGroups } from "../accounts/pickerGroups";
import type { NavTarget } from "../lib/useHashView";

// ---------------------------------------------------------------------------
// API shapes (server/src/register.ts)
// ---------------------------------------------------------------------------

interface SourceLink {
  kind: "invoice" | "payment" | "bill" | "bill-payment" | "statement-line";
  id: string;
}

interface AllRow {
  id: string;
  date: string;
  entryNo: string;
  type: string;
  typeLabel: string;
  /** Customer / vendor / payee — the "Name" half of the Name/Memo column. */
  name: string | null;
  memo: string | null;
  ref: string | null;
  amount: string;
  status: string;
  sourceLink?: SourceLink;
}

interface AccountRow {
  entryId: string;
  date: string;
  entryNo: string;
  type: string;
  typeLabel: string;
  name: string | null;
  memo: string | null;
  ref: string | null;
  amount: string;
  debit?: string;
  credit?: string;
  runningBalance: string;
  status: string;
  sourceLink?: SourceLink;
}

interface RegisterAccount {
  id: string;
  name: string;
  type: string;
  debitNormal: boolean;
}

interface RegisterResponse {
  mode: "all" | "account";
  account?: RegisterAccount;
  rows: (AllRow & Partial<AccountRow>)[];
  nextCursor: string | null;
}

// ---------------------------------------------------------------------------
// filter plumbing
// ---------------------------------------------------------------------------

/** Sentinel id for the picker's "All activity" option — never a real account
 * id (those are numeric strings), so it can't collide with one. */
const ALL_ACTIVITY = "__all_activity__";

/** Plain-English type filter options, mirroring the API's TYPE_LABELS. */
const TYPE_OPTIONS: { key: string; label: string }[] = [
  { key: "invoice", label: "Invoice" },
  { key: "payment", label: "Payment received" },
  { key: "bill", label: "Bill" },
  { key: "bill-payment", label: "Bill payment" },
  { key: "check", label: "Check" },
  { key: "bank", label: "Bank entry" },
  { key: "manual", label: "Manual entry" },
  { key: "reversal", label: "Reversal" },
  { key: "intercompany", label: "Intercompany" },
  { key: "imported", label: "Imported history" },
  { key: "entry", label: "Entry" },
];

const OPEN_LINK: Partial<Record<SourceLink["kind"], { label: string; view: "invoice" | "payment" | "bill" | "bill-payment" }>> = {
  invoice: { label: "Open invoice", view: "invoice" },
  payment: { label: "Open payment", view: "payment" },
  bill: { label: "Open bill", view: "bill" },
  "bill-payment": { label: "Open bill payment", view: "bill-payment" },
};

type Preset = "this-year" | "last-year" | "all-time" | "custom";

/** The server's own amount shape (register.ts optionalMoney) — validated
 * CLIENT-side before any fetch, so a half-typed filter never replaces the
 * table with a raw validation error; the server 400 stays as the backstop. */
const AMOUNT_RE = /^\d{1,15}(\.\d{1,4})?$/;
const AMOUNT_HINT = "Enter an amount like 125.00";

/** "$1,234.50" typed by a human -> "1234.50" for the API. Pure string
 * cleanup, no arithmetic: strips $/commas/spaces, drops a leading "-" (the
 * amount filter matches magnitudes — sign has no meaning here), and fills
 * in the shorthand people actually type (".5" -> "0.5", "125." -> "125"). */
function cleanAmount(s: string): string {
  let v = s.trim().replace(/[$,\s]/g, "");
  if (v.startsWith("-")) v = v.slice(1);
  if (v.startsWith(".")) v = `0${v}`;
  if (v.endsWith(".")) v = v.slice(0, -1);
  return v;
}

const DRCR_KEY = "register-show-drcr";

/** Best-effort sessionStorage read/write — never fatal if storage is
 * unavailable (private browsing); worst case the toggle just doesn't
 * persist, same pattern as EntryDetail's just-reversed flag. */
function readDrCr(): boolean {
  try {
    return window.sessionStorage.getItem(DRCR_KEY) === "1";
  } catch {
    return false;
  }
}

function writeDrCr(on: boolean): void {
  try {
    if (on) window.sessionStorage.setItem(DRCR_KEY, "1");
    else window.sessionStorage.removeItem(DRCR_KEY);
  } catch {
    // best-effort only
  }
}

/** "All activity" plus every active account under the STANDARD sections
 * (Chart Management Task 3): Bank accounts / Credit cards / Lines of credit
 * / Accounts receivable / ... — Chase Ink is findable as a credit card, not
 * filed under "Other". */
function accountGroups(accounts: ApiAccount[] | null): PickerGroup[] {
  const view: PickerGroup = { label: "View", options: [{ id: ALL_ACTIVITY, label: "All activity" }] };
  return [view, ...accountPickerGroups(accounts)];
}

// ---------------------------------------------------------------------------
// component
// ---------------------------------------------------------------------------

export function RegisterScreen({
  navigate,
  onSelectEntry,
  initialAccountId,
}: {
  navigate: (target: NavTarget) => void;
  onSelectEntry: (entryId: string) => void;
  /** Account preselect from the #/transactions/account/:id route (Chart
   * Management Task 2 — a Chart of Accounts row click lands here). Only a
   * starting point: the picker below can change it freely afterward, and the
   * bare #/transactions route just passes undefined. */
  initialAccountId?: string;
}) {
  const { selectedCompanyId } = useCompany();
  const currentYear = new Date().getFullYear(); // a calendar year label, not money

  // ----- filters -----
  const [from, setFrom] = useState("");
  const [to, setTo] = useState("");
  const [preset, setPreset] = useState<Preset>("all-time");
  const [accountId, setAccountId] = useState<string | null>(initialAccountId ?? null);

  // Clicking a DIFFERENT chart row while this screen is already mounted
  // changes only the prop (the component doesn't remount for a hash change
  // within the same view) — adopt it with the same adjust-state-during-render
  // pattern the company-change reset below uses. A transition to undefined
  // (sidebar "Transactions" click or browser Back from an account deep-link)
  // resets to all activity, matching a fresh visit to the bare route.
  // User-driven picker changes leave the prop untouched, so they are never
  // overridden.
  const [prevInitialAccountId, setPrevInitialAccountId] = useState(initialAccountId);
  if (initialAccountId !== prevInitialAccountId) {
    setPrevInitialAccountId(initialAccountId);
    setAccountId(initialAccountId ?? null);
  }
  const [typeKey, setTypeKey] = useState("");
  const [q, setQ] = useState("");
  const [amountMin, setAmountMin] = useState("");
  const [amountMax, setAmountMax] = useState("");

  // Debounced copies of the type-into-me filters so a request doesn't fire
  // per keystroke; dates/selects apply immediately via their own state.
  // Amounts are validated against the server's own shape BEFORE applying: an
  // invalid one shows a small hint under its input and simply doesn't apply
  // (no fetch, the table stays), instead of a full-width server 400.
  const [appliedQ, setAppliedQ] = useState("");
  const [appliedMin, setAppliedMin] = useState("");
  const [appliedMax, setAppliedMax] = useState("");
  const [minInvalid, setMinInvalid] = useState(false);
  const [maxInvalid, setMaxInvalid] = useState(false);
  useEffect(() => {
    const t = setTimeout(() => {
      setAppliedQ(q.trim());
      const min = cleanAmount(amountMin);
      const max = cleanAmount(amountMax);
      const minBad = min !== "" && !AMOUNT_RE.test(min);
      const maxBad = max !== "" && !AMOUNT_RE.test(max);
      setMinInvalid(minBad);
      setMaxInvalid(maxBad);
      if (!minBad) setAppliedMin(min);
      if (!maxBad) setAppliedMax(max);
    }, 350);
    return () => clearTimeout(t);
  }, [q, amountMin, amountMax]);

  const [showDrCr, setShowDrCr] = useState(readDrCr);

  // ----- CSV download state (declared early: the company-change reset and
  // the page-1 fetch effect both clear it) -----
  const [csvBusy, setCsvBusy] = useState(false);
  const [csvError, setCsvError] = useState<string | null>(null);

  // Switching company mid-register would otherwise refetch mode=account with
  // the OLD company's account id — RLS makes that look like an unknown
  // account, so the whole screen becomes a dead-end 404. Reset the picked
  // account the moment the company changes, DURING render (the React
  // adjust-state-on-prop-change pattern): render reruns with the reset state
  // before any effect can fire a fetch against the stale pairing.
  const [prevCompanyId, setPrevCompanyId] = useState(selectedCompanyId);
  if (selectedCompanyId !== prevCompanyId) {
    setPrevCompanyId(selectedCompanyId);
    setAccountId(null);
    setCsvError(null);
  }

  // Review finding 3: that reset fixes the VIEW but would leave a stale
  // #/transactions/account/:id (the OLD company's account) in the address
  // bar — an F5 or Back would then dead-end on "We couldn't find that
  // account". Replace (not push — no history entry for a URL that was never
  // valid for this company) the hash with the bare route so URL matches
  // state. Effect, not render: mutating location during render is a side
  // effect, and the hashchange it fires re-enters the router.
  const companyForHashRef = useRef(selectedCompanyId);
  useEffect(() => {
    if (companyForHashRef.current !== selectedCompanyId) {
      companyForHashRef.current = selectedCompanyId;
      if (initialAccountId !== undefined) {
        window.location.replace("#/transactions");
      }
    }
  }, [selectedCompanyId, initialAccountId]);

  // ----- account picker options -----
  const { data: accounts } = useApiGet<ApiAccount[]>("/api/c/accounts", selectedCompanyId);
  const pickerGroups = useMemo(() => accountGroups(accounts), [accounts]);

  const isAccountMode = accountId !== null;

  // ----- the query string every fetch (page 1, load-more, CSV) shares -----
  const baseQuery = useMemo(() => {
    const params = new URLSearchParams();
    if (isAccountMode) {
      params.set("mode", "account");
      params.set("accountId", accountId);
    }
    if (from) params.set("from", from);
    if (to) params.set("to", to);
    if (typeKey) params.set("type", typeKey);
    if (appliedQ) params.set("q", appliedQ);
    if (appliedMin) params.set("amountMin", appliedMin);
    if (appliedMax) params.set("amountMax", appliedMax);
    return params.toString();
  }, [isAccountMode, accountId, from, to, typeKey, appliedQ, appliedMin, appliedMax]);

  // ----- paged data (manual, not useApiGet: "Load more" accumulates) -----
  const [rows, setRows] = useState<(AllRow & Partial<AccountRow>)[]>([]);
  const [accountMeta, setAccountMeta] = useState<RegisterAccount | null>(null);
  const [nextCursor, setNextCursor] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [reloadToken, setReloadToken] = useState(0);
  // Monotonic fetch sequence: any response landing after a newer request
  // started (filters changed mid-flight, company switched) is dropped.
  const fetchSeq = useRef(0);

  useEffect(() => {
    if (!selectedCompanyId) {
      setRows([]);
      setLoading(false);
      return;
    }
    const seq = ++fetchSeq.current;
    setLoading(true);
    setError(null);
    setCsvError(null); // a stale export error shouldn't outlive the filters it described
    setRows([]);
    setAccountMeta(null);
    setNextCursor(null);
    apiGet<RegisterResponse>(`/api/c/register?${baseQuery}`, selectedCompanyId)
      .then((res) => {
        if (fetchSeq.current !== seq) return;
        setRows(res.rows);
        setAccountMeta(res.account ?? null);
        setNextCursor(res.nextCursor);
      })
      .catch((err: unknown) => {
        if (fetchSeq.current !== seq) return;
        setError(err instanceof ApiError ? err.message : "Something went wrong loading this.");
      })
      .finally(() => {
        if (fetchSeq.current === seq) setLoading(false);
      });
  }, [selectedCompanyId, baseQuery, reloadToken]);

  function loadMore() {
    if (!selectedCompanyId || !nextCursor || loadingMore) return;
    const seq = fetchSeq.current;
    setLoadingMore(true);
    apiGet<RegisterResponse>(
      `/api/c/register?${baseQuery}${baseQuery ? "&" : ""}cursor=${encodeURIComponent(nextCursor)}`,
      selectedCompanyId,
    )
      .then((res) => {
        if (fetchSeq.current !== seq) return; // filters changed while loading
        setRows((prev) => [...prev, ...res.rows]);
        setNextCursor(res.nextCursor);
      })
      .catch((err: unknown) => {
        if (fetchSeq.current !== seq) return;
        setError(err instanceof ApiError ? err.message : "Something went wrong loading this.");
      })
      .finally(() => setLoadingMore(false));
  }

  // ----- CSV download -----
  async function downloadCsv() {
    if (!selectedCompanyId || csvBusy) return;
    setCsvBusy(true);
    setCsvError(null);
    try {
      const res = await fetch(`/api/c/register.csv?${baseQuery}`, {
        headers: { "X-Company-Id": selectedCompanyId },
      });
      if (!res.ok) {
        let message = `Something went wrong talking to the server (HTTP ${res.status}).`;
        try {
          const data: unknown = await res.json();
          const err = (data as { error?: unknown } | null)?.error;
          if (typeof err === "string" && err.trim().length > 0) message = err;
        } catch {
          // non-JSON error body — keep the generic message
        }
        setCsvError(message);
        return;
      }
      const blob = await res.blob();
      const disposition = res.headers.get("content-disposition") ?? "";
      const match = /filename="([^"]+)"/.exec(disposition);
      const filename = match?.[1] ?? "transactions.csv";
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
    } catch {
      setCsvError("Could not reach the server. Check that it's running and try again.");
    } finally {
      setCsvBusy(false);
    }
  }

  // ----- filter handlers -----
  function applyPreset(next: Preset) {
    setPreset(next);
    if (next === "this-year") {
      const r = yearRange(currentYear);
      setFrom(r.from);
      setTo(r.to);
    } else if (next === "last-year") {
      const r = yearRange(currentYear - 1);
      setFrom(r.from);
      setTo(r.to);
    } else if (next === "all-time") {
      setFrom("");
      setTo("");
    }
  }

  function toggleDrCr(on: boolean) {
    setShowDrCr(on);
    writeDrCr(on);
  }

  function openSource(link: SourceLink) {
    const target = OPEN_LINK[link.kind];
    if (target) navigate({ view: target.view, id: link.id });
  }

  // Render the account-register columns only once account-shaped rows have
  // actually LANDED (accountMeta arrives with them). Between picking an
  // account and the response, isAccountMode is already true while `rows`
  // still holds the previous mode's rows (state clears in an effect, which
  // runs after the next paint) — rendering Balance cells against those
  // would read a runningBalance that isn't there.
  const accountView = isAccountMode && accountMeta !== null;

  // Top row is the newest entry shown, so its running balance is the
  // account's balance as of that entry — with no date filter, that IS the
  // current balance (the window sum always runs over full history, so a
  // date-filtered view still continues from everything before it).
  const topBalance = (accountView && rows.length > 0 ? rows[0]!.runningBalance : null) ?? null;
  const hasDateFilter = from !== "" || to !== "";
  // ANY active filter (not just dates) can hide entries newer than the top
  // row, so "Balance now" would be a lie under a type/search/amount filter —
  // say "as of <top row's date>" instead (§9: honest, plain English).
  const hasAnyFilter =
    hasDateFilter || typeKey !== "" || appliedQ !== "" || appliedMin !== "" || appliedMax !== "";

  const emptyMessage = hasDateFilter
    ? "Nothing recorded in this date range yet."
    : "Nothing recorded here yet.";

  // Column count for the empty/loading colspan-free layouts isn't needed —
  // empty states render outside the table entirely, like every other screen.

  return (
    <div className="wrap">
      <header className="top">
        <h1>Transactions</h1>
      </header>

      {!selectedCompanyId ? (
        <p className="msg-inline">Choose a company from the sidebar to see its transactions.</p>
      ) : (
        <>
          <p className="sub" style={{ marginBottom: 14 }}>
            Everything recorded in this company, newest first. Pick an account to see its register.
          </p>

          <div className="report-toolbar register-toolbar">
            <div className="presets">
              <button type="button" aria-pressed={preset === "this-year"} onClick={() => applyPreset("this-year")}>
                This year
              </button>
              <button type="button" aria-pressed={preset === "last-year"} onClick={() => applyPreset("last-year")}>
                Last year
              </button>
              <button type="button" aria-pressed={preset === "all-time"} onClick={() => applyPreset("all-time")}>
                All time
              </button>
            </div>
            <div className="date-inputs">
              <label>
                From
                <input
                  type="date"
                  value={from}
                  onChange={(ev) => {
                    setFrom(ev.target.value);
                    setPreset("custom");
                  }}
                />
              </label>
              <label>
                To
                <input
                  type="date"
                  value={to}
                  onChange={(ev) => {
                    setTo(ev.target.value);
                    setPreset("custom");
                  }}
                />
              </label>
            </div>
            <div className="register-picker">
              <SearchablePicker
                id="register-account"
                label="Account"
                placeholder="Search accounts…"
                groups={pickerGroups}
                value={accountId ?? ALL_ACTIVITY}
                onChange={(id) => setAccountId(id === ALL_ACTIVITY ? null : id)}
              />
            </div>
            <label>
              Type
              <select className="select-input" value={typeKey} onChange={(ev) => setTypeKey(ev.target.value)}>
                <option value="">All types</option>
                {TYPE_OPTIONS.map((t) => (
                  <option key={t.key} value={t.key}>
                    {t.label}
                  </option>
                ))}
              </select>
            </label>
            <label>
              Search
              <input
                type="text"
                className="text-input register-filter-input"
                placeholder="Memo, name, or ref…"
                value={q}
                onChange={(ev) => setQ(ev.target.value)}
              />
            </label>
            <label>
              Amount at least
              <input
                type="text"
                inputMode="decimal"
                className="text-input register-amount-input"
                placeholder="0.00"
                value={amountMin}
                onChange={(ev) => setAmountMin(ev.target.value)}
              />
              {minInvalid && <span className="field-error">{AMOUNT_HINT}</span>}
            </label>
            <label>
              Amount at most
              <input
                type="text"
                inputMode="decimal"
                className="text-input register-amount-input"
                placeholder="0.00"
                value={amountMax}
                onChange={(ev) => setAmountMax(ev.target.value)}
              />
              {maxInvalid && <span className="field-error">{AMOUNT_HINT}</span>}
            </label>
            <div className="register-toolbar-end">
              <button type="button" className="btn" disabled={csvBusy} onClick={() => void downloadCsv()}>
                {csvBusy ? "Preparing…" : "Download CSV"}
              </button>
            </div>
          </div>

          {csvError && <p className="field-error">{csvError}</p>}

          {accountView && accountMeta && (
            <div className="register-account-head">
              <div>
                <h2 className="register-account-name">{accountMeta.name}</h2>
                {topBalance !== null && (
                  <div className="sub">
                    Balance {hasAnyFilter && rows[0] ? `as of ${fmtDate(rows[0].date)}` : "now"}
                  </div>
                )}
              </div>
              {topBalance !== null && <div className="register-balance">{fmtMoney(topBalance)}</div>}
              <label className="register-toggle">
                <input type="checkbox" checked={showDrCr} onChange={(ev) => toggleDrCr(ev.target.checked)} />
                Show debits and credits
              </label>
            </div>
          )}

          {error && <ErrorBanner message={error} onRetry={() => setReloadToken((n) => n + 1)} />}
          {loading && rows.length === 0 && !error && <p className="msg-inline">Loading&hellip;</p>}
          {!loading && !error && rows.length === 0 && <div className="empty-state">{emptyMessage}</div>}

          {rows.length > 0 && (
            <div className="card">
              <table>
                <thead>
                  <tr>
                    <th>Date</th>
                    <th>No.</th>
                    <th>Type</th>
                    <th>Name / Memo</th>
                    {accountView && showDrCr ? (
                      <>
                        <th className="num">Debit</th>
                        <th className="num">Credit</th>
                      </>
                    ) : (
                      <th className="num">Amount</th>
                    )}
                    {accountView && <th className="num">Balance</th>}
                    <th aria-label="Status" />
                  </tr>
                </thead>
                <tbody>
                  {rows.map((row, i) => {
                    const entryId = accountView ? row.entryId! : row.id;
                    const open = row.sourceLink ? OPEN_LINK[row.sourceLink.kind] : undefined;
                    return (
                      <tr
                        key={`${entryId}-${i}`}
                        style={{ cursor: "pointer" }}
                        onClick={() => onSelectEntry(entryId)}
                      >
                        <td style={{ whiteSpace: "nowrap" }}>{fmtDate(row.date)}</td>
                        <td>{row.entryNo}</td>
                        <td style={{ whiteSpace: "nowrap" }}>{row.typeLabel}</td>
                        <td>
                          {/* Who it was with, then what it was for. || not ??:
                              imported history contains ""-memo rows, which should
                              show the same em dash a NULL memo does. With no name
                              the memo keeps the row's normal weight, so an entry
                              that simply has no payee doesn't read as demoted. */}
                          {row.name?.trim() ? (
                            <>
                              <div>{row.name.trim()}</div>
                              <div className="register-memo-sub">{row.memo?.trim() || "—"}</div>
                            </>
                          ) : (
                            <div>{row.memo?.trim() || "—"}</div>
                          )}
                          {row.ref && <div className="register-ref">Ref {row.ref}</div>}
                        </td>
                        {accountView && showDrCr ? (
                          <>
                            <td className="num">{row.debit ? fmtMoney(row.debit) : ""}</td>
                            <td className="num">{row.credit ? fmtMoney(row.credit) : ""}</td>
                          </>
                        ) : (
                          <td className="num">{fmtMoney(row.amount)}</td>
                        )}
                        {accountView && <td className="num">{row.runningBalance ? fmtMoney(row.runningBalance) : ""}</td>}
                        <td className="register-row-end">
                          {/* Both modes. Account-register mode is the one an
                              accountant reconciles in, so a reversed entry
                              looking identical to a live one is worst exactly
                              where it used to be hidden. */}
                          {row.status === "reversed" && (
                            <span className="chip chip-muted">Reversed</span>
                          )}
                          {row.status === "reversal" && (
                            <span className="chip chip-muted">Reversal</span>
                          )}
                          {open && (
                            <button
                              type="button"
                              className="acct-link register-open-link"
                              onClick={(ev) => {
                                ev.stopPropagation();
                                openSource(row.sourceLink!);
                              }}
                            >
                              {open.label}
                            </button>
                          )}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}

          {nextCursor && rows.length > 0 && (
            <div className="pager">
              <button type="button" disabled={loadingMore} onClick={loadMore}>
                {loadingMore ? "Loading…" : "Load more"}
              </button>
            </div>
          )}
        </>
      )}
    </div>
  );
}
