/**
 * dev-ui-023.test.ts — modern form controls must use the theme-compliant
 * primitives (DateInput / EnumSelect / MultiSelect), not native HTML controls.
 * Dev-pipeline twin of ui-polish R26; WARNING (non-blocking, anti-gate).
 * FK <select> is DEV-UI-022's domain (ERROR) and is skipped here.
 */
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 { audit } from '../audit.js';

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');
}

function baseArgs(projectPath: string) {
  return {
    projectPath,
    mode: 'audit' as const,
    moduleCode: 'hr',
    appCode: 'core',
    rules: ['DEV-UI-023'],
    regenerateThreshold: 0,
  };
}

const PAGE_NATIVE_DATE = `
export function EmployeeFormPage() {
  const formData = { hireDate: '' };
  return (<form><input id="hireDate" type="date" value={formData.hireDate} onChange={() => {}} /></form>);
}
`;

const PAGE_NATIVE_SELECT = `
export function EmployeeFormPage() {
  const formData = { status: '' };
  return (
    <form>
      <select value={formData.status} onChange={() => {}}>
        <option value="active">active</option>
      </select>
    </form>
  );
}
`;

const PAGE_NATIVE_MULTISELECT = `
export function EmployeeFormPage() {
  const formData = { skills: [] as string[] };
  return (
    <form>
      <select multiple value={formData.skills} onChange={() => {}}>
        <option value="ts">TS</option>
      </select>
    </form>
  );
}
`;

const PAGE_FK_SELECT = `
export function EmployeeFormPage() {
  const formData = { departmentId: '' };
  return (
    <form>
      <select value={formData.departmentId} onChange={() => {}}>
        <option value="">--</option>
      </select>
    </form>
  );
}
`;

const PAGE_PRIMITIVES = `
import { DateInput } from '@/components/ui/DateInput';
import { EnumSelect } from '@/components/ui/EnumSelect';
export function EmployeeFormPage() {
  const formData = { hireDate: null as string | null, status: null as string | null };
  return (
    <form>
      <DateInput value={formData.hireDate} onChange={() => {}} label="Hire date" />
      <EnumSelect options={[]} value={formData.status} onChange={() => {}} label="Status" />
    </form>
  );
}
`;

describe('audit-dev-frontend / DEV-UI-023 — modern form-control primitives', () => {
  let root: string;
  beforeEach(() => { root = mkdtempSync(path.join(tmpdir(), 'audit-dev-ui-023-')); });
  afterEach(() => { rmSync(root, { recursive: true, force: true }); });

  it('flags a native <input type="date"> (WARNING) and recommends DateInput', async () => {
    writeFile(root, 'src/pages/hr/employees/EmployeeFormPage.tsx', PAGE_NATIVE_DATE);
    const report = await audit(baseArgs(root));
    const warns = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'warn');
    expect(warns.length).toBe(1);
    expect(warns[0].solution).toMatch(/DateInput/);
  });

  it('flags a native <select> (WARNING) and recommends EnumSelect', async () => {
    writeFile(root, 'src/pages/hr/employees/EmployeeFormPage.tsx', PAGE_NATIVE_SELECT);
    const report = await audit(baseArgs(root));
    const warns = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'warn');
    expect(warns.length).toBe(1);
    expect(warns[0].solution).toMatch(/EnumSelect/);
  });

  it('flags a native <select multiple> (WARNING) and recommends MultiSelect', async () => {
    writeFile(root, 'src/pages/hr/employees/EmployeeFormPage.tsx', PAGE_NATIVE_MULTISELECT);
    const report = await audit(baseArgs(root));
    const warns = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'warn');
    expect(warns.length).toBe(1);
    expect(warns[0].solution).toMatch(/MultiSelect/);
  });

  it('does NOT flag an FK <select value={formData.xxxId}> (DEV-UI-022 owns it)', async () => {
    writeFile(root, 'src/pages/hr/employees/EmployeeFormPage.tsx', PAGE_FK_SELECT);
    const report = await audit(baseArgs(root));
    const warns = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'warn');
    expect(warns.length).toBe(0);
  });

  it('passes (ok) when the page already uses DateInput / EnumSelect', async () => {
    writeFile(root, 'src/pages/hr/employees/EmployeeFormPage.tsx', PAGE_PRIMITIVES);
    const report = await audit(baseArgs(root));
    const warns = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'warn');
    const oks = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'ok');
    expect(warns.length).toBe(0);
    expect(oks.length).toBeGreaterThan(0);
  });

  it('returns ok with note when there are no form pages on disk', async () => {
    const report = await audit(baseArgs(root));
    const oks = report.findings.filter((f) => f.code === 'DEV-UI-023' && f.severity === 'ok');
    expect(oks.length).toBe(1);
    expect(oks[0].params.note).toBe('no form pages on disk');
  });
});
