import { formatDuration, markNativeReady, required } from "./shared/shell.ts";

markNativeReady();
type PackageGroup = "utilities" | "frameworks";
interface PackageProbe { id: string; title: string; description: string; group: PackageGroup; run: () => Promise<string> }

const probes: PackageProbe[] = [
  { id: "lodash", title: "lodash-es", description: "Typed collection transforms", group: "utilities", run: async () => { const { chunk } = await import("npm:lodash-es"); return JSON.stringify(chunk([1, 2, 3, 4, 5, 6], 2)); } },
  { id: "zod", title: "zod", description: "Runtime schema validation", group: "utilities", run: async () => { const { z } = await import("npm:zod"); return JSON.stringify(z.object({ port: z.number().int() }).parse({ port: 8788 })); } },
  { id: "date", title: "date-fns", description: "Immutable date utilities", group: "utilities", run: async () => { const { format, addDays } = await import("npm:date-fns"); return format(addDays(new Date("2026-07-13T00:00:00Z"), 9), "yyyy-MM-dd"); } },
  { id: "nanoid", title: "nanoid", description: "Compact secure identifiers", group: "utilities", run: async () => { const { nanoid } = await import("npm:nanoid"); return `id:${nanoid(12)}`; } },
  { id: "uuid", title: "uuid", description: "Standards-based UUID generation", group: "utilities", run: async () => { const { v5 } = await import("npm:uuid"); return v5("native-typescript", v5.URL); } },
  { id: "rxjs", title: "rxjs", description: "Typed reactive streams", group: "utilities", run: async () => { const { of, map, filter, toArray, firstValueFrom } = await import("npm:rxjs"); return JSON.stringify(await firstValueFrom(of(2, 5, 8, 11).pipe(map((n: number) => n * 3), filter((n: number) => n > 15), toArray()))); } },
  { id: "react", title: "react", description: "Element and component model", group: "frameworks", run: async () => { const React = await import("npm:react"); const node = React.createElement("strong", { title: "typed" }, "Native TS"); return `isValidElement=${React.isValidElement(node)} type=${String(node.type)}`; } },
  { id: "next", title: "next", description: "Navigation utility surface", group: "frameworks", run: async () => { const { ReadonlyURLSearchParams } = await import("npm:next/navigation"); const params = new ReadonlyURLSearchParams(new URLSearchParams("mode=native&file=ts")); return `mode=${params.get("mode")} file=${params.get("file")}`; } },
  { id: "vue", title: "vue", description: "Fine-grained reactive state", group: "frameworks", run: async () => { const { reactive, computed } = await import("npm:vue"); const state = reactive({ files: 4, diagnostics: 1 }); const healthy = computed(() => state.files - state.diagnostics); state.files += 2; return `resolved=${healthy.value} / files=${state.files}`; } },
  { id: "angular", title: "@angular/core", description: "Signal-based state primitive", group: "frameworks", run: async () => { const { signal, computed } = await import("npm:@angular/core"); const files = signal(3); const nodes = computed(() => files() * 4); files.set(5); return `files=${files()} graphNodes=${nodes()}`; } },
  { id: "svelte", title: "svelte", description: "Reactive collection primitives", group: "frameworks", run: async () => { const { SvelteSet } = await import("npm:svelte/reactivity"); const files = new SvelteSet(["entry.ts", "model.ts"]); files.add("view.ts"); return `sources=${[...files].join(", ")}`; } },
];

for (const probe of probes) {
  const parent = required<HTMLElement>(`[data-package-group="${probe.group}"]`);
  const card = document.createElement("article");
  card.className = "package-card";
  card.innerHTML = `<div class="package-top"><div><h3>${probe.title}</h3><p>${probe.description}</p></div><span class="status-dot" aria-hidden="true"></span></div><div class="package-result">Not loaded</div><button class="small-button">▶ Run npm:${probe.title}</button>`;
  const result = required<HTMLElement>(".package-result", card);
  const dot = required<HTMLElement>(".status-dot", card);
  const button = required<HTMLButtonElement>("button", card);
  button.addEventListener("click", async () => {
    button.disabled = true;
    result.textContent = "Resolving from approved container...";
    dot.className = "status-dot";
    const started = performance.now();
    try {
      result.textContent = `${await probe.run()}\n${formatDuration(performance.now() - started)}`;
      dot.className = "status-dot ok";
    } catch (error) {
      result.textContent = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
      dot.className = "status-dot error";
    } finally { button.disabled = false; }
  });
  parent.append(card);
}
