import { Test, TestingModule } from '@nestjs/testing';
import { MultiLanguageService, SupportedLanguage } from './multilanguage.service';

describe('MultiLanguageService', () => {
  let service: MultiLanguageService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [MultiLanguageService],
    }).compile();

    service = module.get<MultiLanguageService>(MultiLanguageService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('getLanguageConfig', () => {
    it('should return English config', () => {
      const config = service.getLanguageConfig('en');

      expect(config.code).toBe('en');
      expect(config.name).toBe('English');
      expect(config.nativeName).toBe('English');
      expect(config.systemPromptSuffix).toContain('English');
    });

    it('should return Spanish config', () => {
      const config = service.getLanguageConfig('es');

      expect(config.code).toBe('es');
      expect(config.name).toBe('Spanish');
      expect(config.nativeName).toBe('Español');
      expect(config.systemPromptSuffix).toContain('español');
    });

    it('should return French config', () => {
      const config = service.getLanguageConfig('fr');

      expect(config.code).toBe('fr');
      expect(config.name).toBe('French');
      expect(config.nativeName).toBe('Français');
      expect(config.systemPromptSuffix).toContain('français');
    });

    it('should return Portuguese config', () => {
      const config = service.getLanguageConfig('pt');

      expect(config.code).toBe('pt');
      expect(config.name).toBe('Portuguese');
      expect(config.nativeName).toBe('Português');
      expect(config.systemPromptSuffix).toContain('português');
    });

    it('should return Chinese config', () => {
      const config = service.getLanguageConfig('zh');

      expect(config.code).toBe('zh');
      expect(config.name).toBe('Chinese (Simplified)');
      expect(config.nativeName).toBe('简体中文');
      expect(config.systemPromptSuffix).toContain('简体中文');
    });

    it('should default to English for invalid language', () => {
      const config = service.getLanguageConfig('invalid' as SupportedLanguage);

      expect(config.code).toBe('en');
    });
  });

  describe('buildLocalizedSystemPrompt', () => {
    it('should build localized system prompt in English', () => {
      const basePrompt = 'You are a helpful parenting assistant.';
      const result = service.buildLocalizedSystemPrompt(basePrompt, 'en');

      expect(result).toContain(basePrompt);
      expect(result).toContain('LANGUAGE INSTRUCTIONS');
      expect(result).toContain('English');
      expect(result).toContain('cultural sensitivity');
    });

    it('should build localized system prompt in Spanish', () => {
      const basePrompt = 'You are a helpful parenting assistant.';
      const result = service.buildLocalizedSystemPrompt(basePrompt, 'es');

      expect(result).toContain(basePrompt);
      expect(result).toContain('Responde en español');
      expect(result).toContain('Español');
    });

    it('should include cultural context instructions', () => {
      const basePrompt = 'You are a helpful parenting assistant.';
      const result = service.buildLocalizedSystemPrompt(basePrompt, 'fr');

      expect(result).toContain('cultural sensitivity');
      expect(result).toContain('appropriate terminology');
    });
  });

  describe('getMedicalDisclaimer', () => {
    it('should return emergency disclaimer in English', () => {
      const disclaimer = service.getMedicalDisclaimer('en', 'emergency');

      expect(disclaimer).toContain('EMERGENCY');
      expect(disclaimer).toContain('Call 911');
      expect(disclaimer).toContain('immediate medical attention');
    });

    it('should return high severity disclaimer in English', () => {
      const disclaimer = service.getMedicalDisclaimer('en', 'high');

      expect(disclaimer).toContain('IMPORTANT MEDICAL NOTICE');
      expect(disclaimer).toContain('pediatrician');
      expect(disclaimer).toContain('urgent care');
    });

    it('should return medium severity disclaimer in English', () => {
      const disclaimer = service.getMedicalDisclaimer('en', 'medium');

      expect(disclaimer).toContain('Medical Disclaimer');
      expect(disclaimer).toContain('not a medical professional');
      expect(disclaimer).toContain('consult your pediatrician');
    });

    it('should return emergency disclaimer in Spanish', () => {
      const disclaimer = service.getMedicalDisclaimer('es', 'emergency');

      expect(disclaimer).toContain('EMERGENCIA');
      expect(disclaimer).toContain('Llame al 911');
      expect(disclaimer).toContain('atención médica inmediata');
    });

    it('should return disclaimer in French', () => {
      const disclaimer = service.getMedicalDisclaimer('fr', 'high');

      expect(disclaimer).toContain('AVIS MÉDICAL');
      expect(disclaimer).toContain('pédiatre');
      expect(disclaimer).toContain('15 ou 112');
    });

    it('should return disclaimer in Portuguese', () => {
      const disclaimer = service.getMedicalDisclaimer('pt', 'medium');

      expect(disclaimer).toContain('Aviso Médico');
      expect(disclaimer).toContain('pediatra');
      expect(disclaimer).toContain('profissional de saúde');
    });

    it('should return disclaimer in Chinese', () => {
      const disclaimer = service.getMedicalDisclaimer('zh', 'emergency');

      expect(disclaimer).toContain('紧急情况');
      expect(disclaimer).toContain('120');
      expect(disclaimer).toContain('医疗');
    });

    it('should default to English for unsupported language', () => {
      const disclaimer = service.getMedicalDisclaimer(
        'invalid' as SupportedLanguage,
        'emergency',
      );

      expect(disclaimer).toContain('EMERGENCY');
      expect(disclaimer).toContain('Call 911');
    });
  });

  describe('getMentalHealthResources', () => {
    it('should return mental health resources in English', () => {
      const resources = service.getMentalHealthResources('en');

      expect(resources).toContain('Mental Health Support');
      expect(resources).toContain('988');
      expect(resources).toContain('741741');
      expect(resources).toContain('Postpartum Support International');
    });

    it('should return mental health resources in Spanish', () => {
      const resources = service.getMentalHealthResources('es');

      expect(resources).toContain('Apoyo de Salud Mental');
      expect(resources).toContain('988');
      expect(resources).toContain('741741');
    });

    it('should return mental health resources in French', () => {
      const resources = service.getMentalHealthResources('fr');

      expect(resources).toContain('Soutien en Santé Mentale');
      expect(resources).toContain('3114');
      expect(resources).toContain('SOS Amitié');
    });

    it('should return mental health resources in Portuguese', () => {
      const resources = service.getMentalHealthResources('pt');

      expect(resources).toContain('Apoio à Saúde Mental');
      expect(resources).toContain('CVV');
      expect(resources).toContain('188');
    });

    it('should return mental health resources in Chinese', () => {
      const resources = service.getMentalHealthResources('zh');

      expect(resources).toContain('心理健康支持');
      expect(resources).toContain('400-161-9995');
      expect(resources).toContain('120');
    });

    it('should default to English for unsupported language', () => {
      const resources = service.getMentalHealthResources(
        'invalid' as SupportedLanguage,
      );

      expect(resources).toContain('Mental Health Support');
      expect(resources).toContain('988');
    });
  });

  describe('detectLanguage', () => {
    it('should detect Chinese from characters', () => {
      const result = service.detectLanguage('你好，我需要帮助');

      expect(result).toBe('zh');
    });

    it('should detect Spanish from common words', () => {
      const result = service.detectLanguage('Hola, necesito ayuda con mi bebé');

      expect(result).toBe('es');
    });

    it('should detect French from common words', () => {
      const result = service.detectLanguage('Bonjour, mon enfant a besoin d\'aide');

      expect(result).toBe('fr');
    });

    it('should detect Portuguese from common words', () => {
      const result = service.detectLanguage('Olá, meu filho precisa de ajuda');

      expect(result).toBe('pt');
    });

    it('should default to English for unrecognized text', () => {
      const result = service.detectLanguage('Hello, I need help');

      expect(result).toBe('en');
    });

    it('should handle mixed content by detecting dominant language', () => {
      const result = service.detectLanguage('Hello, mi bebé needs help');

      expect(result).toBe('es'); // Spanish words detected
    });
  });

  describe('getSupportedLanguages', () => {
    it('should return all supported languages', () => {
      const languages = service.getSupportedLanguages();

      expect(languages).toHaveLength(5);
      expect(languages.map((l) => l.code)).toEqual(
        expect.arrayContaining(['en', 'es', 'fr', 'pt', 'zh']),
      );
    });

    it('should include all required properties for each language', () => {
      const languages = service.getSupportedLanguages();

      languages.forEach((lang) => {
        expect(lang).toHaveProperty('code');
        expect(lang).toHaveProperty('name');
        expect(lang).toHaveProperty('nativeName');
        expect(lang).toHaveProperty('systemPromptSuffix');
      });
    });
  });

  describe('isValidLanguage', () => {
    it('should return true for valid language codes', () => {
      expect(service.isValidLanguage('en')).toBe(true);
      expect(service.isValidLanguage('es')).toBe(true);
      expect(service.isValidLanguage('fr')).toBe(true);
      expect(service.isValidLanguage('pt')).toBe(true);
      expect(service.isValidLanguage('zh')).toBe(true);
    });

    it('should return false for invalid language codes', () => {
      expect(service.isValidLanguage('invalid')).toBe(false);
      expect(service.isValidLanguage('de')).toBe(false);
      expect(service.isValidLanguage('ja')).toBe(false);
    });

    it('should return false for empty string', () => {
      expect(service.isValidLanguage('')).toBe(false);
    });
  });

  describe('integration scenarios', () => {
    it('should provide complete localization for Spanish user', () => {
      const config = service.getLanguageConfig('es');
      const systemPrompt = service.buildLocalizedSystemPrompt(
        'You are a helpful assistant.',
        'es',
      );
      const disclaimer = service.getMedicalDisclaimer('es', 'medium');

      expect(config.nativeName).toBe('Español');
      expect(systemPrompt).toContain('Responde en español');
      expect(disclaimer).toContain('pediatra');
    });

    it('should handle emergency scenario in user language', () => {
      const languages: SupportedLanguage[] = ['en', 'es', 'fr', 'pt', 'zh'];

      languages.forEach((lang) => {
        const disclaimer = service.getMedicalDisclaimer(lang, 'emergency');
        expect(disclaimer.length).toBeGreaterThan(100);
        // Each language has emergency keywords in that language
        expect(disclaimer.toLowerCase()).toMatch(/emergency|emergencia|urgence|emergência|紧急/);
      });
    });
  });
});
