"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
// --- Mocks ---
const mockSaveCharacter = vitest_1.vi.fn();
const mockGetCharacter = vitest_1.vi.fn();
const mockListCharacters = vitest_1.vi.fn();
const mockDeleteCharacter = vitest_1.vi.fn();
const mockSaveMasterPrompt = vitest_1.vi.fn();
const mockSaveConversationProfile = vitest_1.vi.fn();
vitest_1.vi.mock('../data-store/index.js', () => ({
    dataStore: {
        saveCharacter: (...args) => mockSaveCharacter(...args),
        getCharacter: (...args) => mockGetCharacter(...args),
        listCharacters: (...args) => mockListCharacters(...args),
        deleteCharacter: (...args) => mockDeleteCharacter(...args),
        saveMasterPrompt: (...args) => mockSaveMasterPrompt(...args),
        saveConversationProfile: (...args) => mockSaveConversationProfile(...args),
    },
}));
const mockGenerateReferenceImages = vitest_1.vi.fn().mockResolvedValue(['task-1', 'task-2']);
vitest_1.vi.mock('./reference-pipeline.js', () => ({
    generateReferenceImages: (...args) => mockGenerateReferenceImages(...args),
}));
const mockCloneCharacter = vitest_1.vi.fn();
vitest_1.vi.mock('./clone.js', () => ({
    cloneCharacter: (...args) => mockCloneCharacter(...args),
}));
vitest_1.vi.mock('../../utils/logger.js', () => ({
    createModuleLogger: () => ({
        info: vitest_1.vi.fn(),
        error: vitest_1.vi.fn(),
        warn: vitest_1.vi.fn(),
        debug: vitest_1.vi.fn(),
    }),
}));
// Import after mocks
const index_js_1 = require("./index.js");
// --- Helpers ---
function makeDNA(overrides) {
    return {
        id: 'test-id-1',
        createdAt: '2025-01-01T00:00:00Z',
        updatedAt: '2025-01-01T00:00:00Z',
        status: 'active',
        identity: { name: 'Aylin', age: 24, nationality: 'Turkish', city: 'Istanbul', occupation: 'Model', personality_tags: ['fun'], mbti: 'ENFP', backstory: 'A model' },
        physicalMeasurements: { height_cm: 170, weight_kg: 55, body_type: 'slim', measurements: { bust: 85, waist: 60, hips: 90 } },
        skinMap: { base: '#F5D0A9', shadow: '#D4A574', highlight: '#FDE8D0' },
        faceAnatomy: { eye_shape: 'almond', eye_color: '#8B4513', eyebrow_shape: 'arched', nose_type: 'straight', lip_shape: 'full', cheekbones: 'high', jawline: 'soft', distinctive_marks: [] },
        hairDNA: { style: 'wavy', length: 'long', texture: 'silky', root_color: '#1A1A1A', mid_color: '#2C2C2C', highlight_color: '#4A3728' },
        bodyBiometrics: { body_type_detail: 'athletic slim', posture: 'upright', skin_texture: 'smooth' },
        profileView: { best_angle: 'three-quarter left', signature_pose: 'hand on hip' },
        expressionMotion: { default_expression: 'soft smile', smile_type: 'closed lip', gaze_style: 'direct' },
        makeupStyle: { philosophy: 'natural glam', skin_finish: 'dewy', colors: { primary: '#C48A6A', secondary: '#8B5E3C', accent: '#D4756B' } },
        fashionStyle: { aesthetic: 'casual chic', main_colors: ['#000000', '#FFFFFF', '#C48A6A'], signature_pieces: ['jeans', 'blazer'] },
        technicalSettings: { camera_body: 'Sony A7IV', portrait_lens: '85mm f/1.4', full_body_lens: '35mm f/1.4', film_stock: 'Kodak Portra 400' },
        ...overrides,
    };
}
// --- Tests ---
(0, vitest_1.describe)('CharacterEngine', () => {
    let engine;
    (0, vitest_1.beforeEach)(() => {
        vitest_1.vi.clearAllMocks();
        engine = new index_js_1.CharacterEngine();
    });
    (0, vitest_1.describe)('createCharacter', () => {
        (0, vitest_1.it)('should create a character with full pipeline', async () => {
            mockSaveCharacter.mockResolvedValue(undefined);
            mockSaveMasterPrompt.mockResolvedValue(undefined);
            mockGenerateReferenceImages.mockResolvedValue(['t1']);
            const result = await engine.createCharacter({ identity: { name: 'Selin', age: 22, nationality: 'Turkish', city: 'Ankara', occupation: 'Student', personality_tags: [], mbti: 'INFJ', backstory: '' } });
            (0, vitest_1.expect)(result.identity.name).toBe('Selin');
            (0, vitest_1.expect)(result.status).toBe('active');
            // saveCharacter called twice: once with 'creating', once with 'active'
            (0, vitest_1.expect)(mockSaveCharacter).toHaveBeenCalledTimes(2);
            (0, vitest_1.expect)(mockSaveMasterPrompt).toHaveBeenCalledTimes(1);
            (0, vitest_1.expect)(mockGenerateReferenceImages).toHaveBeenCalledTimes(1);
        });
        (0, vitest_1.it)('should save conversation profile when provided', async () => {
            mockSaveCharacter.mockResolvedValue(undefined);
            mockSaveMasterPrompt.mockResolvedValue(undefined);
            mockGenerateReferenceImages.mockResolvedValue([]);
            mockSaveConversationProfile.mockResolvedValue(undefined);
            await engine.createCharacter({}, { style: 'tripli' });
            (0, vitest_1.expect)(mockSaveConversationProfile).toHaveBeenCalledTimes(1);
            const savedProfile = mockSaveConversationProfile.mock.calls[0][0];
            (0, vitest_1.expect)(savedProfile.style).toBe('tripli');
        });
        (0, vitest_1.it)('should fill defaults for missing fields', async () => {
            mockSaveCharacter.mockResolvedValue(undefined);
            mockSaveMasterPrompt.mockResolvedValue(undefined);
            mockGenerateReferenceImages.mockResolvedValue([]);
            const result = await engine.createCharacter({});
            (0, vitest_1.expect)(result.identity.name).toBe('Unnamed Character');
            (0, vitest_1.expect)(result.skinMap.base).toBe('#F5D0A9');
            (0, vitest_1.expect)(result.id).toBeTruthy();
        });
        (0, vitest_1.it)('should set initial status to creating then active', async () => {
            const savedStatuses = [];
            mockSaveCharacter.mockImplementation(async (dna) => {
                savedStatuses.push(dna.status);
            });
            mockSaveMasterPrompt.mockResolvedValue(undefined);
            mockGenerateReferenceImages.mockResolvedValue([]);
            await engine.createCharacter({});
            (0, vitest_1.expect)(savedStatuses[0]).toBe('creating');
            (0, vitest_1.expect)(savedStatuses[1]).toBe('active');
        });
    });
    (0, vitest_1.describe)('updateCharacter', () => {
        (0, vitest_1.it)('should merge updates into existing character', async () => {
            const existing = makeDNA();
            mockGetCharacter.mockResolvedValue(existing);
            mockSaveCharacter.mockResolvedValue(undefined);
            const result = await engine.updateCharacter('test-id-1', {
                identity: { name: 'Updated Name', age: 24, nationality: 'Turkish', city: 'Istanbul', occupation: 'Model', personality_tags: ['fun'], mbti: 'ENFP', backstory: 'A model' },
            });
            (0, vitest_1.expect)(result.identity.name).toBe('Updated Name');
            (0, vitest_1.expect)(mockSaveCharacter).toHaveBeenCalledTimes(1);
        });
        (0, vitest_1.it)('should throw if character not found', async () => {
            mockGetCharacter.mockResolvedValue(null);
            await (0, vitest_1.expect)(engine.updateCharacter('nonexistent', {})).rejects.toThrow('Character not found');
        });
        (0, vitest_1.it)('should update the updatedAt timestamp', async () => {
            const existing = makeDNA({ updatedAt: '2020-01-01T00:00:00Z' });
            mockGetCharacter.mockResolvedValue(existing);
            mockSaveCharacter.mockResolvedValue(undefined);
            const result = await engine.updateCharacter('test-id-1', {
                skinMap: { base: '#AAAAAA', shadow: '#BBBBBB', highlight: '#CCCCCC' },
            });
            (0, vitest_1.expect)(result.updatedAt).not.toBe('2020-01-01T00:00:00Z');
        });
        (0, vitest_1.it)('should deep merge nested objects like measurements', async () => {
            const existing = makeDNA();
            mockGetCharacter.mockResolvedValue(existing);
            mockSaveCharacter.mockResolvedValue(undefined);
            const result = await engine.updateCharacter('test-id-1', {
                physicalMeasurements: { height_cm: 175, weight_kg: 55, body_type: 'slim', measurements: { bust: 90, waist: 60, hips: 90 } },
            });
            (0, vitest_1.expect)(result.physicalMeasurements.height_cm).toBe(175);
            (0, vitest_1.expect)(result.physicalMeasurements.measurements.bust).toBe(90);
        });
    });
    (0, vitest_1.describe)('deleteCharacter', () => {
        (0, vitest_1.it)('should return true when character exists', async () => {
            mockDeleteCharacter.mockResolvedValue(true);
            const result = await engine.deleteCharacter('test-id-1');
            (0, vitest_1.expect)(result).toBe(true);
            (0, vitest_1.expect)(mockDeleteCharacter).toHaveBeenCalledWith('test-id-1');
        });
        (0, vitest_1.it)('should return false when character does not exist', async () => {
            mockDeleteCharacter.mockResolvedValue(false);
            const result = await engine.deleteCharacter('nonexistent');
            (0, vitest_1.expect)(result).toBe(false);
        });
    });
    (0, vitest_1.describe)('getCharacter', () => {
        (0, vitest_1.it)('should return character when found', async () => {
            const dna = makeDNA();
            mockGetCharacter.mockResolvedValue(dna);
            const result = await engine.getCharacter('test-id-1');
            (0, vitest_1.expect)(result).toEqual(dna);
        });
        (0, vitest_1.it)('should return null when not found', async () => {
            mockGetCharacter.mockResolvedValue(null);
            const result = await engine.getCharacter('nonexistent');
            (0, vitest_1.expect)(result).toBeNull();
        });
    });
    (0, vitest_1.describe)('listCharacters', () => {
        (0, vitest_1.it)('should return all characters', async () => {
            const chars = [makeDNA({ id: 'a' }), makeDNA({ id: 'b' })];
            mockListCharacters.mockResolvedValue(chars);
            const result = await engine.listCharacters();
            (0, vitest_1.expect)(result).toHaveLength(2);
        });
        (0, vitest_1.it)('should return empty array when no characters', async () => {
            mockListCharacters.mockResolvedValue([]);
            const result = await engine.listCharacters();
            (0, vitest_1.expect)(result).toEqual([]);
        });
    });
    (0, vitest_1.describe)('activateCharacter', () => {
        (0, vitest_1.it)('should set status to active', async () => {
            const dna = makeDNA({ status: 'inactive' });
            mockGetCharacter.mockResolvedValue(dna);
            mockSaveCharacter.mockResolvedValue(undefined);
            const result = await engine.activateCharacter('test-id-1');
            (0, vitest_1.expect)(result.status).toBe('active');
            (0, vitest_1.expect)(mockSaveCharacter).toHaveBeenCalledTimes(1);
        });
        (0, vitest_1.it)('should throw if character not found', async () => {
            mockGetCharacter.mockResolvedValue(null);
            await (0, vitest_1.expect)(engine.activateCharacter('nonexistent')).rejects.toThrow('Character not found');
        });
    });
    (0, vitest_1.describe)('deactivateCharacter', () => {
        (0, vitest_1.it)('should set status to inactive', async () => {
            const dna = makeDNA({ status: 'active' });
            mockGetCharacter.mockResolvedValue(dna);
            mockSaveCharacter.mockResolvedValue(undefined);
            const result = await engine.deactivateCharacter('test-id-1');
            (0, vitest_1.expect)(result.status).toBe('inactive');
        });
        (0, vitest_1.it)('should throw if character not found', async () => {
            mockGetCharacter.mockResolvedValue(null);
            await (0, vitest_1.expect)(engine.deactivateCharacter('nonexistent')).rejects.toThrow('Character not found');
        });
    });
    (0, vitest_1.describe)('cloneCharacter', () => {
        (0, vitest_1.it)('should delegate to clone module', async () => {
            const cloned = makeDNA({ id: 'cloned-id' });
            mockCloneCharacter.mockResolvedValue(cloned);
            const result = await engine.cloneCharacter('source-id', { identity: { name: 'Clone', age: 20, nationality: 'TR', city: 'Izmir', occupation: 'Artist', personality_tags: [], mbti: 'INTP', backstory: '' } });
            (0, vitest_1.expect)(mockCloneCharacter).toHaveBeenCalledWith('source-id', vitest_1.expect.objectContaining({ identity: vitest_1.expect.objectContaining({ name: 'Clone' }) }));
            (0, vitest_1.expect)(result.id).toBe('cloned-id');
        });
    });
});
//# sourceMappingURL=index.test.js.map