import { expect, test } from "bun:test";
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
import { compileWireFile } from "@wrnexus/compiler";
import { mountHtml } from "@wrnexus/test";

const root = join(import.meta.dir, "..");
const frameworkVersion = JSON.parse(readFileSync(join(root, "package.json"), "utf8")).wrnexus
  .version as string;
const packagePages = join(root, "app", "pages", "packages");
const expected = [
  "ai",
  "authz",
  "cli",
  "compiler",
  "core",
  "csr",
  "db",
  "dev-server",
  "encryption",
  "helpers",
  "i18n",
  "jwt",
  "mobile",
  "native",
  "oauth",
  "pubsub",
  "queue",
  "reactive",
  "router",
  "ssr",
  "styles",
  "test",
  "tracking",
  "ui",
  "uploader",
  "validation",
];

test("generates one detailed page for every published package", () => {
  const generated = readdirSync(packagePages)
    .filter((file) => file.endsWith(".wrn"))
    .map((file) => file.replace(/\.wrn$/, ""))
    .sort();
  expect(generated).toEqual([...expected].sort());
});

test("every package page contains installation, guide, and complete API sections", () => {
  for (const name of expected) {
    const source = readFileSync(join(packagePages, `${name}.wrn`), "utf8");
    expect(source).toContain(`bun add @wrnexus/${name}@${frameworkVersion}`);
    expect(source).toContain('id="guide"');
    expect(source).toContain('id="api"');
    expect(source).toContain("Complete TypeScript API");
    expect(source).toContain('class="on-this-page"');
    expect(source).toContain('id="examples"');
    expect(source).toContain('class="example-card"');
  }
});

test("every package page shows multiple named usage examples", () => {
  for (const name of expected) {
    const source = readFileSync(join(packagePages, `${name}.wrn`), "utf8");
    expect(source.match(/class="example-card"/g)?.length ?? 0).toBeGreaterThanOrEqual(2);
    expect(source).not.toContain("<h3>Example 1</h3>");
    expect(source).not.toContain(`import * as packageApi from "@wrnexus/${name}"`);
  }
});

test("site includes core guides and production configuration", () => {
  for (const route of [
    "index.wrn",
    "packages.wrn",
    "getting-started.wrn",
    "language.wrn",
    "architecture.wrn",
  ]) {
    expect(existsSync(join(root, "app", "pages", route))).toBe(true);
  }
  expect(readFileSync(join(root, "wrnexus.config.ts"), "utf8")).toContain(
    "WRNexusJS Documentation",
  );
});

test("language reference covers directives, events, loops, and conditionals", () => {
  const source = readFileSync(join(root, "app", "pages", "language.wrn"), "utf8");
  for (const section of [
    "anatomy",
    "state",
    "server",
    "directives",
    "forms",
    "security",
    "errors",
  ]) {
    expect(source).toContain(`id="${section}"`);
  }
  expect(source).toContain("data-show");
  expect(source).toContain("mobile behavior");
});

test("portal exposes truthful access and machine discovery", () => {
  expect(readFileSync(join(root, "app", "pages", "index.wrn"), "utf8")).toContain(
    "Private Developer Preview",
  );
  expect(readFileSync(join(root, "app", "pages", "access.wrn"), "utf8")).toContain(
    "private registry credentials",
  );
  for (const asset of [
    "robots.txt",
    "sitemap.xml",
    "llms.txt",
    "llms-full.txt",
    "docs-index.json",
  ]) {
    expect(existsSync(join(root, "public", asset))).toBe(true);
  }

  const llms = readFileSync(join(root, "public", "llms.txt"), "utf8");
  expect(llms).toContain(`# WRNexusJS documentation ${frameworkVersion}`);
  expect(llms).toContain("# Installed package documentation");
  expect(llms).toContain("## @wrnexus/helpers");
  expect(llms).toContain("redirectToLogin");
});

test("workspace guide documents app addition and safe forward-auth redirects", () => {
  const source = readFileSync(
    join(root, "app", "pages", "guides", "workspaces-and-gateway.wrn"),
    "utf8",
  );
  expect(source).toContain("wrnexus workspace add reports --domain=reports.localhost");
  expect(source).toContain("@wrnexus/helpers");
  expect(source).toContain("redirectToLogin");
  expect(source).toContain("allowedHosts");
  expect(source).toContain("/api/verify");
});

test("package index includes searchable category filters", () => {
  const source = readFileSync(join(root, "app", "pages", "packages.wrn"), "utf8");
  expect(source).toContain('state category = "All"');
  expect(source).toContain("category = 'Security'");
  expect(source).toContain("category = 'Native'");
  expect(source).toContain("category === 'All'");
  expect(source).not.toContain("category === 'All' ||");
  expect(source).not.toContain(") && (query");
  expect(source.match(/class="package-card"/g)).toHaveLength(expected.length);
});

test("clicking a category hides packages from other categories", async () => {
  const source = readFileSync(join(root, "app", "pages", "packages.wrn"), "utf8");
  const directory = join(tmpdir(), "wrnexus-doc-tests");
  mkdirSync(directory, { recursive: true });
  const modulePath = join(directory, `packages-${Date.now()}.ts`);
  writeFileSync(modulePath, compileWireFile(source));
  const page = (await import(pathToFileURL(modulePath).href)).default as () => string;
  const mounted = mountHtml(page());
  const dataButton = mounted
    .querySelectorAll(".category-row button")
    .find((button) => button.textContent?.startsWith("Data"));
  expect(dataButton).toBeDefined();
  (dataButton as HTMLElement).click();
  const visible = mounted
    .querySelectorAll(".package-card")
    .filter((card) => (card as HTMLElement).style.display !== "none")
    .map((card) => card.getAttribute("href"));
  expect(visible).toEqual(["/packages/db", "/packages/queue", "/packages/uploader"]);
});
