/* Parley — the two screens that own the workspace rather than the work: who is
   in it, and what it costs. Commit model: INSTANT on both. No Save button
   anywhere; a Select or a Switch applies the moment it moves and raises an undo
   toast from App.jsx where the change is consequential, and the three changes
   that need more than one field — renaming the workspace, replacing the card,
   setting the cap — open a staged dialog, which is legal because a dialog
   carries its own commit model.

   Every figure here is a function from metrics.js. Seats are people plus the
   invites still standing; the cycle's charge is the plan's seat price times the
   paid seats plus the turns that ran after the allowance was exhausted — the
   same billed turns the usage screen reads, so the two screens cannot drift. */
(() => {
  const {
    Button, Badge, Select, Switch, Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell,
    Alert, AlertTitle, AlertDescription, Separator,
  } = window.OriginDesignSystem_7c998b;

  /* ── Workspace ─────────────────────────────────────────────────────── */

  function WorkspaceScreen({ data, user, onChangeAccess, onRunMember, onRunInvite, onInvite, onRename, onRetention, onSso, onNavigate }) {
    const now = data.now;
    const plan = planOf(WORKSPACE.plan);
    const members = memberRows(data);
    const dormant = members.filter((m) => m.dormant);
    const seenThisWeek = data.people.filter((p) => now - p.lastSeenAt < 7 * DAY);
    const standing = standingInvites(data);
    const expired = expiredInvites(data);
    const sharedIn = liveThreads(data.threads).filter((t) => t.visibility !== "private");
    const left = seatsLeft(data);
    const ssoAvailable = plan.value === "company";

    const inviteButton = (
      <Button size="sm" disabled={!canInvite(data)} onClick={onInvite}><Icon name="user-plus" size={14} />Invite people</Button>
    );

    return (
      <div className="pl-page">
        <PageHead
          title="Workspace"
          note={"Northgate has been on Parley since " + formatDay(WORKSPACE.startedAt) + ". Everything shared with the workspace is readable by every person below, and by nobody else."}
        />

        <AnchorRow items={[
          { label: "Seats used", value: seatsUsed(data) + " of " + WORKSPACE.seats, qualifier: data.people.length + " people and " + standing.length + " " + (standing.length === 1 ? "invite" : "invites") + " still standing" },
          { label: "People", value: String(data.people.length), qualifier: seenThisWeek.length + " signed in this week" + (dormant.length ? " · " + dormant.length + " not in 60 days" : "") },
          { label: "Invites out", value: String(standing.length), qualifier: expired.length ? expired.length + " expired, holding no seat" : "None have expired" },
          { label: "Shared threads", value: String(sharedIn.length), qualifier: "Readable by everyone in the workspace" },
        ]} />

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>People</CardTitle>
            <CardDescription>
              Access changes apply the moment you pick one. Cost is what their own threads have been billed, at the rates on the models page.
            </CardDescription>
          </CardHeader>
          <CardPanel className="pl-card-table">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Person</TableHead>
                  <TableHead>Access</TableHead>
                  <TableHead>Last signed in</TableHead>
                  <TableHead className="pl-num pl-drop-md">Threads</TableHead>
                  <TableHead className="pl-num">Cost</TableHead>
                  <TableHead className="pl-actions-head">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {members.map((row) => (
                  <TableRow key={row.person.id} className={row.dormant ? "pl-row--recessed" : undefined}>
                    <TableCell>
                      <span className="pl-record">
                        <span className="pl-record__name">{row.person.name}{row.person.id === user.id ? " (you)" : ""}</span>
                        <span className="pl-record__meta">{row.person.role} · {row.person.email}</span>
                      </span>
                    </TableCell>
                    <TableCell>
                      {row.person.access === "owner" ? (
                        <FloatingTip side="bottom" label={labelOf(ACCESS_LEVELS, "owner") + " — " + ACCESS_LEVELS[0].note}>
                          <span className="pl-muted">{labelOf(ACCESS_LEVELS, "owner")}</span>
                        </FloatingTip>
                      ) : (
                        <span className="pl-filters__select" style={{ width: "8.5rem" }}>
                          <label className="pl-sr" htmlFor={"pl-access-" + row.person.id}>Access for {row.person.name}</label>
                          <Select id={"pl-access-" + row.person.id} size="sm" value={row.person.access}
                            items={ACCESS_LEVELS.filter((a) => a.value !== "owner")}
                            onValueChange={(v) => onChangeAccess(row.person, v)} />
                        </span>
                      )}
                    </TableCell>
                    <TableCell title={formatAbsolute(row.person.lastSeenAt)}>
                      <span className="pl-when">{formatWhen(row.person.lastSeenAt, now)}</span>
                      {row.dormant ? <span className="pl-sub">Not in {Math.round((now - row.person.lastSeenAt) / DAY)} days, still holding a seat</span> : null}
                    </TableCell>
                    <TableCell className="pl-num pl-drop-md">{row.threads.length}</TableCell>
                    <TableCell className="pl-num">{formatCost(row.cost)}</TableCell>
                    <TableCell className="pl-actions">
                      <RowActions transitions={memberTransitions(row.person, user)} onRun={(t) => onRunMember(row.person, t)} label={"Actions for " + row.person.name} />
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </CardPanel>
          <CardFooter>
            <span className="pl-foot">
              {data.people.length} people against {WORKSPACE.seats} paid seats
              {dormant.length ? " · " + dormant.length + " not signed in for 60 days, shown recessed — removing one frees a seat" : ""}
            </span>
          </CardFooter>
        </Card>

        <div className="pl-columns">
          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>Invites</CardTitle>
                <CardDescription>
                  {standing.length
                    ? standing.length + " " + (standing.length === 1 ? "invite is" : "invites are") + " still standing and " + (standing.length === 1 ? "holds a seat" : "hold a seat each") + (expired.length ? "; " + expired.length + " expired and " + (expired.length === 1 ? "holds" : "hold") + " nothing." : ".")
                    : "Nothing is outstanding. An invite holds a seat from the moment it is sent until it expires."}
                </CardDescription>
              </CardHeader>
              {data.invites.length ? (
                <CardPanel>
                  <div className="pl-stack--tight" style={{ display: "flex", flexDirection: "column" }}>
                    {data.invites.map((invite) => {
                      const gone = INVITE_FLAGS.isExpired(invite, now);
                      return (
                        <div className={"pl-setting" + (gone ? " pl-row--recessed" : "")} key={invite.id}>
                          <span className="pl-setting__text">
                            <span className="pl-setting__name">{invite.email}</span>
                            <span className="pl-record__meta">
                              {labelOf(ACCESS_LEVELS, invite.access)} · invited by {personById(data.people, invite.invitedBy).name.split(" ")[0]} {formatAge(invite.at, now)} ·{" "}
                              {gone ? "expired " + formatAge(invite.expiresAt, now) : formatCountdown(invite.expiresAt, now) + " to accept"}
                            </span>
                            <span className="pl-record__meta">{invite.note}</span>
                          </span>
                          <RowActions transitions={inviteTransitions(invite, now)} onRun={(t) => onRunInvite(invite, t)} label={"Actions for the invite to " + invite.email} />
                        </div>
                      );
                    })}
                  </div>
                </CardPanel>
              ) : null}
              <CardFooter>
                {canInvite(data)
                  ? inviteButton
                  : <FloatingTip side="bottom" label={"All " + WORKSPACE.seats + " seats are taken. Remove someone, revoke an invite, or add seats on the billing page."}>{inviteButton}</FloatingTip>}
                <span className="pl-foot" style={{ marginInlineStart: "auto" }}>
                  {left ? left + " " + (left === 1 ? "seat" : "seats") + " free" : "No seat free"}
                </span>
              </CardFooter>
            </Card>
          </div>
          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>Policy</CardTitle>
                <CardDescription>Three settings, each applying as soon as it moves.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="pl-setting">
                  <span className="pl-setting__text">
                    <span className="pl-setting__name">Name</span>
                    <span className="pl-record__meta">{WORKSPACE.name} — it appears on every invite, every shared link and the sign-in page.</span>
                  </span>
                  <Button size="xs" variant="outline" onClick={onRename}>Rename workspace</Button>
                </div>
                <div className="pl-setting">
                  <span className="pl-setting__text">
                    <span className="pl-setting__name">Deleted threads</span>
                    <span className="pl-record__meta">How long a deleted thread's messages are recoverable by support before they go for good.</span>
                  </span>
                  <span className="pl-filters__select">
                    <label className="pl-sr" htmlFor="pl-retention">Retention</label>
                    <Select id="pl-retention" size="sm" items={RETENTION_OPTIONS} value={String(WORKSPACE.retentionDays)} onValueChange={onRetention} />
                  </span>
                </div>
                <div className="pl-setting">
                  <span className="pl-setting__text">
                    <span className="pl-setting__name">Require single sign-on</span>
                    <span className="pl-record__meta">
                      {ssoAvailable
                        ? "Everyone signs in through your identity provider; passwords stop working."
                        : labelOf(PLANS, "company") + " only. On " + plan.label + ", people sign in with an email and a password."}
                    </span>
                  </span>
                  {ssoAvailable ? (
                    <Switch checked={WORKSPACE.ssoRequired} onCheckedChange={onSso} aria-label="Require single sign-on" />
                  ) : (
                    <FloatingTip side="bottom" label={"Enforced single sign-on is part of " + labelOf(PLANS, "company") + ". Change the plan on the billing page."}>
                      <span className="pl-chips">
                        <Switch checked={false} disabled aria-label="Require single sign-on — not on this plan" />
                      </span>
                    </FloatingTip>
                  )}
                </div>
              </CardPanel>
              <CardFooter>
                <Button size="xs" variant="ghost" onClick={() => onNavigate("/settings/billing")}>Plan and billing<Icon name="arrow-right" size={13} /></Button>
              </CardFooter>
            </Card>
          </div>
        </div>
      </div>
    );
  }

  /* ── Plan and billing ──────────────────────────────────────────────── */

  function BillingScreen({ data, user, onRunInvoice, onChangePlan, onUpdateCard, onSetCap, onNavigate }) {
    const now = data.now;
    const charges = cycleCharges(data);
    const plan = charges.plan;
    const cycle = cycleUsage(data);
    const ratio = cycle.tokens / plan.includedTokens;
    const failed = data.invoices.filter(INVOICE_FLAGS.needsAction);
    const cardExpired = PAYMENT_FLAGS.isExpired(data.payment, now);
    const charged = chargedInvoices(data.invoices);
    const capRatio = WORKSPACE.spendCapCents ? charges.total / WORKSPACE.spendCapCents : 0;

    return (
      <div className="pl-page">
        <PageHead
          title="Plan and billing"
          note={"Seats are charged once a month. Turns are included until the allowance runs out, and billed at the published rates after that — so what this cycle costs moves every time anyone sends a message."}
        />

        {failed.length ? (
          <Alert variant="error">
            <AlertTitle>{failed[0].number} was not paid</AlertTitle>
            <AlertDescription>
              {formatCost(invoiceTotal(failed[0]))} for {formatDay(failed[0].periodStart)} to {formatDay(failed[0].periodEnd)}. {failed[0].statusNote}
              {" "}Replacing the card below retries it; so does the invoice's own row action.
            </AlertDescription>
          </Alert>
        ) : null}

        <AnchorRow items={[
          { label: "This cycle", value: formatCost(charges.total), qualifier: charges.seats + " seats at " + formatCost(plan.seatPrice) + " each" + (charges.overage ? ", plus " + formatCost(charges.overage) + " over the allowance" : ", nothing over the allowance yet") },
          { label: "Tokens", value: formatTokens(cycle.tokens), qualifier: "of the " + formatTokens(plan.includedTokens) + " included · " + Math.round(ratio * 100) + "%" },
          { label: "Billed turns", value: String(cycle.rows.length), qualifier: charges.overageRows.length ? charges.overageRows.length + " of them past the allowance" : "All inside the allowance" },
          { label: "Next invoice", value: formatDay(WORKSPACE.cycleEnd + DAY), qualifier: "Charged to the card on file" },
        ]} />

        {/* The plan is a list of three options and needs the width; the two
           small money widgets sit side by side underneath, so neither column
           runs out of content before the other (AGENTS §5.1). */}
        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Plan</CardTitle>
            <CardDescription>Seat price is per person per month. A plan that cannot hold this workspace says so rather than letting you pick it.</CardDescription>
          </CardHeader>
          <CardPanel>
            {PLANS.map((option) => {
              const current = option.value === plan.value;
              const tooSmall = option.seatLimit < seatsUsed(data);
              const button = (
                <Button size="xs" variant="outline" disabled={tooSmall} onClick={() => onChangePlan(option)}>Change plan</Button>
              );
              return (
                <div className="pl-setting" key={option.value}>
                  <span className="pl-setting__text">
                    <span className="pl-setting__name">{option.label} · {formatCost(option.seatPrice)} a seat</span>
                    <span className="pl-record__meta">{formatTokens(option.includedTokens)} tokens included · up to {option.seatLimit} seats</span>
                    <span className="pl-record__meta">{option.blurb}</span>
                  </span>
                  <span className="pl-chips">
                    {current
                      ? <Badge size="sm" variant="secondary">Current</Badge>
                      : tooSmall
                        ? <FloatingTip side="bottom" label={option.label + " covers " + option.seatLimit + " seats. " + WORKSPACE.name + " is using " + seatsUsed(data) + "."}>{button}</FloatingTip>
                        : button}
                  </span>
                </div>
              );
            })}
          </CardPanel>
          <CardFooter>
            <span className="pl-foot">
              {plan.label} at {formatCost(plan.seatPrice)} × {charges.seats} seats is {formatCost(charges.seatCost)} a month before any usage.
            </span>
          </CardFooter>
        </Card>

        <div className="pl-columns pl-columns--even" style={{ gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)" }}>
          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>Card on file</CardTitle>
                <CardDescription>One card, charged on the first of the month.</CardDescription>
              </CardHeader>
              <CardPanel>
                <dl className="pl-defs">
                  <div><dt>Card</dt><dd>{data.payment.brand} ···· {data.payment.last4}</dd></div>
                  <div>
                    <dt>Expires</dt>
                    <dd style={cardExpired ? { color: "var(--destructive-foreground)" } : undefined}>
                      {String(data.payment.expMonth).padStart(2, "0")}/{data.payment.expYear}
                    </dd>
                  </div>
                  <div><dt>Name</dt><dd>{data.payment.holder}</dd></div>
                  <div><dt>Added</dt><dd>{formatDay(data.payment.addedAt)}</dd></div>
                </dl>
                {cardExpired ? (
                  <p className="pl-turn__note"><Icon name="credit-card" size={16} />This card expired. Nothing can be charged until it is replaced, including the retry on {failed.length ? failed[0].number : "the open invoice"}.</p>
                ) : null}
              </CardPanel>
              <CardFooter>
                <Button size="sm" variant={cardExpired ? "default" : "outline"} onClick={onUpdateCard}>Update card</Button>
              </CardFooter>
            </Card>
          </div>

          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>Spend cap</CardTitle>
                <CardDescription>A ceiling for one cycle. Turns stop rather than the bill growing past it.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="pl-stack--tight" style={{ display: "flex", flexDirection: "column" }}>
                  <div className="pl-spread">
                    <span className="pl-rail__figure">{WORKSPACE.spendCapCents ? formatCost(WORKSPACE.spendCapCents) : "No cap"}</span>
                    <span className="pl-foot">{WORKSPACE.spendCapCents ? Math.round(capRatio * 100) + "% used" : ""}</span>
                  </div>
                  {WORKSPACE.spendCapCents ? <Bar ratio={capRatio} tone={capRatio >= 0.75 ? "warn" : null} /> : null}
                  <span className="pl-foot">
                    {WORKSPACE.spendCapCents
                      ? formatCost(charges.total) + " of " + formatCost(WORKSPACE.spendCapCents) + " this cycle, seats included. Seats are charged whether or not the cap is reached; only turns stop."
                      : "Nothing stops a turn. This cycle stands at " + formatCost(charges.total) + "."}
                  </span>
                </div>
              </CardPanel>
              <CardFooter>
                <Button size="sm" variant="outline" onClick={onSetCap}>Set spend cap</Button>
              </CardFooter>
            </Card>
          </div>
        </div>

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Invoices</CardTitle>
            <CardDescription>Issued monthly, seats and usage on one line each. This cycle is not here yet — it is the figure above.</CardDescription>
          </CardHeader>
          <CardPanel className="pl-card-table">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Invoice</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="pl-num pl-drop-md">Seats</TableHead>
                  <TableHead className="pl-num pl-drop-md">Usage</TableHead>
                  <TableHead className="pl-num">Total</TableHead>
                  <TableHead className="pl-actions-head">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.invoices.map((invoice) => (
                  <TableRow key={invoice.id} className={INVOICE_FLAGS.isCharged(invoice) ? undefined : "pl-row--recessed"}>
                    <TableCell>
                      <span className="pl-record">
                        <span className="pl-record__name">{invoice.number}</span>
                        <span className="pl-record__meta">{formatDay(invoice.periodStart)} – {formatDay(invoice.periodEnd)} · {invoice.seats} seats</span>
                      </span>
                    </TableCell>
                    <TableCell>
                      <span className="pl-record">
                        <StatusBadge values={INVOICE_STATUS} value={invoice.status} />
                        {invoice.statusNote ? <span className="pl-sub">{invoice.statusNote}</span> : invoice.paidAt ? <span className="pl-sub">Paid {formatDay(invoice.paidAt)}</span> : null}
                      </span>
                    </TableCell>
                    <TableCell className="pl-num pl-drop-md">{formatCost(invoice.seatCost)}</TableCell>
                    <TableCell className="pl-num pl-drop-md">{formatCost(invoice.usageCost)}</TableCell>
                    <TableCell className="pl-num">{formatCost(invoiceTotal(invoice))}</TableCell>
                    <TableCell className="pl-actions">
                      <RowActions transitions={invoiceTransitions(invoice)} onRun={(t) => onRunInvoice(invoice, t)} label={"Actions for " + invoice.number} />
                    </TableCell>
                  </TableRow>
                ))}
                <TableRow>
                  <TableCell><strong>Charged to date</strong></TableCell>
                  <TableCell className="pl-muted">{charged.length} of {data.invoices.length} invoices</TableCell>
                  <TableCell className="pl-num pl-drop-md"><strong>{formatCost(charged.reduce((s, i) => s + i.seatCost, 0))}</strong></TableCell>
                  <TableCell className="pl-num pl-drop-md"><strong>{formatCost(charged.reduce((s, i) => s + i.usageCost, 0))}</strong></TableCell>
                  <TableCell className="pl-num"><strong>{formatCost(charged.reduce((s, i) => s + invoiceTotal(i), 0))}</strong></TableCell>
                  <TableCell />
                </TableRow>
              </TableBody>
            </Table>
          </CardPanel>
          <CardFooter>
            <span className="pl-foot">
              Voided invoices are shown recessed and are left out of the total — nothing was ever charged against them. Every usage line above is the same billed turns the usage screen charts.
            </span>
            <Button size="sm" variant="ghost" style={{ marginInlineStart: "auto", flex: "none" }} onClick={() => onNavigate("/usage")}>Usage, turn by turn<Icon name="arrow-right" size={13} /></Button>
          </CardFooter>
        </Card>
      </div>
    );
  }

  Object.assign(window, { WorkspaceScreen, BillingScreen });
})();
