import { markNativeReady, required, setText } from "./shared/shell.ts";
import { validatePayload, type CapabilityResult, type TypedPayload } from "./shared/capabilities.ts";

markNativeReady();

const payload: TypedPayload = {
  project: "Native TypeScript Lab",
  files: ["home.ts", "shell.ts", "capabilities.ts"],
  generation: 1,
};

const checks: CapabilityResult[] = [
  { id: "module", label: ".ts module evaluation", ok: true, detail: "import.meta evaluated directly by Chromium" },
  validatePayload(payload),
  { id: "dom", label: "DOM library types", ok: document instanceof Document, detail: "Document and Canvas APIs available" },
];

try {
  const module = await import("data:text/typescript,export%20const%20answer%3A%20number%20%3D%2042");
  checks.push({ id: "dynamic", label: "Dynamic TypeScript import", ok: module.answer === 42, detail: `data: module returned ${module.answer}` });
} catch (error) {
  checks.push({ id: "dynamic", label: "Dynamic TypeScript import", ok: false, detail: String(error) });
}

for (const result of checks) {
  const state = required<HTMLElement>(`[data-check="${result.id}"]`);
  state.textContent = result.ok ? "PASS" : "FAIL";
  state.classList.toggle("ok", result.ok);
  const detail = state.closest("li")?.querySelector<HTMLElement>("[data-check-detail]");
  if (detail) detail.textContent = result.detail;
}

setText("[data-metric-files]", String(payload.files.length));
setText("[data-metric-passes]", `${checks.filter((check) => check.ok).length}/${checks.length}`);
setText("[data-metric-answer]", checks[checks.length - 1]?.ok ? "42" : "ERR");

const canvas = required<HTMLCanvasElement>("#home-graph");
const context = canvas.getContext("2d")!;

interface NodePoint { x: number; y: number; vx: number; vy: number; color: string; label: string }
const nodes: NodePoint[] = payload.files.map((file, index) => ({
  x: 90 + index * 120,
  y: 120 + (index % 2) * 68,
  vx: .18 + index * .05,
  vy: index % 2 ? -.14 : .12,
  color: index === 0 ? "#ff645f" : index === 1 ? "#55d5dc" : "#b6df63",
  label: file,
}));

function resize(): void {
  const ratio = window.devicePixelRatio || 1;
  const rect = canvas.getBoundingClientRect();
  canvas.width = Math.round(rect.width * ratio);
  canvas.height = Math.round(rect.height * ratio);
  context.setTransform(ratio, 0, 0, ratio, 0, 0);
}

function draw(): void {
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  context.clearRect(0, 0, width, height);
  context.strokeStyle = "#344149";
  context.lineWidth = 1;
  for (let index = 1; index < nodes.length; index++) {
    context.beginPath();
    context.moveTo(nodes[0].x, nodes[0].y);
    context.lineTo(nodes[index].x, nodes[index].y);
    context.stroke();
  }
  for (const node of nodes) {
    node.x += node.vx;
    node.y += node.vy;
    if (node.x < 60 || node.x > width - 60) node.vx *= -1;
    if (node.y < 55 || node.y > height - 55) node.vy *= -1;
    context.fillStyle = node.color;
    context.fillRect(node.x - 6, node.y - 6, 12, 12);
    context.fillStyle = "#dce4e7";
    context.font = "12px ui-monospace, monospace";
    context.fillText(node.label, node.x + 14, node.y + 4);
  }
  requestAnimationFrame(draw);
}

resize();
window.addEventListener("resize", resize);
draw();
