/* Parley — usage. Chart-led: the day chart is the primary display and the two
   tables underneath partition the same array of billed turns, so their columns
   sum back to the figures above them.

   Scope (period, person) is applied before the figures compute and its control
   sits above them (AGENTS §5.3). There are no list filters on this screen —
   nothing here is a list you narrow, so there is one reset and it resets the
   scope. */
(() => {
  const {
    Button, Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter, Select, Meter,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell, Separator,
  } = window.OriginDesignSystem_7c998b;

  const PERIODS = [
    { value: "cycle", label: "This cycle" },
    { value: "14", label: "Last 14 days" },
    { value: "7", label: "Last 7 days" },
  ];

  function DayChart({ buckets, now }) {
    const peak = Math.max.apply(null, buckets.map((b) => b.tokens).concat([1]));
    return (
      <>
        <div className="pl-chart" role="img" aria-label={"Tokens a day over " + buckets.length + " days, peaking at " + formatTokens(peak)}>
          {buckets.map((bucket) => (
            <FloatingTip key={bucket.at} side="bottom"
              label={formatDayFull(bucket.at) + " — " + (bucket.tokens ? formatTokens(bucket.tokens) + " tokens over " + bucket.rows.length + (bucket.rows.length === 1 ? " turn" : " turns") + " · " + formatCost(bucket.cost) : "nothing ran")}>
              <span className="pl-chart__col">
                <span className={"pl-chart__bar" + (bucket.tokens ? "" : " pl-chart__bar--empty")} style={bucket.tokens ? { height: (bucket.tokens / peak) * 100 + "%" } : undefined} />
              </span>
            </FloatingTip>
          ))}
        </div>
        <div className="pl-chart__axis">
          {buckets.map((bucket, i) => (
            <span key={bucket.at}>{i === 0 || i === buckets.length - 1 || new Date(bucket.at).getDate() === 1 ? formatDay(bucket.at) : ""}</span>
          ))}
        </div>
      </>
    );
  }

  function UsageScreen({ data, user, onNavigate }) {
    const [period, setPeriod] = React.useState("cycle");
    const [who, setWho] = React.useState("all");
    const now = data.now;

    const cycleDays = Math.round((now - WORKSPACE.cycleStart) / DAY) + 1;
    const days = period === "cycle" ? cycleDays : parseInt(period, 10);
    const from = period === "cycle" ? WORKSPACE.cycleStart : now - (days - 1) * DAY;

    /* Scope is applied here, once, and every figure below reads the result. */
    const scopedThreads = who === "all" ? data.threads : data.threads.filter((t) => t.ownerId === who);
    const rows = billingRows(scopedThreads, data.files).filter((r) => r.at >= from);
    const buckets = byDay(rows, now, days);
    const tokens = tokensOf(rows);
    const cost = costOf(rows);
    const threadsTouched = rows.reduce((ids, r) => (ids.indexOf(r.thread.id) > -1 ? ids : ids.concat([r.thread.id])), []).length;
    const models = byModel(rows);
    const people = byOwner(rows, data.people);
    const person = who === "all" ? null : personById(data.people, who);
    const dirty = period !== "cycle" || who !== "all";

    return (
      <div className="pl-page">
        <PageHead
          title="Usage"
          note={"A turn is billed for everything in the window when it ran plus what it wrote, so a long thread with big files attached costs more each time you reply to it."}
        />

        <div className="pl-filters" style={{ borderBottom: "1px solid var(--border)", paddingBottom: "var(--space-4)" }}>
          <span className="pl-rail__label">Scope</span>
          <span className="pl-filters__select">
            <label className="pl-sr" htmlFor="pl-period">Period</label>
            <Select id="pl-period" size="sm" items={PERIODS} value={period} onValueChange={setPeriod} />
          </span>
          <span className="pl-filters__select">
            <label className="pl-sr" htmlFor="pl-who">Person</label>
            <Select id="pl-who" size="sm" value={who} onValueChange={setWho}
              items={[{ value: "all", label: "Everyone" }].concat(data.people.map((p) => ({ value: p.id, label: p.name })))} />
          </span>
          {dirty ? <Button variant="ghost" size="sm" onClick={() => { setPeriod("cycle"); setWho("all"); }}>Reset scope</Button> : null}
          <p className="pl-foot" style={{ flexBasis: "100%" }}>
            {period === "cycle"
              ? "The current cycle, " + formatDay(WORKSPACE.cycleStart) + " to today."
              : "The last " + days + " days, to today."}
            {person ? " " + person.name + "’s threads only — " + WORKSPACE.name + " has " + data.people.length + " people." : " Everyone in " + WORKSPACE.name + "."}
          </p>
        </div>

        <AnchorRow items={[
          { label: "Tokens", value: formatTokens(tokens), qualifier: formatTokens(rows.reduce((s, r) => s + r.in, 0)) + " read, " + formatTokens(rows.reduce((s, r) => s + r.out, 0)) + " written" },
          { label: "Cost", value: formatCost(cost), qualifier: "At the published rates, no discount applied" },
          { label: "Billed turns", value: String(rows.length), qualifier: "Failed turns are not billed and are not counted" },
          { label: "Threads", value: String(threadsTouched), qualifier: "Had at least one turn in this period" },
        ]} />

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Tokens a day</CardTitle>
            <CardDescription>
              {buckets.filter((b) => b.tokens).length} of these {days} days had a turn on them. The bars are the same {rows.length} turns as the figures above.
            </CardDescription>
          </CardHeader>
          <CardPanel><DayChart buckets={buckets} now={now} /></CardPanel>
          <CardFooter>
            <div className="pl-stack--tight" style={{ display: "flex", flexDirection: "column", width: "100%" }}>
              <div className="pl-spread">
                <span className="pl-foot">{formatTokens(tokens)} of the {formatTokens(WORKSPACE.includedTokens)} included in {labelOf(PLANS, WORKSPACE.plan)}</span>
                <span className="pl-foot">{Math.round((tokens / WORKSPACE.includedTokens) * 100)}%</span>
              </div>
              <Bar ratio={tokens / WORKSPACE.includedTokens} tone={tokens / WORKSPACE.includedTokens >= 0.75 ? "warn" : null} />
              <span className="pl-foot">
                {who === "all"
                  ? "The allowance is workspace-wide and resets on " + formatDayFull(WORKSPACE.cycleEnd + DAY) + "."
                  : "The allowance is workspace-wide; this bar shows " + person.name.split(" ")[0] + "’s share of it."}
              </span>
            </div>
          </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>By model</CardTitle>
                <CardDescription>Output is billed at five times input on every model, which is why a long question is cheap and a long answer is not.</CardDescription>
              </CardHeader>
              <CardPanel className="pl-card-table">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Model</TableHead>
                      <TableHead className="pl-num">Turns</TableHead>
                      <TableHead className="pl-num">Read</TableHead>
                      <TableHead className="pl-num">Written</TableHead>
                      <TableHead className="pl-num">Cost</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {models.map((row) => (
                      <TableRow key={row.key}>
                        <TableCell>
                          <span className="pl-record">
                            <span className="pl-record__name">{row.model.label}</span>
                            <span className="pl-record__meta">{formatRate(row.model.inRate)} in · {formatRate(row.model.outRate)} out</span>
                          </span>
                        </TableCell>
                        <TableCell className="pl-num">{row.rows.length}</TableCell>
                        <TableCell className="pl-num">{formatTokens(row.rows.reduce((s, r) => s + r.in, 0))}</TableCell>
                        <TableCell className="pl-num">{formatTokens(row.rows.reduce((s, r) => s + r.out, 0))}</TableCell>
                        <TableCell className="pl-num">{formatCost(row.cost)}</TableCell>
                      </TableRow>
                    ))}
                    <TableRow>
                      <TableCell><strong>Total</strong></TableCell>
                      <TableCell className="pl-num"><strong>{rows.length}</strong></TableCell>
                      <TableCell className="pl-num"><strong>{formatTokens(rows.reduce((s, r) => s + r.in, 0))}</strong></TableCell>
                      <TableCell className="pl-num"><strong>{formatTokens(rows.reduce((s, r) => s + r.out, 0))}</strong></TableCell>
                      <TableCell className="pl-num"><strong>{formatCost(cost)}</strong></TableCell>
                    </TableRow>
                  </TableBody>
                </Table>
              </CardPanel>
            </Card>
          </div>
          <div className="pl-col">
            <Card className="pl-card-full">
              <CardHeader>
                <CardTitle>By person</CardTitle>
                <CardDescription>Threads are counted where they were started, not where they were read.</CardDescription>
              </CardHeader>
              <CardPanel className="pl-card-table">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Person</TableHead>
                      <TableHead className="pl-num">Threads</TableHead>
                      <TableHead className="pl-num">Turns</TableHead>
                      <TableHead className="pl-num">Tokens</TableHead>
                      <TableHead className="pl-num">Cost</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {people.map((row) => (
                      <TableRow key={row.key}>
                        <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}</span>
                          </span>
                        </TableCell>
                        <TableCell className="pl-num">{row.threads}</TableCell>
                        <TableCell className="pl-num">{row.rows.length}</TableCell>
                        <TableCell className="pl-num">{formatTokens(row.tokens)}</TableCell>
                        <TableCell className="pl-num">{formatCost(row.cost)}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </CardPanel>
              <CardFooter>
                <span className="pl-foot">
                  {people.length} of {data.people.length} people ran a turn in this period. {WORKSPACE.seats} seats are paid for.
                </span>
              </CardFooter>
            </Card>
          </div>
        </div>
      </div>
    );
  }

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