import test from "node:test";
import assert from "node:assert/strict";
import { translate } from "../../shared/i18n.js";
import { accountSwitchAllowed, accountSwitchLockAccountId, accountSwitchLocked, chatProgressLabel, chatProgressTone, headerProject, lastChatProjectLabel } from "./context-state.js";

const workspaces = [
  { id: "alpha", label: "Alpha" },
  { id: "beta", label: "Beta" }
];

test("header project follows the open chat workspace", () => {
  assert.equal(headerProject({ workspaceId: "beta" }, workspaces[0], workspaces)?.label, "Beta");
});

test("header project prefers the current workspace label over a stale session label", () => {
  assert.equal(headerProject({ workspaceId: "beta", projectLabel: "Old project" }, workspaces[0], workspaces)?.label, "Beta");
});

test("header project keeps the session label for unknown-workspace history", () => {
  assert.equal(headerProject({ workspaceId: "missing", projectLabel: "Desktop project" }, workspaces[0], workspaces)?.label, "Desktop project");
});

test("header project stays empty without a last-used chat", () => {
  assert.equal(headerProject(null, workspaces[0], workspaces), undefined);
});

test("new chat header follows the selected project before its session exists", () => {
  assert.equal(headerProject(null, workspaces[1], workspaces, true)?.label, "Beta");
  assert.equal(headerProject({ workspaceId: "alpha" }, workspaces[1], workspaces, true)?.label, "Beta");
});

test("chat progress uses concise English status labels", () => {
  const t = (key) => translate("en", key);
  assert.equal(chatProgressLabel(null, t), "No chat selected");
  assert.equal(chatProgressLabel({ status: "opening" }, t), "Opening chat");
  assert.equal(chatProgressLabel({ status: "starting" }, t), "Starting");
  assert.equal(chatProgressLabel({ status: "running" }, t), "Working");
  assert.equal(chatProgressLabel({ status: "waiting_approval" }, t), "Waiting for approval");
  assert.equal(chatProgressLabel({ status: "waiting_response" }, t), "Waiting for response");
  assert.equal(chatProgressLabel({ status: "completed" }, t), "Answer complete");
  assert.equal(chatProgressLabel({ status: "failed" }, t), "Answer failed");
  assert.equal(chatProgressLabel({ status: "interrupted" }, t), "Interrupted");
});

test("chat progress and fallback project labels use selected language", () => {
  const t = (key) => translate("ko", key);

  assert.equal(chatProgressLabel(null, t), "선택한 채팅 없음");
  assert.equal(chatProgressLabel({ status: "starting" }, t), "시작 중");
  assert.equal(chatProgressLabel({ status: "running" }, t), "작업 중");
  assert.equal(chatProgressLabel({ status: "waiting_approval" }, t), "승인 대기 중");
  assert.equal(chatProgressLabel({ status: "waiting_response" }, t), "응답 대기 중");
  assert.equal(chatProgressLabel({ status: "completed" }, t), "답변 완료");
  assert.equal(chatProgressLabel({ status: "failed" }, t), "답변 실패");
  assert.equal(chatProgressLabel({ status: "interrupted" }, t), "중단됨");
  assert.equal(chatProgressLabel({ status: "idle" }, t), "준비됨");
  assert.equal(lastChatProjectLabel({ id: "s", workspaceId: "" }, undefined, t), "프로젝트 없음");
  assert.equal(lastChatProjectLabel(null, undefined, t), "최근 채팅 없음");
});

test("chat progress maps statuses to indicator tones", () => {
  assert.equal(chatProgressTone({ status: "completed" }), "complete");
  assert.equal(chatProgressTone({ status: "opening" }), "active");
  assert.equal(chatProgressTone({ status: "starting" }), "active");
  assert.equal(chatProgressTone({ status: "running" }), "active");
  assert.equal(chatProgressTone({ status: "waiting_approval" }), "active");
  assert.equal(chatProgressTone({ status: "waiting_response" }), "active");
  assert.equal(chatProgressTone({ status: "failed" }), "error");
  assert.equal(chatProgressTone({ status: "interrupted" }), "error");
  assert.equal(chatProgressTone({ status: "idle" }), "idle");
  assert.equal(chatProgressTone(null), "idle");
});

test("last chat project always has display text", () => {
  const t = (key) => translate("en", key);
  assert.equal(lastChatProjectLabel({ id: "s" }, { label: "Alpha" }), "Alpha");
  assert.equal(lastChatProjectLabel({ id: "s", workspaceId: "" }, undefined, t), "No project");
  assert.equal(lastChatProjectLabel({ id: "s", workspaceId: "" }, undefined, (key) => translate("ko", key)), "프로젝트 없음");
  assert.equal(lastChatProjectLabel(null, undefined, t), "No recent chat");
});

test("header project does not borrow selected workspace for an unassigned chat", () => {
  assert.equal(headerProject({ workspaceId: "" }, workspaces[0], workspaces), undefined);
});

test("account switching stays available while Codex sessions are active", () => {
  assert.equal(accountSwitchLocked([{ status: "running" }]), false);
  assert.equal(accountSwitchLocked([{ status: "waiting_approval" }]), false);
  assert.equal(accountSwitchLocked([{ status: "completed" }, { status: "interrupted" }]), false);
});

test("active chats do not impose an account selection lock", () => {
  const lockedAccountId = accountSwitchLockAccountId(
    [{ accountId: "stale-b", status: "running" }],
    { accountId: "account-a", status: "running" }
  );

  assert.equal(lockedAccountId, "");
  assert.equal(accountSwitchLocked([], { accountId: "account-a", status: "running" }), false);
  assert.equal(accountSwitchAllowed("account-a", "stale-b", lockedAccountId), true);
  assert.equal(accountSwitchAllowed("stale-b", "stale-b", lockedAccountId), true);
  assert.equal(accountSwitchAllowed("account-c", "stale-b", lockedAccountId), true);
});
