import { describe, it, expect } from 'vitest';

import {
  ALL_VARIANTS,
  DEFAULT_VARIANTS,
  availableVariants,
  showRegisterHint,
  supportsMultipleWordsToggle,
  multipleWordsForRequest,
  usesStarBlank,
  BLANK_STAR,
} from './variants';

describe('ALL_VARIANTS', () => {
  it('lists variants Erudit-first', () => {
    expect(ALL_VARIANTS.map((v) => v.id)).toEqual(['erudit_ru', 'scrabble_ru', 'scrabble_en']);
  });
});

describe('availableVariants', () => {
  it('falls back to the Erudit-only default for an empty or absent preference set', () => {
    const fallback = ALL_VARIANTS.filter((v) => DEFAULT_VARIANTS.includes(v.id));
    expect(fallback.map((v) => v.id)).toEqual(['erudit_ru']);
    expect(availableVariants([])).toEqual(fallback);
    expect(availableVariants(undefined)).toEqual(fallback);
  });

  it('offers only the preferred variants', () => {
    expect(availableVariants(['scrabble_en']).map((v) => v.id)).toEqual(['scrabble_en']);
    expect(availableVariants(['erudit_ru', 'scrabble_en']).map((v) => v.id)).toEqual(['erudit_ru', 'scrabble_en']);
  });

  it('keeps the Erudit-first catalogue order regardless of preference order', () => {
    expect(availableVariants(['scrabble_en', 'erudit_ru', 'scrabble_ru']).map((v) => v.id)).toEqual([
      'erudit_ru',
      'scrabble_ru',
      'scrabble_en',
    ]);
  });
});

describe('showRegisterHint', () => {
  it('invites only an online guest holding a single variant', () => {
    expect(showRegisterHint(true, 1, false)).toBe(true);
  });

  it('stays hidden for a registered player, offline, or when several variants are offered', () => {
    expect(showRegisterHint(false, 1, false)).toBe(false);
    expect(showRegisterHint(true, 1, true)).toBe(false);
    expect(showRegisterHint(true, 2, false)).toBe(false);
  });
});

describe('supportsMultipleWordsToggle', () => {
  it('is true for Russian variants only', () => {
    expect(supportsMultipleWordsToggle('scrabble_ru')).toBe(true);
    expect(supportsMultipleWordsToggle('erudit_ru')).toBe(true);
    expect(supportsMultipleWordsToggle('scrabble_en')).toBe(false);
  });
});

describe('multipleWordsForRequest', () => {
  it('carries the toggle for Russian games', () => {
    expect(multipleWordsForRequest('scrabble_ru', false)).toBe(false);
    expect(multipleWordsForRequest('scrabble_ru', true)).toBe(true);
    expect(multipleWordsForRequest('erudit_ru', false)).toBe(false);
  });

  it('forces standard (true) for English whatever the toggle', () => {
    expect(multipleWordsForRequest('scrabble_en', false)).toBe(true);
    expect(multipleWordsForRequest('scrabble_en', true)).toBe(true);
  });
});

describe('usesStarBlank', () => {
  it('marks the blank with a star for Erudit only', () => {
    expect(usesStarBlank('erudit_ru')).toBe(true);
    expect(usesStarBlank('scrabble_ru')).toBe(false);
    expect(usesStarBlank('scrabble_en')).toBe(false);
  });

  it('BLANK_STAR is the heavy teardrop-spoked asterisk (U+273B)', () => {
    expect(BLANK_STAR).toBe('✻');
    expect(BLANK_STAR.codePointAt(0)).toBe(0x273b);
  });
});
