import { describe, expect, it } from 'vitest';
import { liveDraftTiles, parseDraft, serializeDraft, validRackOrder } from './draft';
import type { PendingTile } from './placement';

describe('draft', () => {
  it('round-trips the rack order and board tiles', () => {
    const pending: PendingTile[] = [
      { rackIndex: 2, row: 7, col: 7, letter: 'Q', blank: false },
      { rackIndex: 0, row: 7, col: 8, letter: 'I', blank: true },
    ];
    const parsed = parseDraft(serializeDraft([3, 0, 1, 2], pending));
    expect(parsed).not.toBeNull();
    expect(parsed!.rackOrder).toEqual([3, 0, 1, 2]);
    expect(parsed!.tiles).toEqual([
      { row: 7, col: 7, letter: 'Q', blank: false },
      { row: 7, col: 8, letter: 'I', blank: true },
    ]);
  });

  it('parses an empty or malformed draft as null', () => {
    expect(parseDraft('')).toBeNull();
    expect(parseDraft('not json')).toBeNull();
  });

  it('parses a draft with no rack order or tiles', () => {
    expect(parseDraft(JSON.stringify({ rack_order: '', board_tiles: [] }))).toEqual({ rackOrder: [], tiles: [] });
  });

  it('accepts a valid rack permutation and rejects a stale one', () => {
    expect(validRackOrder([2, 0, 1], 3)).toEqual([2, 0, 1]);
    expect(validRackOrder([0, 1], 3)).toBeNull(); // wrong length (the rack changed)
    expect(validRackOrder([0, 0, 1], 3)).toBeNull(); // a duplicate, not a permutation
    expect(validRackOrder([0, 1, 3], 3)).toBeNull(); // an index out of range
  });

  it('drops draft tiles whose cell is now occupied', () => {
    const tiles = [
      { row: 7, col: 7, letter: 'A', blank: false },
      { row: 7, col: 8, letter: 'B', blank: false },
    ];
    expect(liveDraftTiles(tiles, (r, c) => r === 7 && c === 7)).toEqual([
      { row: 7, col: 8, letter: 'B', blank: false },
    ]);
  });
});
