import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { audit, loadTokens } from '../audit.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

function writeFile(root: string, rel: string, content: string): void {
  const abs = path.join(root, rel);
  mkdirSync(path.dirname(abs), { recursive: true });
  writeFileSync(abs, content, 'utf-8');
}

describe('R20-accent-overuse', () => {
  let tmpDir: string;

  beforeEach(() => {
    tmpDir = mkdtempSync(path.join(tmpdir(), 'ui-polish-r20-'));
  });

  afterEach(() => {
    rmSync(tmpDir, { recursive: true, force: true });
  });

  it('should FIRE — Pattern A: thick accent border on non-button div', async () => {
    writeFile(tmpDir, 'src/pages/test/TestPage.tsx', `
export function TestPage() {
  return (
    <div className="border-2 border-[var(--color-accent-500)] rounded-lg p-4">
      Card content
    </div>
  );
}
    `);

    const tokensFile = path.resolve(
      __dirname,
      '../../../tokens.json',
    );
    const tokens = await loadTokens(tokensFile);

    const report = await audit(
      { projectPath: tmpDir, mode: 'audit', rules: ['R20'], paths: [], urls: [], regenerateThreshold: 0 },
      tokens,
    );

    expect(report.findings).toHaveLength(1);
    const finding = report.findings[0];
    expect(finding.ruleId).toBe('R20-accent-overuse');
    expect(finding.severity).toBe('warning');
    expect(finding.message).toContain('Thick accent border');
    expect(finding.message).toContain('non-button');
  });

  it('should NOT FIRE — Pattern A: thick accent border on button (legitimate)', async () => {
    writeFile(tmpDir, 'src/pages/test/TestPage.tsx', `
export function TestPage() {
  return (
    <button className="border-2 border-[var(--color-accent-500)] rounded-lg px-4 py-2">
      Click me
    </button>
  );
}
    `);

    const tokensFile = path.resolve(
      __dirname,
      '../../../tokens.json',
    );
    const tokens = await loadTokens(tokensFile);

    const report = await audit(
      { projectPath: tmpDir, mode: 'audit', rules: ['R20'], paths: [], urls: [], regenerateThreshold: 0 },
      tokens,
    );

    expect(report.findings).toHaveLength(0);
  });

  it('should FIRE — Pattern B: pale accent as section background', async () => {
    writeFile(tmpDir, 'src/pages/test/TestPage.tsx', `
export function TestPage() {
  return (
    <section className="bg-[var(--color-accent-50)] p-6">
      <h2>Section title</h2>
    </section>
  );
}
    `);

    const tokensFile = path.resolve(
      __dirname,
      '../../../tokens.json',
    );
    const tokens = await loadTokens(tokensFile);

    const report = await audit(
      { projectPath: tmpDir, mode: 'audit', rules: ['R20'], paths: [], urls: [], regenerateThreshold: 0 },
      tokens,
    );

    expect(report.findings).toHaveLength(1);
    const finding = report.findings[0];
    expect(finding.ruleId).toBe('R20-accent-overuse');
    expect(finding.severity).toBe('warning');
    expect(finding.message).toContain('Pale accent');
    expect(finding.message).toContain('section');
  });

  it('should FIRE — Pattern C: full accent fill on non-button div', async () => {
    writeFile(tmpDir, 'src/pages/test/TestPage.tsx', `
export function TestPage() {
  return (
    <div className="bg-[var(--color-accent-600)] text-white p-4 rounded">
      Banner
    </div>
  );
}
    `);

    const tokensFile = path.resolve(
      __dirname,
      '../../../tokens.json',
    );
    const tokens = await loadTokens(tokensFile);

    const report = await audit(
      { projectPath: tmpDir, mode: 'audit', rules: ['R20'], paths: [], urls: [], regenerateThreshold: 0 },
      tokens,
    );

    expect(report.findings).toHaveLength(1);
    const finding = report.findings[0];
    expect(finding.ruleId).toBe('R20-accent-overuse');
    expect(finding.severity).toBe('warning');
    expect(finding.message).toContain('Full accent fill');
    expect(finding.message).toContain('non-button');
  });

  it('should NOT FIRE — Pattern C: full accent fill on button (legitimate CTA)', async () => {
    writeFile(tmpDir, 'src/pages/test/TestPage.tsx', `
export function TestPage() {
  return (
    <button className="bg-[var(--color-accent-600)] text-white px-4 py-2 rounded">
      Submit
    </button>
  );
}
    `);

    const tokensFile = path.resolve(
      __dirname,
      '../../../tokens.json',
    );
    const tokens = await loadTokens(tokensFile);

    const report = await audit(
      { projectPath: tmpDir, mode: 'audit', rules: ['R20'], paths: [], urls: [], regenerateThreshold: 0 },
      tokens,
    );

    expect(report.findings).toHaveLength(0);
  });
});
