import { describe, expect, it } from 'vitest';
import { LINES } from '../../engine/src/types';
import { BOARD_TEMPLATES } from '../src/board-templates';

const lineKey = (cells: readonly number[]) => [...cells].sort((a, b) => a - b).join(',');
const LINE_KEYS = new Set(LINES.map(lineKey));
const CORNERS = new Set([0, 2, 6, 8]);

describe('BOARD_TEMPLATES', () => {
  it('lists the 8 symmetries in engine order', () => {
    expect(BOARD_TEMPLATES.map((t) => [t.symmetry, t.key])).toEqual([
      [0, 'identity'],
      [1, 'rot90'],
      [2, 'rot180'],
      [3, 'rot270'],
      [4, 'mirror-lr'],
      [5, 'mirror-tb'],
      [6, 'transpose'],
      [7, 'anti-transpose'],
    ]);
  });

  it('uses permutation[p] = destination cell', () => {
    const byKey = Object.fromEntries(BOARD_TEMPLATES.map((t) => [t.key, t.permutation]));
    expect(byKey.identity).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8]);
    // rot90 (r,c) -> (c, 2-r): top-left corner goes to top-right.
    expect(byKey.rot90).toEqual([2, 5, 8, 1, 4, 7, 0, 3, 6]);
    expect(byKey.rot180).toEqual([8, 7, 6, 5, 4, 3, 2, 1, 0]);
    expect(byKey.rot270).toEqual([6, 3, 0, 7, 4, 1, 8, 5, 2]);
    expect(byKey['mirror-lr']).toEqual([2, 1, 0, 5, 4, 3, 8, 7, 6]);
    expect(byKey['mirror-tb']).toEqual([6, 7, 8, 3, 4, 5, 0, 1, 2]);
    expect(byKey.transpose).toEqual([0, 3, 6, 1, 4, 7, 2, 5, 8]);
    expect(byKey['anti-transpose']).toEqual([8, 5, 2, 7, 4, 1, 6, 3, 0]);
  });

  it('are distinct bijections that map lines to lines and keep position classes', () => {
    expect(new Set(BOARD_TEMPLATES.map((t) => t.permutation.join())).size).toBe(8);
    for (const t of BOARD_TEMPLATES) {
      expect([...t.permutation].sort((a, b) => a - b), t.key).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8]);
      for (const line of LINES) expect(LINE_KEYS.has(lineKey(line.map((p) => t.permutation[p]!))), t.key).toBe(true);
      expect(t.permutation[4]).toBe(4);
      for (const p of CORNERS) expect(CORNERS.has(t.permutation[p]!), t.key).toBe(true);
    }
  });
});
