import test from "node:test";
import assert from "node:assert/strict";
import { formatContextUsage, formatRateWindow, formatUsageError, initialUsageStatus, lastConversationAccountName, rateLimitTone, reduceUsageStatus, statusOwnerId, visibleTokenUsage } from "./status-state.js";

test("formats compact primary and weekly reset values", () => {
  const now = new Date(2026, 5, 30, 10, 0);
  assert.equal(formatRateWindow({ remainingPercent: 7, resetsAt: new Date(2026, 5, 30, 12, 14).toISOString() }, "primary", now), "7% left · 12:14 PM");
  assert.equal(formatRateWindow({ remainingPercent: 7, resetsAt: new Date(2026, 5, 30, 0, 14).toISOString() }, "primary", now), "7% left · 12:14 AM");
  assert.equal(formatRateWindow({ remainingPercent: 42, resetsAt: new Date(2026, 5, 30, 14, 20).toISOString() }, "weekly", now), "42% left · 4h 20m");
  assert.equal(formatRateWindow({ remainingPercent: 42, resetsAt: new Date(2026, 6, 3, 10, 0).toISOString() }, "weekly", now), "42% left · Jul 3");
  assert.equal(formatRateWindow({ remainingPercent: 43, resetsAt: null }, "primary", now), "43% left · Unavailable");
});

test("colors remaining limits by threshold", () => {
  assert.equal(rateLimitTone({ remainingPercent: 50 }), "usage-good");
  assert.equal(rateLimitTone({ remainingPercent: 49 }), "usage-warning");
  assert.equal(rateLimitTone({ remainingPercent: 20 }), "usage-warning");
  assert.equal(rateLimitTone({ remainingPercent: 19 }), "usage-low");
  assert.equal(rateLimitTone(null), "");
});

test("formats verified context usage", () => {
  assert.equal(formatContextUsage({ totalTokens: 1200, contextWindow: 4000, usedPercent: 30, remainingPercent: 70 }), "70% left");
  assert.equal(formatContextUsage({ totalTokens: 1200, contextWindow: 4000, usedPercent: 30, remainingPercent: 70 }, "ko"), "70% 남음");
});

test("does not synthesize context remaining from legacy cumulative usage", () => {
  assert.equal(formatContextUsage({ totalTokens: 10000, contextWindow: 4000, usedPercent: 100 }), "Unavailable");
});

test("formats missing usage as unavailable", () => {
  assert.equal(formatRateWindow(null), "Unavailable");
  assert.equal(formatRateWindow(null, "primary", new Date(), "ko"), "사용할 수 없음");
  assert.equal(formatContextUsage(null), "Unavailable");
  assert.equal(formatContextUsage(null, "ko"), "사용할 수 없음");
});

test("formats login-required usage errors clearly", () => {
  assert.equal(formatUsageError("account_login_required"), "Login required");
  assert.equal(formatUsageError("account_login_required", "ko"), "로그인 필요");
  assert.equal(formatUsageError("pc_unreachable"), "PC app offline");
  assert.equal(formatUsageError("pc_unreachable", "ko"), "PC 앱 오프라인");
  assert.equal(formatUsageError("request_failed"), "Unavailable");
  assert.equal(formatUsageError("request_failed", "ko"), "사용할 수 없음");
  assert.equal(formatUsageError(""), "");
});

test("usage status failure preserves the last successful usage", () => {
  const usage = { primary: { remainingPercent: 55 }, secondary: { remainingPercent: 80 } };
  const loading = reduceUsageStatus({ usage, loading: false, error: "" }, { type: "loading" });
  const failed = reduceUsageStatus(loading, { type: "failed" });

  assert.deepEqual(loading, { usage, loading: true, error: "" });
  assert.deepEqual(failed, { usage, loading: false, error: "usage_unavailable" });
});

test("background usage refresh keeps the last values visible without a loading flash", () => {
  const current = { usage: { primary: { remainingPercent: 55 } }, loading: false, error: "", resetPending: false, resetError: "" };

  assert.equal(reduceUsageStatus(current, { type: "loading", silent: true }), current);
});

test("usage status can preserve the offline failure code", () => {
  const failed = reduceUsageStatus(initialUsageStatus, { type: "failed", error: "pc_unreachable" });

  assert.equal(failed.error, "pc_unreachable");
});

test("reset-credit actions preserve usage and update pending state", () => {
  const usage = { primary: { remainingPercent: 5 }, resetCreditsAvailable: 2 };
  const pending = reduceUsageStatus({ usage, loading: false, error: "", resetPending: false, resetError: "" }, { type: "reset_credit_pending" });
  const failed = reduceUsageStatus(pending, { type: "reset_credit_failed", error: "noCredit" });

  assert.deepEqual(pending, { usage, loading: false, error: "", resetPending: true, resetError: "" });
  assert.deepEqual(failed, { usage, loading: false, error: "", resetPending: false, resetError: "noCredit" });
});

test("selected account drives usage status even when a session is open", () => {
  assert.equal(statusOwnerId({ accountId: "desktop" }, "a"), "a");
  assert.equal(statusOwnerId(null, "a"), "a");
});

test("context usage is shown only for the selected account session", () => {
  const tokenUsage = { totalTokens: 1200, contextWindow: 4000, usedPercent: 30 };
  assert.equal(visibleTokenUsage({ accountId: "a", tokenUsage }, "a"), tokenUsage);
  assert.equal(visibleTokenUsage({ accountId: "a", tokenUsage }, "b"), null);
  assert.equal(visibleTokenUsage(null, "a"), null);
});

test("last conversation account uses the session owner instead of the selected account", () => {
  const accounts = [
    { id: "a", label: "Personal" },
    { id: "b", displayName: "Work Account" }
  ];

  assert.equal(lastConversationAccountName({ accountId: "a", codexThreadId: "thread-a" }, accounts), "Personal");
  assert.equal(lastConversationAccountName({ accountId: "b", codexThreadId: "thread-b" }, accounts), "Work Account");
  assert.equal(lastConversationAccountName({ accountId: "a" }, accounts), "None");
  assert.equal(lastConversationAccountName(null, accounts), "None");
  assert.equal(lastConversationAccountName(null, accounts, "ko"), "없음");
});
