// <StatusChips> — the agent page's status row: the consolidated status
// badge (alive/thinking/paused/etc., with pause/resume + cancel-turn in
// its dropdown), the model + effort pickers, and context/cost usage.
// This is the concrete fix for the design guide's own named anti-example
// (the old page's model/effort *pickers* lived in the `⋯` overflow menu
// while the current model/effort only showed as a disconnected chip) —
// every badge here IS the control for what it displays, composed from
// `@hive/shared`'s `Badge`/`Dropdown` (../../shared/src/badge,
// ../../shared/src/dropdown). Presentational only: formatting +
// selection state live in the caller (`Root.tsx`, via the
// `useAgentState` hook), so this component can still be demoed and
// reviewed against plain sample data independent of live `/api/state`.
import { useRef, useState } from "preact/hooks";
import { Badge, type BadgeTone } from "@hive/shared/badge.js";
import { Dropdown, type DropdownOption } from "@hive/shared/dropdown.js";
import "./StatusChips.css";

export interface StatusChipsProps {
  statusLabel: string;
  statusTone: BadgeTone;
  statusTooltip?: string;
  model: string;
  /** Concrete model id the last completed turn actually ran on, e.g.
   * "claude-sonnet-4-5-20260805" — shown as the badge's tooltip so the
   * operator can tell what an alias resolved to. `undefined` before any
   * turn has completed. */
  resolvedModel?: string;
  availableModels: string[];
  onSelectModel: (name: string) => void;
  effort: string;
  availableEfforts: string[];
  onSelectEffort: (level: string) => void;
  ctxLabel?: string;
  costLabel?: string;
  paused: boolean;
  onTogglePause: () => void;
  lastTurnLabel?: string;
  thinking: boolean;
  onCancelTurn: () => Promise<void>;
}

const MODEL_DESCRIPTIONS: Record<string, string> = {
  haiku: "fast",
  sonnet: "balanced",
  opus: "powerful",
};
const EFFORT_DESCRIPTIONS: Record<string, string> = {
  low: "",
  medium: "default",
  high: "",
  xhigh: "",
  max: "",
};

function Picker({
  label,
  value,
  options,
  descriptions,
  onSelect,
  title,
}: {
  label: string;
  value: string;
  options: string[];
  descriptions: Record<string, string>;
  onSelect: (v: string) => void;
  title?: string;
}) {
  const [open, setOpen] = useState(false);
  const anchorRef = useRef<HTMLDivElement>(null);
  const dropdownOptions: DropdownOption[] = options.map((name) => ({
    value: name,
    label: name,
    description: descriptions[name] || undefined,
  }));
  return (
    <div class="status-chip-anchor" ref={anchorRef}>
      <Badge
        label={label}
        value={value}
        onClick={() => setOpen((o) => !o)}
        expanded={open}
        title={title}
      />
      <Dropdown
        open={open}
        options={dropdownOptions}
        activeValue={value}
        label={`select ${label}`}
        onSelect={(v) => {
          onSelect(v);
          setOpen(false);
        }}
        onClose={() => setOpen(false)}
        anchorRef={anchorRef}
      />
    </div>
  );
}

// The consolidated alive/thinking/paused badge (mara: "why do we
// have separate alive badge? ... it could be one badge that shows
// thinking / idle / paused / ... with a dropdown that opens when
// clicked to pause/unpause or cancel turn"). Cancel-turn is a
// click-again-to-confirm row rather than a native confirm dialog (mara:
// "make the menu entry a 'click again to confirm'") — armed state resets
// whenever the dropdown closes, so a stray reopen never fires it early.
function StatusMenu({
  statusLabel,
  statusTone,
  statusTooltip,
  paused,
  onTogglePause,
  thinking,
  onCancelTurn,
}: Pick<
  StatusChipsProps,
  | "statusLabel"
  | "statusTone"
  | "statusTooltip"
  | "paused"
  | "onTogglePause"
  | "thinking"
  | "onCancelTurn"
>) {
  const [open, setOpen] = useState(false);
  const [confirmCancel, setConfirmCancel] = useState(false);
  const anchorRef = useRef<HTMLDivElement>(null);

  function close() {
    setOpen(false);
    setConfirmCancel(false);
  }

  const options: DropdownOption[] = [
    { value: "toggle-pause", label: paused ? "▶ resume" : "⏸ pause" },
  ];
  if (thinking) {
    options.push({
      value: "cancel-turn",
      label: confirmCancel ? "■ click again to confirm" : "■ cancel turn",
      danger: true,
    });
  }

  return (
    <div class="status-chip-anchor" ref={anchorRef}>
      <Badge
        value={statusLabel}
        tone={statusTone}
        title={statusTooltip}
        onClick={() => setOpen((o) => !o)}
        expanded={open}
      />
      <Dropdown
        open={open}
        options={options}
        label="agent status"
        onSelect={(value) => {
          if (value === "toggle-pause") {
            onTogglePause();
            close();
            return;
          }
          // value === 'cancel-turn': first click arms it, second fires.
          if (!confirmCancel) {
            setConfirmCancel(true);
            return;
          }
          onCancelTurn();
          close();
        }}
        onClose={close}
        anchorRef={anchorRef}
      />
    </div>
  );
}

export function StatusChips({
  statusLabel,
  statusTone,
  statusTooltip,
  model,
  resolvedModel,
  availableModels,
  onSelectModel,
  effort,
  availableEfforts,
  onSelectEffort,
  ctxLabel,
  costLabel,
  paused,
  onTogglePause,
  lastTurnLabel,
  thinking,
  onCancelTurn,
}: StatusChipsProps) {
  return (
    <div class="status-chips">
      <StatusMenu
        statusLabel={statusLabel}
        statusTone={statusTone}
        statusTooltip={statusTooltip}
        paused={paused}
        onTogglePause={onTogglePause}
        thinking={thinking}
        onCancelTurn={onCancelTurn}
      />
      <Picker
        label="model"
        value={model}
        options={availableModels}
        descriptions={MODEL_DESCRIPTIONS}
        onSelect={onSelectModel}
        title={resolvedModel ? `resolved to ${resolvedModel}` : undefined}
      />
      {availableEfforts.length ? (
        <Picker
          label="effort"
          value={effort}
          options={availableEfforts}
          descriptions={EFFORT_DESCRIPTIONS}
          onSelect={onSelectEffort}
        />
      ) : null}
      {ctxLabel ? (
        <Badge
          label="ctx"
          value={ctxLabel}
          title="tokens used in the current context window"
        />
      ) : null}
      {costLabel ? (
        <Badge
          label="cost"
          value={costLabel}
          title="cumulative tokens billed across the last turn (sum across every inference; tool-heavy turns rebill the cached prompt per call)"
        />
      ) : null}
      {lastTurnLabel ? (
        <span class="status-chips-last-turn">{lastTurnLabel}</span>
      ) : null}
    </div>
  );
}
