"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const fs_1 = require("fs");
const os_1 = require("os");
const path_1 = require("path");
const fs_2 = require("fs");
const index_js_1 = require("./index.js");
function makeDNA(id) {
    return {
        id,
        createdAt: '2025-01-01T00:00:00Z',
        updatedAt: '2025-01-01T00:00:00Z',
        status: 'active',
        identity: { name: 'Test', age: 25, nationality: 'TR', city: 'Istanbul', occupation: 'Model', personality_tags: ['fun'], mbti: 'ENFP', backstory: 'test' },
        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: [] },
        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'], signature_pieces: ['jeans'] },
        technicalSettings: { camera_body: 'Canon R5', portrait_lens: '85mm f/1.4', full_body_lens: '35mm f/1.4', film_stock: 'Portra 400' },
    };
}
let tmpDir;
let store;
(0, vitest_1.beforeEach)(() => {
    tmpDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'datastore-test-'));
    store = new index_js_1.DataStore(tmpDir);
});
(0, vitest_1.afterEach)(() => {
    (0, fs_1.rmSync)(tmpDir, { recursive: true, force: true });
});
(0, vitest_1.describe)('DataStore.init', () => {
    (0, vitest_1.it)('should create all required subdirectories', async () => {
        await store.init();
        const expected = ['config', 'characters', 'templates', 'queue', 'analytics', 'stars', 'translations', 'logs', 'backups'];
        for (const dir of expected) {
            (0, vitest_1.expect)((0, fs_2.existsSync)((0, path_1.resolve)(tmpDir, dir))).toBe(true);
        }
    });
});
(0, vitest_1.describe)('Character CRUD', () => {
    (0, vitest_1.it)('should save and retrieve a character', async () => {
        await store.init();
        const dna = makeDNA('char-1');
        await store.saveCharacter(dna);
        const result = await store.getCharacter('char-1');
        (0, vitest_1.expect)(result).toEqual(dna);
    });
    (0, vitest_1.it)('should return null for non-existent character', async () => {
        await store.init();
        const result = await store.getCharacter('non-existent');
        (0, vitest_1.expect)(result).toBeNull();
    });
    (0, vitest_1.it)('should list all characters', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('c1'));
        await store.saveCharacter(makeDNA('c2'));
        const list = await store.listCharacters();
        (0, vitest_1.expect)(list).toHaveLength(2);
        const ids = list.map(c => c.id).sort();
        (0, vitest_1.expect)(ids).toEqual(['c1', 'c2']);
    });
    (0, vitest_1.it)('should delete a character', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('del-1'));
        const deleted = await store.deleteCharacter('del-1');
        (0, vitest_1.expect)(deleted).toBe(true);
        const result = await store.getCharacter('del-1');
        (0, vitest_1.expect)(result).toBeNull();
    });
    (0, vitest_1.it)('should return false when deleting non-existent character', async () => {
        await store.init();
        const deleted = await store.deleteCharacter('nope');
        (0, vitest_1.expect)(deleted).toBe(false);
    });
    (0, vitest_1.it)('should create character subdirectories on save', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('sub-dirs'));
        const charDir = (0, path_1.resolve)(tmpDir, 'characters', 'sub-dirs');
        (0, vitest_1.expect)((0, fs_2.existsSync)((0, path_1.resolve)(charDir, 'reference-images'))).toBe(true);
        (0, vitest_1.expect)((0, fs_2.existsSync)((0, path_1.resolve)(charDir, 'generated-images'))).toBe(true);
        (0, vitest_1.expect)((0, fs_2.existsSync)((0, path_1.resolve)(charDir, 'quality-reports'))).toBe(true);
        (0, vitest_1.expect)((0, fs_2.existsSync)((0, path_1.resolve)(charDir, 'conversations'))).toBe(true);
    });
});
(0, vitest_1.describe)('Master Prompt CRUD', () => {
    const prompt = {
        characterId: 'mp-1',
        subject: 'young woman',
        clothing: 'casual dress',
        environment: 'cafe',
        lighting: 'natural',
        camera: '85mm f/1.4',
        aesthetic: 'warm',
        negative_prompt: 'blurry',
        createdAt: '2025-01-01T00:00:00Z',
        updatedAt: '2025-01-01T00:00:00Z',
    };
    (0, vitest_1.it)('should save and retrieve master prompt', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('mp-1'));
        await store.saveMasterPrompt(prompt);
        const result = await store.getMasterPrompt('mp-1');
        (0, vitest_1.expect)(result).toEqual(prompt);
    });
    (0, vitest_1.it)('should return null for non-existent master prompt', async () => {
        await store.init();
        const result = await store.getMasterPrompt('no-prompt');
        (0, vitest_1.expect)(result).toBeNull();
    });
});
(0, vitest_1.describe)('Conversation Profile CRUD', () => {
    const profile = {
        characterId: 'cp-1',
        style: 'neseli',
        toneOfVoice: { formality: 'casual', emoji_frequency: 'high', message_length: 'short', humor_level: 'frequent', flirtation_level: 'subtle' },
        languagePatterns: { common_phrases: ['haha'], filler_words: ['yani'], reaction_templates: { happy: ['yay'] } },
        salesBehavior: { min_messages_before_pitch: 10, cooldown_minutes: 60, pitch_style: 'playful' },
    };
    (0, vitest_1.it)('should save and retrieve conversation profile', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('cp-1'));
        await store.saveConversationProfile(profile);
        const result = await store.getConversationProfile('cp-1');
        (0, vitest_1.expect)(result).toEqual(profile);
    });
});
(0, vitest_1.describe)('Conversation History CRUD', () => {
    const history = {
        characterId: 'ch-1',
        telegramUserId: 12345,
        userName: 'testuser',
        userInfo: { name: 'Test', interests: ['art'], notes: [] },
        messages: [{ id: 'm1', role: 'user', content: 'hello', timestamp: '2025-01-01T00:00:00Z' }],
        lastActivity: '2025-01-01T00:00:00Z',
        totalMessages: 1,
        totalStarsSpent: 0,
    };
    (0, vitest_1.it)('should save and retrieve conversation history', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('ch-1'));
        await store.saveConversationHistory(history);
        const result = await store.getConversationHistory('ch-1', 12345);
        (0, vitest_1.expect)(result).toEqual(history);
    });
    (0, vitest_1.it)('should return null for non-existent conversation', async () => {
        await store.init();
        const result = await store.getConversationHistory('ch-1', 99999);
        (0, vitest_1.expect)(result).toBeNull();
    });
    (0, vitest_1.it)('should list conversations for a character', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('ch-1'));
        await store.saveConversationHistory(history);
        await store.saveConversationHistory({ ...history, telegramUserId: 67890, userName: 'user2' });
        const list = await store.listConversations('ch-1');
        (0, vitest_1.expect)(list).toHaveLength(2);
    });
    (0, vitest_1.it)('should delete a conversation', async () => {
        await store.init();
        await store.saveCharacter(makeDNA('ch-1'));
        await store.saveConversationHistory(history);
        const deleted = await store.deleteConversation('ch-1', 12345);
        (0, vitest_1.expect)(deleted).toBe(true);
        const result = await store.getConversationHistory('ch-1', 12345);
        (0, vitest_1.expect)(result).toBeNull();
    });
});
(0, vitest_1.describe)('Stars Transactions', () => {
    const tx = {
        id: 'tx-1',
        characterId: 'st-1',
        telegramUserId: 111,
        type: 'payment',
        starCount: 50,
        status: 'completed',
        createdAt: '2025-01-01T00:00:00Z',
    };
    (0, vitest_1.it)('should save and retrieve stars transactions', async () => {
        await store.init();
        await store.saveStarsTransaction(tx);
        const result = await store.getStarsTransactions('st-1');
        (0, vitest_1.expect)(result).toHaveLength(1);
        (0, vitest_1.expect)(result[0]).toEqual(tx);
    });
    (0, vitest_1.it)('should append transactions to existing list', async () => {
        await store.init();
        await store.saveStarsTransaction(tx);
        await store.saveStarsTransaction({ ...tx, id: 'tx-2', starCount: 100 });
        const result = await store.getStarsTransactions('st-1');
        (0, vitest_1.expect)(result).toHaveLength(2);
    });
    (0, vitest_1.it)('should return empty array for non-existent character transactions', async () => {
        await store.init();
        const result = await store.getStarsTransactions('no-char');
        (0, vitest_1.expect)(result).toEqual([]);
    });
});
(0, vitest_1.describe)('Scene Templates', () => {
    const template = {
        id: 'tpl-1',
        name: 'Beach',
        category: 'outdoor',
        promptTemplate: '{subject} on a beach',
        environment: { lighting: 'golden hour', timeOfDay: 'sunset' },
        defaultAspectRatio: '16:9',
        createdAt: '2025-01-01T00:00:00Z',
        updatedAt: '2025-01-01T00:00:00Z',
    };
    (0, vitest_1.it)('should save and retrieve a template', async () => {
        await store.init();
        await store.saveTemplate(template);
        const result = await store.getTemplate('tpl-1');
        (0, vitest_1.expect)(result).toEqual(template);
    });
    (0, vitest_1.it)('should list all templates', async () => {
        await store.init();
        await store.saveTemplate(template);
        await store.saveTemplate({ ...template, id: 'tpl-2', name: 'Cafe' });
        const list = await store.listTemplates();
        (0, vitest_1.expect)(list).toHaveLength(2);
    });
    (0, vitest_1.it)('should delete a template', async () => {
        await store.init();
        await store.saveTemplate(template);
        const deleted = await store.deleteTemplate('tpl-1');
        (0, vitest_1.expect)(deleted).toBe(true);
        const result = await store.getTemplate('tpl-1');
        (0, vitest_1.expect)(result).toBeNull();
    });
    (0, vitest_1.it)('should return null for non-existent template', async () => {
        await store.init();
        const result = await store.getTemplate('nope');
        (0, vitest_1.expect)(result).toBeNull();
    });
});
(0, vitest_1.describe)('Path helpers', () => {
    (0, vitest_1.it)('should return correct reference images directory', () => {
        const dir = store.getReferenceImagesDir('abc');
        (0, vitest_1.expect)(dir).toContain('characters');
        (0, vitest_1.expect)(dir).toContain('abc');
        (0, vitest_1.expect)(dir).toContain('reference-images');
    });
    (0, vitest_1.it)('should return correct generated images directory', () => {
        const dir = store.getGeneratedImagesDir('abc');
        (0, vitest_1.expect)(dir).toContain('generated-images');
    });
    (0, vitest_1.it)('should return correct quality reports directory', () => {
        const dir = store.getQualityReportsDir('abc');
        (0, vitest_1.expect)(dir).toContain('quality-reports');
    });
});
//# sourceMappingURL=index.test.js.map