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

import { resolveSpeechLanguage, toBCP47 } from '../core/language';

describe('toBCP47', () => {
  it('maps known ISO-2 codes to canonical BCP-47', () => {
    expect(toBCP47('en')).toBe('en-US');
    expect(toBCP47('ru')).toBe('ru-RU');
    expect(toBCP47('ko')).toBe('ko-KR');
    expect(toBCP47('pt')).toBe('pt-BR');
    expect(toBCP47('no')).toBe('nb-NO');
  });

  it('resolves catalogue ISO codes to their canonical dialect', () => {
    // Not in the built-in table, but present in the Web Speech
    // catalogue — must resolve to a real region, never `uk-UK`/`cs-CS`.
    expect(toBCP47('uk')).toBe('uk-UA');
    expect(toBCP47('cs')).toBe('cs-CZ');
  });

  it('falls back to <code>-<UPPER(code)> for fully unknown ISO codes', () => {
    expect(toBCP47('xx')).toBe('xx-XX');
  });

  it('passes BCP-47 input through unchanged', () => {
    expect(toBCP47('en-GB')).toBe('en-GB');
    expect(toBCP47('zh-TW')).toBe('zh-TW');
  });

  it('returns undefined for empty / null', () => {
    expect(toBCP47(null)).toBeUndefined();
    expect(toBCP47(undefined)).toBeUndefined();
    expect(toBCP47('')).toBeUndefined();
    expect(toBCP47('   ')).toBeUndefined();
  });
});

describe('resolveSpeechLanguage', () => {
  it('priority: explicit beats everything', () => {
    expect(
      resolveSpeechLanguage({
        explicit: 'ko-KR',
        prefs: 'ru-RU',
        i18n: 'en',
      }),
    ).toBe('ko-KR');
  });

  it('priority: prefs beats i18n', () => {
    expect(resolveSpeechLanguage({ prefs: 'ru-RU', i18n: 'en' })).toBe('ru-RU');
  });

  it('priority: i18n beats navigator', () => {
    expect(resolveSpeechLanguage({ i18n: 'ru' })).toBe('ru-RU');
  });

  it('falls back to en-US when nothing supplied and no navigator', () => {
    expect(resolveSpeechLanguage({})).toMatch(/^[a-z]{2}-[A-Z]{2}$/);
  });

  it('normalises ISO-2 in any slot', () => {
    expect(resolveSpeechLanguage({ explicit: 'ru' })).toBe('ru-RU');
    expect(resolveSpeechLanguage({ prefs: 'ko' })).toBe('ko-KR');
  });
});
