"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
// Mock data-store before importing clone module
vitest_1.vi.mock('../data-store/index.js', () => {
    return {
        dataStore: {
            getCharacter: vitest_1.vi.fn(),
            saveCharacter: vitest_1.vi.fn(),
            saveMasterPrompt: vitest_1.vi.fn(),
            getMasterPrompt: vitest_1.vi.fn(),
            saveConversationProfile: vitest_1.vi.fn(),
            getConversationProfile: vitest_1.vi.fn(),
        },
    };
});
// Mock uuid to control generated IDs in tests
vitest_1.vi.mock('uuid', () => ({
    v4: vitest_1.vi.fn(() => 'new-clone-uuid-1234'),
}));
const clone_js_1 = require("./clone.js");
const index_js_1 = require("../data-store/index.js");
function makeDNA(overrides) {
    return {
        id: 'source-uuid-1234',
        createdAt: '2025-01-01T00:00:00Z',
        updatedAt: '2025-01-01T00:00:00Z',
        status: 'active',
        identity: { name: 'Aylin', age: 24, nationality: 'TR', city: 'Istanbul', occupation: 'Model', personality_tags: ['fun', 'outgoing'], mbti: 'ENFP', backstory: 'A vibrant soul' },
        physicalMeasurements: { height_cm: 170, weight_kg: 55, body_type: 'slim', measurements: { bust: 90, waist: 60, hips: 90 } },
        skinMap: { base: '#F5D0A9', shadow: '#D4A574', highlight: '#FFE4C4' },
        faceAnatomy: { eye_shape: 'almond', eye_color: '#8B4513', eyebrow_shape: 'arched', nose_type: 'straight', lip_shape: 'full', cheekbones: 'high', jawline: 'soft', distinctive_marks: ['mole on left cheek'] },
        hairDNA: { style: 'wavy', length: 'long', texture: 'silky', root_color: '#3B2F2F', mid_color: '#5C4033', highlight_color: '#8B6914' },
        bodyBiometrics: { body_type_detail: 'hourglass', posture: 'upright', skin_texture: 'smooth' },
        profileView: { best_angle: 'left-45', signature_pose: 'hand-on-hip' },
        expressionMotion: { default_expression: 'smile', smile_type: 'warm', gaze_style: 'direct' },
        makeupStyle: { philosophy: 'natural', skin_finish: 'dewy', colors: { primary: '#C48793', secondary: '#E8B4B8', accent: '#8B0000' } },
        fashionStyle: { aesthetic: 'casual-chic', main_colors: ['#000000', '#FFFFFF', '#FF5733'], signature_pieces: ['jeans', 'blazer'] },
        technicalSettings: { camera_body: 'Canon R5', portrait_lens: '85mm f/1.4', full_body_lens: '35mm f/1.4', film_stock: 'Portra 400' },
        ...overrides,
    };
}
function makeProfile(characterId) {
    return {
        characterId,
        style: 'neseli',
        toneOfVoice: {
            formality: 'casual',
            emoji_frequency: 'high',
            message_length: 'short',
            humor_level: 'frequent',
            flirtation_level: 'subtle',
        },
        languagePatterns: {
            common_phrases: ['haha', 'ya'],
            filler_words: ['şey', 'yani'],
            reaction_templates: { happy: ['yay!', 'süper!'] },
        },
        salesBehavior: {
            min_messages_before_pitch: 10,
            cooldown_minutes: 60,
            pitch_style: 'playful',
        },
    };
}
(0, vitest_1.beforeEach)(() => {
    vitest_1.vi.restoreAllMocks();
    vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(null);
    vitest_1.vi.mocked(index_js_1.dataStore.saveCharacter).mockResolvedValue(undefined);
    vitest_1.vi.mocked(index_js_1.dataStore.saveMasterPrompt).mockResolvedValue(undefined);
    vitest_1.vi.mocked(index_js_1.dataStore.saveConversationProfile).mockResolvedValue(undefined);
    vitest_1.vi.mocked(index_js_1.dataStore.getConversationProfile).mockResolvedValue(null);
});
(0, vitest_1.describe)('cloneCharacter', () => {
    (0, vitest_1.it)('should throw when source character is not found', async () => {
        await (0, vitest_1.expect)((0, clone_js_1.cloneCharacter)('nonexistent-id')).rejects.toThrow('Source character not found: nonexistent-id');
    });
    (0, vitest_1.it)('should assign a new UUID v4 to the cloned character', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(result.id).toBe('new-clone-uuid-1234');
        (0, vitest_1.expect)(result.id).not.toBe('source-uuid-1234');
    });
    (0, vitest_1.it)('should set new createdAt and updatedAt timestamps', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(result.createdAt).not.toBe('2025-01-01T00:00:00Z');
        // Both should be set from the same Date call
        (0, vitest_1.expect)(result.updatedAt).toBe(result.createdAt);
        // Should be a valid ISO timestamp
        (0, vitest_1.expect)(new Date(result.createdAt).toISOString()).toBe(result.createdAt);
    });
    (0, vitest_1.it)('should set status to creating', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(result.status).toBe('creating');
    });
    (0, vitest_1.it)('should deep clone all DNA fields from source', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(result.identity.name).toBe('Aylin');
        (0, vitest_1.expect)(result.skinMap.base).toBe('#F5D0A9');
        (0, vitest_1.expect)(result.hairDNA.root_color).toBe('#3B2F2F');
        (0, vitest_1.expect)(result.fashionStyle.main_colors).toEqual(['#000000', '#FFFFFF', '#FF5733']);
        (0, vitest_1.expect)(result.technicalSettings.camera_body).toBe('Canon R5');
    });
    (0, vitest_1.it)('should not mutate the source DNA', async () => {
        const source = makeDNA();
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(source);
        await (0, clone_js_1.cloneCharacter)('source-uuid-1234', { identity: { name: 'Zeynep' } });
        (0, vitest_1.expect)(source.identity.name).toBe('Aylin');
        (0, vitest_1.expect)(source.id).toBe('source-uuid-1234');
    });
    (0, vitest_1.it)('should apply selective field overrides', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234', {
            identity: { name: 'Zeynep', age: 22 },
            skinMap: { base: '#AABBCC' },
        });
        // Overridden fields
        (0, vitest_1.expect)(result.identity.name).toBe('Zeynep');
        (0, vitest_1.expect)(result.identity.age).toBe(22);
        (0, vitest_1.expect)(result.skinMap.base).toBe('#AABBCC');
        // Non-overridden fields preserved from merge
        (0, vitest_1.expect)(result.identity.city).toBe('Istanbul');
        (0, vitest_1.expect)(result.skinMap.shadow).toBe('#D4A574');
    });
    (0, vitest_1.it)('should always set status to creating regardless of overrides', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234', { status: 'active' });
        // Status is always 'creating' for new clones (managed field)
        (0, vitest_1.expect)(result.status).toBe('creating');
    });
    (0, vitest_1.it)('should save the cloned character to data store', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(index_js_1.dataStore.saveCharacter).toHaveBeenCalledTimes(1);
        const savedDNA = vitest_1.vi.mocked(index_js_1.dataStore.saveCharacter).mock.calls[0][0];
        (0, vitest_1.expect)(savedDNA.id).toBe('new-clone-uuid-1234');
    });
    (0, vitest_1.it)('should rebuild and save master prompt from new DNA', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(index_js_1.dataStore.saveMasterPrompt).toHaveBeenCalledTimes(1);
        const savedPrompt = vitest_1.vi.mocked(index_js_1.dataStore.saveMasterPrompt).mock.calls[0][0];
        (0, vitest_1.expect)(savedPrompt.characterId).toBe('new-clone-uuid-1234');
        (0, vitest_1.expect)(savedPrompt.subject).toBeTruthy();
        (0, vitest_1.expect)(savedPrompt.camera).toContain('Canon R5');
    });
    (0, vitest_1.it)('should copy conversation profile with new characterId', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        vitest_1.vi.mocked(index_js_1.dataStore.getConversationProfile).mockResolvedValue(makeProfile('source-uuid-1234'));
        await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(index_js_1.dataStore.saveConversationProfile).toHaveBeenCalledTimes(1);
        const savedProfile = vitest_1.vi.mocked(index_js_1.dataStore.saveConversationProfile).mock.calls[0][0];
        (0, vitest_1.expect)(savedProfile.characterId).toBe('new-clone-uuid-1234');
        (0, vitest_1.expect)(savedProfile.style).toBe('neseli');
        (0, vitest_1.expect)(savedProfile.toneOfVoice.emoji_frequency).toBe('high');
    });
    (0, vitest_1.it)('should not save conversation profile if source has none', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        (0, vitest_1.expect)(index_js_1.dataStore.saveConversationProfile).not.toHaveBeenCalled();
    });
    (0, vitest_1.it)('should deep clone conversation profile (no shared references)', async () => {
        const profile = makeProfile('source-uuid-1234');
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        vitest_1.vi.mocked(index_js_1.dataStore.getConversationProfile).mockResolvedValue(profile);
        await (0, clone_js_1.cloneCharacter)('source-uuid-1234');
        const savedProfile = vitest_1.vi.mocked(index_js_1.dataStore.saveConversationProfile).mock.calls[0][0];
        savedProfile.languagePatterns.common_phrases.push('test');
        (0, vitest_1.expect)(profile.languagePatterns.common_phrases).toEqual(['haha', 'ya']);
    });
    (0, vitest_1.it)('should ignore id, createdAt, updatedAt in overrides', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234', {
            id: 'should-be-ignored',
            createdAt: '1999-01-01T00:00:00Z',
            updatedAt: '1999-01-01T00:00:00Z',
        });
        (0, vitest_1.expect)(result.id).toBe('new-clone-uuid-1234');
        (0, vitest_1.expect)(result.createdAt).not.toBe('1999-01-01T00:00:00Z');
    });
    (0, vitest_1.it)('should accept options parameter without error', async () => {
        vitest_1.vi.mocked(index_js_1.dataStore.getCharacter).mockResolvedValue(makeDNA());
        const result = await (0, clone_js_1.cloneCharacter)('source-uuid-1234', undefined, { regenerateImages: true });
        (0, vitest_1.expect)(result.id).toBe('new-clone-uuid-1234');
    });
});
//# sourceMappingURL=clone.test.js.map