/**
 * thinking-level.ts unit tests: the conversation-time pickers' short-name lookup and the
 * selectable list — both pickers offer only low/medium/high/xhigh (many models cannot disable
 * thinking; there is no "follow config" row — the session picker auto-follows the Agent
 * config by initializing its display to it), while "none" stays a displayable stored value;
 * "" (internally "untouched"/no override) and a legacy meta's "default" resolve to null so
 * callers substitute the config level or a placeholder.
 */
import { describe, expect, it } from "vitest";
import {
  SELECTABLE_THINKING_LEVELS,
  THINKING_LEVELS,
  effectiveThinkingLevel,
  thinkingLevelLabel,
  thinkingLevelOptionsFor,
} from "../src/features/chat/thinking-level";

/** Mirrors the shape of S.chat.thinkingLevelNames. */
const NAMES: Readonly<Record<string, string>> = {
  none: "None",
  low: "Low",
  medium: "Medium",
  high: "High",
  xhigh: "Extreme High",
};

describe("thinking level lists", () => {
  it("offers only low/medium/high/xhigh — no 'none' (many models cannot disable thinking)", () => {
    expect(SELECTABLE_THINKING_LEVELS).toEqual(["low", "medium", "high", "xhigh"]);
    expect(SELECTABLE_THINKING_LEVELS).not.toContain("none");
  });

  it("keeps all five stored levels displayable (a legacy 'none' is shown, never offered)", () => {
    expect(THINKING_LEVELS).toEqual(["none", "low", "medium", "high", "xhigh"]);
    expect(THINKING_LEVELS.map((l) => thinkingLevelLabel(NAMES, l))).toEqual([
      "None",
      "Low",
      "Medium",
      "High",
      "Extreme High",
    ]);
  });
});

describe("thinkingLevelLabel", () => {
  it("returns null for non-levels: '' (untouched/no override), a legacy meta's 'default', unknown, null", () => {
    expect(thinkingLevelLabel(NAMES, "")).toBeNull();
    expect(thinkingLevelLabel(NAMES, "default")).toBeNull();
    expect(thinkingLevelLabel(NAMES, "ultra")).toBeNull();
    expect(thinkingLevelLabel(NAMES, null)).toBeNull();
    expect(thinkingLevelLabel(NAMES, undefined)).toBeNull();
  });

  it("falls back to the raw value if the name table misses a level (defensive)", () => {
    expect(thinkingLevelLabel({}, "medium")).toBe("medium");
  });
});

describe("effectiveThinkingLevel (draft picker display — mirrors core agent.ts)", () => {
  it("resolves Agent explicit > project default_chat > built-in medium, the same chain core applies", () => {
    // Agent's explicit level always wins — including over a set project default.
    expect(effectiveThinkingLevel("high", "low")).toBe("high");
    expect(effectiveThinkingLevel("none", "low")).toBe("none"); // a stored legacy "none" is explicit too
    // No explicit agent level ("") -> the project default.
    expect(effectiveThinkingLevel("", "low")).toBe("low");
    // Neither -> the built-in "medium" (the documented Agent default).
    expect(effectiveThinkingLevel("", undefined)).toBe("medium");
  });
});

describe("thinkingLevelOptionsFor (agent-settings dropdown assembly)", () => {
  /** Mirrors the shape of S.agent.thinkingLevelOptions after the none row's removal. */
  const OPTIONS: ReadonlyArray<readonly [string, string]> = [
    ["", "Send no override."],
    ["low", "Low tier."],
    ["medium", "Medium tier."],
    ["high", "High tier."],
    ["xhigh", "Extra-high tier."],
  ];

  it("filters the '' inherit row and keeps dictionary order; no none row normally", () => {
    for (const stored of [undefined, "", "medium", "xhigh"]) {
      const rows = thinkingLevelOptionsFor(OPTIONS, "legacy none", stored);
      expect(rows.map((r) => r.value)).toEqual(["low", "medium", "high", "xhigh"]);
      expect(rows.some((r) => r.value === "none")).toBe(false);
      expect(rows[0]).toMatchObject({
        triggerLabel: "low",
        label: "low",
        description: "Low tier.",
      });
    }
  });

  it("appends a display-only none row when the persisted config stores none (backward compat)", () => {
    const rows = thinkingLevelOptionsFor(OPTIONS, "legacy none", "none");
    expect(rows.map((r) => r.value)).toEqual(["low", "medium", "high", "xhigh", "none"]);
    expect(rows.at(-1)).toEqual({
      value: "none",
      triggerLabel: "none",
      label: "none",
      description: "legacy none",
    });
  });
});
