/**
 * Testes do sistema de i18n (M9.8).
 *
 * Cobre dicionário, interpolação, detecção de browser locale,
 * persistência localStorage e o LanguageSwitcher.
 */

import { describe, it, expect, beforeEach } from 'vitest';
import {
  t,
  listKeys,
  detectBrowserLocale,
  loadStoredLocale,
  saveStoredLocale,
  supportedLocales,
  DEFAULT_LOCALE,
  type Locale,
} from '../i18n';

describe('M9.8 — Dicionário de traduções', () => {
  it('Possui mais de 100 chaves', () => {
    expect(listKeys().length).toBeGreaterThan(100);
  });

  it('Todas as chaves têm tradução em pt-BR e en-US', () => {
    const keys = listKeys();
    for (const key of keys) {
      // Não podemos verificar diretamente, mas t() sempre retorna string
      expect(t(key, 'pt-BR')).not.toBe('');
      expect(t(key, 'en-US')).not.toBe('');
    }
  });

  it('Chaves pt-BR e en-US têm conteúdo diferente quando apropriado', () => {
    expect(t('nav_home', 'pt-BR')).not.toBe(t('nav_home', 'en-US'));
    expect(t('nav_warehouse', 'pt-BR')).not.toBe(t('nav_warehouse', 'en-US'));
  });

  it('Chaves "neutras" (marca) são iguais em pt-BR e en-US', () => {
    expect(t('app_title', 'pt-BR')).toBe('VentoApp');
    expect(t('app_title', 'en-US')).toBe('VentoApp');
  });

  it('Fallback para pt-BR quando locale é inválido', () => {
    expect(t('nav_home', 'fr-FR' as Locale)).toBe(t('nav_home', 'pt-BR'));
  });

  it('Retorna a chave quando tradução não existe', () => {
    expect(t('chave_inexistente_xyz', 'pt-BR')).toBe('chave_inexistente_xyz');
  });
});

describe('M9.8 — Interpolação', () => {
  it('Substitui {placeholder} por valor', () => {
    expect(t('settings_projects_count', 'pt-BR', { count: 5 })).toContain('5');
  });

  it('Substitui múltiplos placeholders', () => {
    const text = t('settings_projects_count', 'en-US', { count: 12 });
    expect(text).toContain('12');
  });

  it('Mantém placeholder se parâmetro não fornecido', () => {
    const text = t('settings_projects_count', 'pt-BR');
    expect(text).toContain('{count}');
  });

  it('Sem params, retorna template puro', () => {
    expect(t('nav_home', 'pt-BR')).toBe('Início');
    expect(t('nav_home', 'en-US')).toBe('Home');
  });
});

describe('M9.8 — supportedLocales', () => {
  it('Contém pt-BR e en-US', () => {
    expect(supportedLocales).toContain('pt-BR');
    expect(supportedLocales).toContain('en-US');
  });

  it('DEFAULT_LOCALE é pt-BR', () => {
    expect(DEFAULT_LOCALE).toBe('pt-BR');
  });
});

describe('M9.8 — Detecção automática de locale', () => {
  it('Detecta pt-BR para navigator.language = "pt-BR"', () => {
    Object.defineProperty(navigator, 'language', { value: 'pt-BR', configurable: true });
    expect(detectBrowserLocale()).toBe('pt-BR');
  });

  it('Detecta en-US para navigator.language = "en-US"', () => {
    Object.defineProperty(navigator, 'language', { value: 'en-US', configurable: true });
    expect(detectBrowserLocale()).toBe('en-US');
  });

  it('Detecta pt-BR para navigator.language = "pt-PT"', () => {
    Object.defineProperty(navigator, 'language', { value: 'pt-PT', configurable: true });
    expect(detectBrowserLocale()).toBe('pt-BR');
  });

  it('Fallback para pt-BR quando idioma não suportado', () => {
    Object.defineProperty(navigator, 'language', { value: 'ja-JP', configurable: true });
    expect(detectBrowserLocale()).toBe('pt-BR');
  });
});

describe('M9.8 — Persistência localStorage (via polyfill)', () => {
  // Polyfill de localStorage para ambiente node
  const storage: Record<string, string> = {};
  const mockLocalStorage = {
    getItem: (key: string) => storage[key] ?? null,
    setItem: (key: string, value: string) => {
      storage[key] = value;
    },
    removeItem: (key: string) => {
      delete storage[key];
    },
    clear: () => {
      Object.keys(storage).forEach((k) => delete storage[k]);
    },
  };
  const originalWindow = (globalThis as { window?: typeof window }).window;

  beforeEach(() => {
    Object.keys(storage).forEach((k) => delete storage[k]);
    (globalThis as { window?: typeof window }).window = {
      ...(originalWindow ?? {}),
      localStorage: mockLocalStorage as Storage,
    } as typeof window;
  });

  it('saveStoredLocale persiste o locale', () => {
    saveStoredLocale('en-US');
    expect(window.localStorage.getItem('ventoapp.locale')).toBe('en-US');
  });

  it('loadStoredLocale lê o locale salvo', () => {
    saveStoredLocale('en-US');
    expect(loadStoredLocale()).toBe('en-US');
  });

  it('loadStoredLocale retorna DEFAULT quando nada salvo', () => {
    expect(loadStoredLocale()).toBe(DEFAULT_LOCALE);
  });

  it('saveStoredLocale sobrescreve valor anterior', () => {
    saveStoredLocale('en-US');
    saveStoredLocale('pt-BR');
    expect(loadStoredLocale()).toBe('pt-BR');
  });
});

describe('M9.8 — Chaves principais em pt-BR', () => {
  it('app_title = VentoApp', () => expect(t('app_title', 'pt-BR')).toBe('VentoApp'));
  it('nav_home = Início', () => expect(t('nav_home', 'pt-BR')).toBe('Início'));
  it('nav_warehouse = Galpão', () => expect(t('nav_warehouse', 'pt-BR')).toBe('Galpão'));
  it('nav_cylinder = Cilindro', () => expect(t('nav_cylinder', 'pt-BR')).toBe('Cilindro'));
  it('nav_vault = Abóbada', () => expect(t('nav_vault', 'pt-BR')).toBe('Abóbada'));
  it('nav_dome = Cúpula', () => expect(t('nav_dome', 'pt-BR')).toBe('Cúpula'));
  it('nav_settings = Configurações', () => expect(t('nav_settings', 'pt-BR')).toBe('Configurações'));
});

describe('M9.8 — Chaves principais em en-US', () => {
  it('nav_home = Home', () => expect(t('nav_home', 'en-US')).toBe('Home'));
  it('nav_warehouse = Warehouse', () => expect(t('nav_warehouse', 'en-US')).toBe('Warehouse'));
  it('nav_cylinder = Cylinder', () => expect(t('nav_cylinder', 'en-US')).toBe('Cylinder'));
  it('nav_vault = Vault', () => expect(t('nav_vault', 'en-US')).toBe('Vault'));
  it('nav_dome = Dome', () => expect(t('nav_dome', 'en-US')).toBe('Dome'));
  it('nav_settings = Settings', () => expect(t('nav_settings', 'en-US')).toBe('Settings'));
});

describe('M9.8 — Conteúdo dos módulos (M9.2-M9.4)', () => {
  it('linear_loads_title existe em ambos idiomas', () => {
    expect(t('linear_loads_title', 'pt-BR')).toContain('M9.2');
    expect(t('linear_loads_title', 'en-US')).toContain('M9.2');
  });

  it('scene_capture_title existe em ambos idiomas', () => {
    expect(t('scene_capture_title', 'pt-BR')).toContain('M9.3');
    expect(t('scene_capture_title', 'en-US')).toContain('M9.3');
  });

  it('ftool_title existe em ambos idiomas', () => {
    expect(t('ftool_title', 'pt-BR')).toContain('M9.4');
    expect(t('ftool_title', 'en-US')).toContain('M9.4');
  });
});

describe('M9.8 — Componentes i18n', () => {
  it('LanguageSwitcher é exportado', async () => {
    const mod = await import('../../components/LanguageSwitcher');
    expect(typeof mod.default).toBe('function');
  });

  it('i18nStore existe com locale inicial', async () => {
    const mod = await import('../../store/i18nStore');
    expect(typeof mod.useI18nStore).toBe('function');
    const state = mod.useI18nStore.getState();
    expect(typeof state.locale).toBe('string');
    expect(['pt-BR', 'en-US']).toContain(state.locale);
    expect(typeof state.setLocale).toBe('function');
  });

  it('tNow retorna tradução baseada no store', async () => {
    const { useI18nStore, tNow } = await import('../../store/i18nStore');
    useI18nStore.getState().setLocale('en-US');
    expect(tNow('nav_home')).toBe('Home');
    useI18nStore.getState().setLocale('pt-BR');
    expect(tNow('nav_home')).toBe('Início');
  });
});