import { describe, expect, it } from "vitest";

import { factId } from "@fragments-sdk/core";

import { parseClass } from "../parse-class.js";

const FILE = "src/fuzz.tsx";
const NODE_ID = factId("usage_node", {
  file: FILE,
  nodePath: "0:0",
  element: "div",
});
const LOCATION = { file: FILE, line: 1, column: 0 };

const PARTS = [
  "",
  "bg-red-500",
  "m-[15%]",
  "dark:hover:!bg-red-500/50",
  "[&>div]:p-4",
  "data-[state=open]:opacity-100",
  "aria-[expanded=true]:block",
  "group-hover:text-blue-500",
  "bg-(--my-color)",
  "-mx-4",
  "![bad",
  "hover:",
  "::::",
  "p-[calc(100%-theme(spacing.2))]",
  "text-[rgb(10,20,30)]",
  "@md/card:grid-cols-2",
  String.raw`weird\:\[\]`,
];

function randomString(seed: number): string {
  let state = seed >>> 0;
  const next = () => {
    state = (state * 1664525 + 1013904223) >>> 0;
    return state;
  };

  const count = 1 + (next() % 5);
  const out: string[] = [];
  for (let i = 0; i < count; i++) {
    const part = PARTS[next() % PARTS.length];
    if (part) out.push(part);
    const noiseLength = next() % 8;
    let noise = "";
    for (let j = 0; j < noiseLength; j++) {
      const chars = "abcdefghijklmnopqrstuvwxyz0123456789-_:[]()/%#&>@!";
      noise += chars[next() % chars.length];
    }
    if (noise) out.push(noise);
  }
  return out.join(next() % 2 === 0 ? ":" : "");
}

describe("parseClass fuzz — ACCEPTANCE §2.17", () => {
  it("returns a tailwind_class fact for 10K varied strings and never throws", () => {
    let unknown = 0;

    for (let i = 0; i < 10_000; i++) {
      const fact = parseClass({
        raw: randomString(i + 1),
        file: FILE,
        nodeId: NODE_ID,
        originPath: `fuzz#${i}`,
        location: LOCATION,
      });
      expect(fact.kind).toBe("tailwind_class");
      if (fact.utility === "unknown") unknown++;
    }

    expect(unknown).toBeGreaterThan(0);
    expect(unknown).toBeLessThan(10_000);
  });
});
