import { describe, it, expect } from 'vitest';
import type { ConversationStyleType } from '../../types/character.js';
import { PRESET_PROFILES, AVAILABLE_STYLES, getProfile } from './profiles.js';

describe('AVAILABLE_STYLES', () => {
  it('should contain all 9 styles including custom', () => {
    expect(AVAILABLE_STYLES).toHaveLength(9);
    expect(AVAILABLE_STYLES).toContain('custom');
  });

  it('should contain all 8 preset styles', () => {
    const presets: ConversationStyleType[] = [
      'tipik_turk_kizi', 'tripli', 'alingan', 'neseli',
      'gizemli', 'soguk', 'ilgili', 'oyuncu',
    ];
    for (const style of presets) {
      expect(AVAILABLE_STYLES).toContain(style);
    }
  });
});

describe('PRESET_PROFILES', () => {
  it('should have all 8 preset profiles', () => {
    expect(Object.keys(PRESET_PROFILES)).toHaveLength(8);
  });

  it('each profile should have required toneOfVoice fields', () => {
    for (const [, profile] of Object.entries(PRESET_PROFILES)) {
      expect(profile.toneOfVoice).toBeDefined();
      expect(['casual', 'semi-formal']).toContain(profile.toneOfVoice.formality);
      expect(['low', 'medium', 'high']).toContain(profile.toneOfVoice.emoji_frequency);
      expect(['short', 'medium', 'long']).toContain(profile.toneOfVoice.message_length);
      expect(['none', 'subtle', 'frequent']).toContain(profile.toneOfVoice.humor_level);
      expect(['none', 'subtle', 'moderate', 'high']).toContain(profile.toneOfVoice.flirtation_level);
    }
  });

  it('each profile should have non-empty language patterns', () => {
    for (const [, profile] of Object.entries(PRESET_PROFILES)) {
      expect(profile.languagePatterns.common_phrases.length).toBeGreaterThan(0);
      expect(profile.languagePatterns.filler_words.length).toBeGreaterThan(0);
      expect(Object.keys(profile.languagePatterns.reaction_templates).length).toBeGreaterThan(0);
    }
  });

  it('each profile should have valid salesBehavior', () => {
    for (const [, profile] of Object.entries(PRESET_PROFILES)) {
      expect(profile.salesBehavior.min_messages_before_pitch).toBeGreaterThan(0);
      expect(profile.salesBehavior.cooldown_minutes).toBeGreaterThan(0);
      expect(['subtle', 'playful', 'direct']).toContain(profile.salesBehavior.pitch_style);
    }
  });

  it('each profile should have reaction templates for common emotions', () => {
    const emotions = ['happy', 'sad', 'angry', 'surprised', 'flirt'];
    for (const [, profile] of Object.entries(PRESET_PROFILES)) {
      for (const emotion of emotions) {
        expect(profile.languagePatterns.reaction_templates[emotion]).toBeDefined();
        expect(profile.languagePatterns.reaction_templates[emotion].length).toBeGreaterThan(0);
      }
    }
  });
});

describe('getProfile', () => {
  it('should return a profile with the given characterId for a preset style', () => {
    const profile = getProfile('neseli', 'char-123');
    expect(profile.characterId).toBe('char-123');
    expect(profile.style).toBe('neseli');
  });

  it('should return a deep clone (no shared references with preset)', () => {
    const p1 = getProfile('tripli', 'a');
    const p2 = getProfile('tripli', 'b');
    p1.languagePatterns.common_phrases.push('test');
    expect(p2.languagePatterns.common_phrases).not.toContain('test');
  });

  it('should return a custom profile with customStyleDescription', () => {
    const profile = getProfile('custom', 'char-456', 'Çok romantik ve şiirsel konuşan biri');
    expect(profile.style).toBe('custom');
    expect(profile.characterId).toBe('char-456');
    expect(profile.customStyleDescription).toBe('Çok romantik ve şiirsel konuşan biri');
  });

  it('should default customStyleDescription to empty string when not provided', () => {
    const profile = getProfile('custom', 'char-789');
    expect(profile.customStyleDescription).toBe('');
  });

  it('should not include customStyleDescription for preset styles', () => {
    const profile = getProfile('soguk', 'char-abc');
    expect(profile.customStyleDescription).toBeUndefined();
  });

  it('should throw for an unknown style', () => {
    expect(() => getProfile('nonexistent' as ConversationStyleType, 'x')).toThrow('Unknown conversation style');
  });

  it('should return all 8 preset styles without error', () => {
    const presets: ConversationStyleType[] = [
      'tipik_turk_kizi', 'tripli', 'alingan', 'neseli',
      'gizemli', 'soguk', 'ilgili', 'oyuncu',
    ];
    for (const style of presets) {
      const profile = getProfile(style, `char-${style}`);
      expect(profile.characterId).toBe(`char-${style}`);
      expect(profile.style).toBe(style);
    }
  });
});
