/* Dashboard — the screen the product opens on.
   Commit model: INSTANT. There is no Save button anywhere on this screen; each
   control confirms itself. Harmless controls apply bare (period scope, tab),
   consequential ones apply immediately and raise an undo toast (capture, retry,
   approve), irreversible ones open a confirm dialog (refund, reject).
   Data state: populated. Loading, empty, no-results and error are branches of
   one conditional elsewhere — none of them is on screen beside these rows. */

const {
  Card: TileCard, CardPanel: TileCardPanel,
  Select, Button: ScreenButton, MenuItem: ExportItem, MenuGroupLabel: ExportLabel,
  AlertDialog, AlertDialogPopup, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter,
  Empty: ScreenEmpty, EmptyHeader: ScreenEmptyHeader, EmptyMedia: ScreenEmptyMedia,
  EmptyTitle: ScreenEmptyTitle, EmptyDescription: ScreenEmptyDescription, EmptyContent: ScreenEmptyContent,
} = window.OriginDesignSystem_7c998b;

/* The figure tile every screen opens with. The icon is inset in the top-right
   corner at the card's own radius less its inset, so the chip is concentric
   with the card rather than merely near its corner. It names the KIND of figure
   and nothing else — it carries no state, so it never competes with the value. */
function MetricTile({ label, value, qualifier, icon }) {
  return (
    <TileCard className={"fd-tile" + (icon ? " fd-tile--icon" : "")}>
      {icon ? <span className="fd-tile__icon" aria-hidden="true"><Icon name={icon} size={16} /></span> : null}
      <TileCardPanel className="fd-tile__body">
        <span className="fd-tile__label">{label}</span>
        <span className="fd-tile__value">{value}</span>
        <span className="fd-tile__qualifier">{qualifier}</span>
      </TileCardPanel>
    </TileCard>
  );
}

function ConfirmDialog({ request, onCancel, onConfirm }) {
  return (
    <AlertDialog open={!!request} onOpenChange={(open) => { if (!open) onCancel(); }}>
      <AlertDialogPopup>
        <AlertDialogHeader>
          <AlertDialogTitle>{request ? request.title : ""}</AlertDialogTitle>
          <AlertDialogDescription>{request ? request.description : ""}</AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <ScreenButton variant="outline" onClick={onCancel}>Cancel</ScreenButton>
          <ScreenButton variant="destructive" onClick={onConfirm}>{request ? request.confirmLabel : ""}</ScreenButton>
        </AlertDialogFooter>
      </AlertDialogPopup>
    </AlertDialog>
  );
}

/* Nothing in this product links here: every rendered entry point resolves to a
   registered route. It exists for a hand-typed or stale path — which has no
   breadcrumb, because the route table is what breadcrumbs are made of. */
function RouteNotBuilt({ path, onNavigate }) {
  const route = matchRoute(path, MERIDIAN_ROUTES);
  return (
    <div className="fd-page">
      <PageHeader path={path} title={route ? route.label : "Not found"} />
      <ScreenEmpty>
        <ScreenEmptyHeader>
          <ScreenEmptyMedia variant="icon"><Icon name="route" size={18} /></ScreenEmptyMedia>
          <ScreenEmptyTitle>{route ? route.label + " is registered, not built" : "There is nothing at " + path}</ScreenEmptyTitle>
          <ScreenEmptyDescription>{route ? "The route and its place in the palette are real; the screen behind it is not part of this template." : "This path is not in Meridian's route table, so it has no breadcrumb and nothing links to it. The eleven destinations in the sidebar are the whole product."}</ScreenEmptyDescription>
        </ScreenEmptyHeader>
        <ScreenEmptyContent>
          <ScreenButton variant="outline" onClick={() => onNavigate("/")}>Back to dashboard</ScreenButton>
        </ScreenEmptyContent>
      </ScreenEmpty>
    </div>
  );
}

function DashboardScreen({ data, pushToast, onNavigate, period, onPeriodChange, commits }) {
  const now = MERIDIAN_NOW;
  /* Every commit is App.jsx's, so this row and the row on the payouts screen
     call one function (AGENTS §8.2). */
  const { approvePayout, rejectPayout, refundPayment, capturePayment, retryPayment, approveExpense, onExpenseTransition } = commits;
  const days = Number(period);
  const periodLabel = PERIODS.find((p) => p.value === period).label;

  /* Every figure below reads one of these two scoped arrays, or the live
     payouts / disputes / balance the cards name for themselves. */
  const periodPayments = paymentsInPeriod(data.payments, days, now);
  const periodDisputes = disputesInPeriod(data.disputes, days, now);
  const periodExpenses = expensesInPeriod(data.expenses, days, now);

  const succeeded = succeededPayments(periodPayments);
  const refunded = refundedPayments(periodPayments);
  const failed = failedPayments(periodPayments);
  const attempts = settledAttempts(periodPayments);
  const authorised = authorisedAttempts(periodPayments);

  const exportMenu = (
    <Floating
      align="end"
      width="12rem"
      label="Export"
      trigger={<ScreenButton variant="outline" size="sm"><Icon name="download" />Export<Icon name="chevron-down" /></ScreenButton>}
    >
      {(close) => (
        <>
          <ExportLabel>{periodLabel}</ExportLabel>
          {["CSV", "XLSX"].map((format) => (
            <ExportItem key={format} onClick={() => { close(); pushToast({ title: "Export started", description: periodLabel + " · " + format + " — we'll email it to " + MERIDIAN_USER.name.split(" ")[0].toLowerCase() + "@northwind.example" }); }}>
              {format}
            </ExportItem>
          ))}
        </>
      )}
    </Floating>
  );

  return (
    <div className="fd-page">
      <PageHeader path="/" title="Dashboard" actions={exportMenu} />

      {/* Scope. Sits above the figures it moves. */}
      <div className="fd-scope">
        <div className="fd-scope__control">
          <label className="fd-scope__label" htmlFor="fd-period">Period</label>
          <Select id="fd-period" size="sm" items={PERIODS} value={period} onValueChange={onPeriodChange} />
        </div>
        <p className="fd-scope__note">Volume figures cover the {periodLabel.toLowerCase()}. Balance, payouts and disputes are current.</p>
      </div>

      <div className="fd-metrics">
        <MetricTile
          icon="trending-up" label="Net volume"
          value={formatMoney(netVolume(periodPayments))}
          qualifier={formatMoney(sumBy(succeeded, "amount")) + " across " + succeeded.length + " succeeded, less " + formatMoney(refundTotal(periodPayments)) + " refunded"}
        />
        <MetricTile
          icon="percent" label="Authorisation rate"
          value={formatPercent(authorisationRate(periodPayments))}
          qualifier={authorised.length + " of " + attempts.length + " attempts with an outcome"}
        />
        <MetricTile
          icon="x-circle" label="Failed payments"
          value={formatCount(failed.length)}
          qualifier={formatMoney(sumBy(failed, "amount")) + " not collected"}
        />
        <MetricTile
          icon="shield-alert" label="Disputes opened"
          value={formatMoney(sumBy(periodDisputes, "amount"))}
          qualifier={periodDisputes.length + " opened, " + disputesNeedingEvidence(periodDisputes).length + " still need evidence"}
        />
        <MetricTile
          icon="receipt" label="Card spend"
          value={formatMoney(cardSpendTotal(periodExpenses))}
          qualifier={settledExpenses(periodExpenses).length + " settled expenses on " + liveCards(data.cards).length + " live cards, " + reviewableExpenses(periodExpenses, data.policy).length + " of them waiting on your review"}
        />
      </div>

      <div className="fd-columns">
        <div className="fd-col">
          <VolumeCard payments={periodPayments} periodLabel={periodLabel} now={now} days={days} />
          <PayoutQueueCard payouts={data.payouts} approver={data.approver} members={data.members} now={now} onApprove={approvePayout} onReject={rejectPayout} onNavigate={onNavigate} />
          <PaymentsCard
            payments={periodPayments}
            disputes={data.disputes}
            periodLabel={periodLabel}
            now={now}
            onCapture={capturePayment}
            onRetry={retryPayment}
            onRefund={refundPayment}
            onNavigate={onNavigate}
          />
        </div>
        <div className="fd-col">
          <BalanceCard balance={data.balance} payouts={data.payouts} disputes={data.disputes} onNavigate={onNavigate} />
          <DisputesCard disputes={data.disputes} now={now} onNavigate={onNavigate} />
          <ReplyQueueCard data={data} signedInId={MERIDIAN_SIGNED_IN} now={now} onNavigate={onNavigate} />
          <ExpenseReviewCard
            expenses={data.expenses}
            cards={data.cards}
            members={data.members}
            policy={data.policy}
            now={now}
            onApprove={approveExpense}
            onRun={onExpenseTransition}
            onNavigate={onNavigate}
          />
          <MethodMixCard payments={periodPayments} periodLabel={periodLabel} />
        </div>
      </div>

    </div>
  );
}

Object.assign(window, { DashboardScreen, RouteNotBuilt, MetricTile, ConfirmDialog });
