import { describe, expect, it } from 'vitest';
import {
  IdempotencyKeySchema,
  LineIndexSchema,
  NicknameInputSchema,
  OptionIdSchema,
  PositionSchema,
  PowerUpTypeSchema,
  TeamNameInputSchema,
  UuidSchema,
  VenueCodeSchema,
} from '../src';
import { uuid } from './fixtures';

describe('UuidSchema', () => {
  it('accepts RFC UUIDs (including crypto.randomUUID output)', () => {
    expect(UuidSchema.safeParse(uuid(1)).success).toBe(true);
    expect(UuidSchema.safeParse(crypto.randomUUID()).success).toBe(true);
  });

  it.each(['', 'not-a-uuid', '00000000-0000-4000-8000-00000000000', '00000000-0000-4000-8000-00000000000g', 42])(
    'rejects %j',
    (value) => {
      expect(UuidSchema.safeParse(value).success).toBe(false);
    },
  );
});

describe('IdempotencyKeySchema', () => {
  it('accepts a UUID and 8-64 chars of [A-Za-z0-9_-]', () => {
    for (const key of [crypto.randomUUID(), 'abcdefgh', 'A_b-9'.padEnd(64, 'x')]) {
      expect(IdempotencyKeySchema.safeParse(key).success, key).toBe(true);
    }
  });

  it('rejects short, long and non-token keys', () => {
    for (const key of ['short', 'x'.repeat(65), 'has space1', 'semi;colon', 'ünïcode123']) {
      expect(IdempotencyKeySchema.safeParse(key).success, key).toBe(false);
    }
  });
});

describe('PositionSchema', () => {
  it('accepts 0..8', () => {
    for (let p = 0; p <= 8; p++) expect(PositionSchema.safeParse(p).success).toBe(true);
  });

  it.each([9, -1, 1.5, '4', Number.NaN])('rejects %j', (value) => {
    expect(PositionSchema.safeParse(value).success).toBe(false);
  });
});

describe('small primitives', () => {
  it('line index is 0..7', () => {
    expect(LineIndexSchema.safeParse(7).success).toBe(true);
    expect(LineIndexSchema.safeParse(8).success).toBe(false);
  });

  it('option ids are 1-8 chars', () => {
    expect(OptionIdSchema.safeParse('a').success).toBe(true);
    expect(OptionIdSchema.safeParse('').success).toBe(false);
    expect(OptionIdSchema.safeParse('abcdefghi').success).toBe(false);
  });

  it('venue codes are 2-12 alphanumerics', () => {
    expect(VenueCodeSchema.safeParse('DEMO').success).toBe(true);
    expect(VenueCodeSchema.safeParse('ab12CD34ef56').success).toBe(true);
    for (const code of ['D', 'ABCDEFGHIJKLM', 'DE-MO', 'DE MO']) {
      expect(VenueCodeSchema.safeParse(code).success, code).toBe(false);
    }
  });

  it('raw nicknames are 1-40 chars before normalisation', () => {
    expect(NicknameInputSchema.safeParse('M').success).toBe(true);
    expect(NicknameInputSchema.safeParse('  Mike  ').success).toBe(true);
    expect(NicknameInputSchema.safeParse('').success).toBe(false);
    expect(NicknameInputSchema.safeParse('x'.repeat(41)).success).toBe(false);
  });

  it('team name input allows null and blank (no team) but caps length', () => {
    expect(TeamNameInputSchema.safeParse(null).success).toBe(true);
    expect(TeamNameInputSchema.safeParse('').success).toBe(true);
    expect(TeamNameInputSchema.safeParse('x'.repeat(41)).success).toBe(false);
  });

  it('power-up types mirror the engine', () => {
    expect(PowerUpTypeSchema.options).toEqual(['DOUBLE_DOWN', 'SECOND_CHANCE', 'CATEGORY_SWAP']);
    expect(PowerUpTypeSchema.safeParse('TRIPLE_DOWN').success).toBe(false);
  });
});
