import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";

import type { AdminAccessMatrixResponse, AdminAccessOpenFga, AdminAccessSummaryResponse, AdminAccessUser, AdminAccessUsersResponse } from "../src/types/index.ts";
import { normalizeAccessDetail, normalizeAccessSummary, normalizeAccessUsers } from "../src/stores/admin-access-view.ts";
import { mergeProviderRow, normalizeProviderConfig, normalizeProviderProfiles, normalizeProviderValidation } from "../src/stores/provider-profiles-view.ts";

const actor: AdminAccessUser = { id: "usr_admin", username: "admin", displayName: "Admin", role: "admin", status: "active" };
const user: AdminAccessUser = { id: "usr_1", username: "alice", displayName: "Alice", role: "user", status: "active" };
const openfga: AdminAccessOpenFga = { contractVersion: "hwlab-openfga-authorization-v1", mode: "enforce", configured: true, ready: true, status: "ready", apiUrlConfigured: true, storeName: "hwlab-v03", storeId: "sto…1234", modelId: "mod…1234", degradedReason: null, valuesRedacted: true };
const tools = { hwpod: true, unidesk_ssh: false, trans_cmd: false, github_pr: false };

test("R4 Access helpers map the fixed admin-access-v1 DTO", () => {
  const payload: AdminAccessSummaryResponse = { contractVersion: "admin-access-v1", actor, counts: { users: 3, tuples: 5, toolTuples: 4 }, openfga, supported: { toolIds: ["hwpod", "unidesk_ssh", "trans_cmd", "github_pr"] } };
  const summary = normalizeAccessSummary(payload);
  assert.equal(summary.users, 3);
  assert.equal(summary.toolTuples, 4);
  assert.deepEqual(summary.toolIds, ["hwpod", "unidesk_ssh", "trans_cmd", "github_pr"]);
  assert.equal(summary.openfga.ready, true);

  const usersPayload: AdminAccessUsersResponse = { contractVersion: "admin-access-v1", actor, openfga, users: [{ user, tools, tupleCount: 1 }], count: 1 };
  const users = normalizeAccessUsers(usersPayload);
  assert.equal(users.length, 1);
  assert.equal(users[0]?.id, "usr_1");
  assert.equal(users[0]?.toolCount, 1);
  assert.equal(users[0]?.tools.hwpod, true);
});

test("R4 Access detail maps tool object into toggles", () => {
  const detailPayload: AdminAccessMatrixResponse = { contractVersion: "admin-access-v1", actor, user, tools, tuples: [{ userId: "usr_1", relation: "can_use", object: "tool:hwpod", createdByAdminId: actor.id, createdAt: "2026-07-14T00:00:00.000Z" }], openfga };
  const detail = normalizeAccessDetail(detailPayload);
  assert.equal(detail.user?.id, "usr_1");
  assert.ok(detail.tools.some((tool) => tool.id === "hwpod" && tool.allowed));
  assert.ok(detail.tools.some((tool) => tool.id === "trans_cmd" && !tool.allowed));
  assert.equal(detail.tuples.length, 1);
});

test("ContentViewer keeps wrap available and hides maximize when fullscreen is disabled", () => {
  const source = readFileSync(new URL("../src/components/common/ContentViewer.vue", import.meta.url), "utf8");
  assert.match(source, /<button\s+class="icon-button"[\s\S]*?<WrapText/);
  assert.doesNotMatch(source, /<button\s+v-if="fullscreenEnabled"[\s\S]{0,240}<WrapText/);
  assert.match(source, /<button\s+v-if="fullscreenEnabled"[\s\S]{0,240}<Maximize2/);
  assert.match(source, /:open="fullscreenEnabled && fullscreen"/);
});

test("R4 Provider helpers accept Sub2API-style item envelopes", () => {
  const rows = normalizeProviderProfiles({ data: { items: [{ profile: "deepseek", configured: true, secretRef: { namespace: "agentrun-v02", name: "agentrun-v02-provider-deepseek", keys: ["auth.json", "config.toml"] }, credentialHashSuffix: "abc123", configHashSuffix: "def456", bridge: { route: "Moon Bridge -> DeepSeek" }, valuesPrinted: false }] } });
  assert.equal(rows.length, 1);
  assert.equal(rows[0]?.profile, "deepseek");
  assert.equal(rows[0]?.secretRefText, "agentrun-v02/agentrun-v02-provider-deepseek [auth.json,config.toml]");
  assert.equal(rows[0]?.credentialHashSuffix, "abc123");
  assert.equal(rows[0]?.valuesPrinted, false);
});

test("R4 Provider config and validation summaries stay redacted", () => {
  const config = normalizeProviderConfig({ data: { profile: "deepseek", configToml: "model = \"deepseek-chat\"", configHashSuffix: "cfg123", valuesPrinted: false } }, "deepseek");
  assert.equal(config.profile, "deepseek");
  assert.match(config.configToml, /deepseek-chat/);
  assert.equal(config.valuesPrinted, false);

  const validation = normalizeProviderValidation({ data: { validationId: "val_1", profile: "deepseek", status: "completed", runId: "run_1", commandId: "cmd_1", result: { terminalStatus: "completed", agentRun: { jobName: "agentrun-v02-runner" } }, valuesPrinted: false } }, "deepseek");
  assert.equal(validation.validationId, "val_1");
  assert.equal(validation.jobName, "agentrun-v02-runner");
  assert.equal(validation.valuesPrinted, false);
});

test("R4 Provider merge keeps updated profile and ordering", () => {
  const rows = normalizeProviderProfiles({ items: [{ profile: "custom" }, { profile: "deepseek", configured: false }] });
  const updated = normalizeProviderProfiles({ items: [{ profile: "deepseek", configured: true, credentialHashSuffix: "abc" }] })[0] ?? null;
  const merged = mergeProviderRow(rows, updated);
  assert.equal(merged[0]?.profile, "deepseek");
  assert.equal(merged[0]?.configured, true);
  assert.equal(merged.length, 2);
});
