import { describe, expect, it } from "vitest";
import { makeTokenDefinitionFact, type GovernanceConfig } from "@fragments-sdk/core";
import { scanWithFacts } from "./check.js";
import { applyFixes } from "./apply-fixes.js";

const policy: GovernanceConfig = {
  severity: "warn",
  rules: { "tokens/hardcoded-values": { enabled: true, severity: "warn" } },
  styles: [
    {
      kind: "style.rawColors.forbid",
      except: ["transparent", "currentColor", "inherit"],
      prefer: "token",
      severity: "warn",
    },
  ],
};

const tokens = [
  makeTokenDefinitionFact({ name: "--brand-600", value: "#2563eb", category: "color" }),
];

function conform(content: string, filePath = "snippet.scss") {
  const { findings } = scanWithFacts({
    facts: { governConfig: policy, tokens },
    files: [{ absPath: `/${filePath}`, relPath: filePath, content }],
  });
  return applyFixes({ filePath, source: content, findings });
}

describe("applyFixes — CSS value range", () => {
  it("replaces a single-line color value", () => {
    const { source, applied } = conform(".btn { color: #2563eb; }");
    expect(applied).toHaveLength(1);
    expect(source).toContain("var(--brand-600)");
    expect(source).not.toContain("#2563eb");
  });

  it("replaces a color whose value is wrapped onto the next line", () => {
    // Regression: the pre-value whitespace skip used to ignore newlines, which
    // collapsed the value range to zero width and left the raw color behind.
    const source = ".btn {\n  color:\n    #2563eb;\n}\n";
    const result = conform(source);
    expect(result.applied).toHaveLength(1);
    expect(result.source).toContain("var(--brand-600)");
    expect(result.source).not.toContain("#2563eb");
    expect(result.source).not.toMatch(/:var\([^)]*\)\s*#/);
  });

  it("preserves parenthesized values like rgb()", () => {
    const rgbTokens = [
      makeTokenDefinitionFact({
        name: "--brand-600",
        value: "rgb(37, 99, 235)",
        category: "color",
      }),
    ];
    const { findings } = scanWithFacts({
      facts: { governConfig: policy, tokens: rgbTokens },
      files: [
        {
          absPath: "/x.scss",
          relPath: "x.scss",
          content: ".x { color: rgb(37, 99, 235); }",
        },
      ],
    });
    const { source } = applyFixes({
      filePath: "x.scss",
      source: ".x { color: rgb(37, 99, 235); }",
      findings,
    });
    expect(source).toContain("var(--brand-600)");
    expect(source).not.toContain("rgb(37, 99, 235)");
  });
});
