import assert from "node:assert/strict";
import test from "node:test";

import { toEditorTabId } from "../state/activeTabStore.ts";
import type { EditorTab } from "../state/editorTabStore.ts";
import type { LogView } from "../state/logViewState.ts";
import { isActiveChromeThemeResolvable, resolveActiveChromeTheme } from "./activeChromeTheme.ts";
import type { Host, TerminalSession, TerminalTheme, Workspace } from "../../types";

const theme = (id: string, type: "dark" | "light" = "dark"): TerminalTheme => ({
  id,
  name: id,
  type,
  colors: {
    background: type === "dark" ? "#111111" : "#eeeeee",
    foreground: type === "dark" ? "#eeeeee" : "#111111",
    cursor: "#22aaff",
  },
});

const currentTheme = theme("current");
const hostTheme = theme("host-theme");
const logTheme = theme("log-theme", "light");

const baseInput = {
  accentMode: "theme" as const,
  currentTerminalTheme: currentTheme,
  customAccent: "221.2 83.2% 53.3%",
  editorTabs: [],
  followAppTerminalTheme: false,
  hostById: new Map<string, Host>(),
  logViews: [],
  sessionById: new Map<string, TerminalSession>(),
  themeById: new Map([
    [currentTheme.id, currentTheme],
    [hostTheme.id, hostTheme],
    [logTheme.id, logTheme],
  ]),
  workspaceById: new Map<string, Workspace>(),
};

test("editor tabs use the theme from their owning host", () => {
  const editorTab = {
    id: "editor-1",
    hostId: "host-1",
    sessionId: "sftp-1",
  };

  const resolved = resolveActiveChromeTheme({
    ...baseInput,
    activeTabId: toEditorTabId(editorTab.id),
    editorTabs: [editorTab as unknown as EditorTab],
    hostById: new Map([
      ["host-1", { id: "host-1", theme: hostTheme.id } as unknown as Host],
    ]),
  });

  assert.equal(resolved?.id, hostTheme.id);
});

test("log tabs use the saved log theme when available", () => {
  const resolved = resolveActiveChromeTheme({
    ...baseInput,
    activeTabId: "log-1",
    logViews: [{
      id: "log-1",
      connectionLogId: "1",
      log: { id: "1", themeId: logTheme.id },
    } as unknown as LogView],
  });

  assert.equal(resolved?.id, logTheme.id);
});

test("root pages use the normal application theme", () => {
  const resolved = resolveActiveChromeTheme({
    ...baseInput,
    activeTabId: "vault",
  });

  assert.equal(resolved, null);
});

test("chrome theme sync waits until a newly opened session is present in deps", () => {
  assert.equal(
    isActiveChromeThemeResolvable({
      activeTabId: "session-new",
      editorTabs: [],
      logViews: [],
      sessionById: new Map(),
      workspaceById: new Map(),
    }),
    false,
  );

  assert.equal(
    isActiveChromeThemeResolvable({
      activeTabId: "session-new",
      editorTabs: [],
      logViews: [],
      sessionById: new Map([["session-new", { id: "session-new" } as TerminalSession]]),
      workspaceById: new Map(),
    }),
    true,
  );
});
