"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const sales_redirect_js_1 = require("./sales-redirect.js");
function makeMessage(overrides) {
    return {
        id: `msg-${Math.random().toString(36).slice(2, 8)}`,
        content: 'merhaba',
        timestamp: new Date().toISOString(),
        ...overrides,
    };
}
function makeHistory(messageCount, opts) {
    const messages = [];
    const baseTime = new Date('2025-01-15T12:00:00Z').getTime();
    for (let i = 0; i < messageCount; i++) {
        const role = i % 2 === 0 ? 'user' : 'assistant';
        const ts = new Date(baseTime + i * 60_000).toISOString();
        messages.push(makeMessage({ role, timestamp: ts, content: role === 'user' ? 'selam nasılsın' : 'iyiyim sen?' }));
    }
    if (opts?.withPitch && messages.length > 0) {
        // Add a pitch on the last assistant message
        const lastAssistantIdx = messages.length - (messages.length % 2 === 0 ? 1 : 2);
        if (lastAssistantIdx >= 0 && messages[lastAssistantIdx].role === 'assistant') {
            messages[lastAssistantIdx] = {
                ...messages[lastAssistantIdx],
                timestamp: opts.pitchTimestamp ?? messages[lastAssistantIdx].timestamp,
                metadata: { starsPitchMade: true },
            };
        }
    }
    return {
        characterId: 'char-1',
        telegramUserId: 12345,
        userName: 'TestUser',
        userInfo: { name: 'Test', interests: [], notes: [] },
        messages,
        lastActivity: messages.length > 0 ? messages[messages.length - 1].timestamp : new Date().toISOString(),
        totalMessages: messages.length,
        totalStarsSpent: 0,
    };
}
function makeProfile(overrides) {
    return {
        characterId: 'char-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: {},
        },
        salesBehavior: {
            min_messages_before_pitch: 5,
            cooldown_minutes: 30,
            pitch_style: 'playful',
            ...overrides,
        },
    };
}
(0, vitest_1.describe)('SalesRedirector', () => {
    let redirector;
    (0, vitest_1.beforeEach)(() => {
        redirector = new sales_redirect_js_1.SalesRedirector();
        vitest_1.vi.useFakeTimers();
        vitest_1.vi.setSystemTime(new Date('2025-01-15T14:00:00Z'));
    });
    (0, vitest_1.afterEach)(() => {
        vitest_1.vi.useRealTimers();
    });
    (0, vitest_1.describe)('shouldPitch', () => {
        (0, vitest_1.it)('should return false when message count is below minimum', () => {
            const history = makeHistory(3);
            const profile = makeProfile({ min_messages_before_pitch: 5 });
            (0, vitest_1.expect)(redirector.shouldPitch(history, profile)).toBe(false);
        });
        (0, vitest_1.it)('should return true when message count meets minimum and no prior pitch', () => {
            const history = makeHistory(10);
            const profile = makeProfile({ min_messages_before_pitch: 5 });
            (0, vitest_1.expect)(redirector.shouldPitch(history, profile)).toBe(true);
        });
        (0, vitest_1.it)('should return false when cooldown has not elapsed since last pitch', () => {
            // Pitch made 10 minutes ago, cooldown is 30 minutes
            const tenMinutesAgo = new Date(Date.now() - 10 * 60_000).toISOString();
            const history = makeHistory(10, { withPitch: true, pitchTimestamp: tenMinutesAgo });
            const profile = makeProfile({ min_messages_before_pitch: 5, cooldown_minutes: 30 });
            (0, vitest_1.expect)(redirector.shouldPitch(history, profile)).toBe(false);
        });
        (0, vitest_1.it)('should return true when cooldown has elapsed since last pitch', () => {
            // Pitch made 60 minutes ago, cooldown is 30 minutes
            const sixtyMinutesAgo = new Date(Date.now() - 60 * 60_000).toISOString();
            const history = makeHistory(10, { withPitch: true, pitchTimestamp: sixtyMinutesAgo });
            const profile = makeProfile({ min_messages_before_pitch: 5, cooldown_minutes: 30 });
            (0, vitest_1.expect)(redirector.shouldPitch(history, profile)).toBe(true);
        });
        (0, vitest_1.it)('should return false when conversation has zero messages', () => {
            const history = makeHistory(0);
            const profile = makeProfile({ min_messages_before_pitch: 0 });
            (0, vitest_1.expect)(redirector.shouldPitch(history, profile)).toBe(false);
        });
    });
    (0, vitest_1.describe)('generatePitchHint', () => {
        (0, vitest_1.it)('should return a string hint for playful style', () => {
            const profile = makeProfile({ pitch_style: 'playful' });
            const hint = redirector.generatePitchHint(profile);
            (0, vitest_1.expect)(typeof hint).toBe('string');
            (0, vitest_1.expect)(hint.length).toBeGreaterThan(0);
        });
        (0, vitest_1.it)('should return a string hint for subtle style', () => {
            const profile = makeProfile({ pitch_style: 'subtle' });
            const hint = redirector.generatePitchHint(profile);
            (0, vitest_1.expect)(typeof hint).toBe('string');
            (0, vitest_1.expect)(hint.length).toBeGreaterThan(0);
        });
        (0, vitest_1.it)('should return a string hint for direct style', () => {
            const profile = makeProfile({ pitch_style: 'direct' });
            const hint = redirector.generatePitchHint(profile);
            (0, vitest_1.expect)(typeof hint).toBe('string');
            (0, vitest_1.expect)(hint.length).toBeGreaterThan(0);
        });
    });
    (0, vitest_1.describe)('recordPitch', () => {
        (0, vitest_1.it)('should mark the last assistant message with starsPitchMade', () => {
            const history = makeHistory(6); // 3 user + 3 assistant
            const updated = redirector.recordPitch(history);
            // Find last assistant message
            const lastAssistant = [...updated.messages].reverse().find((m) => m.role === 'assistant');
            (0, vitest_1.expect)(lastAssistant?.metadata?.starsPitchMade).toBe(true);
        });
        (0, vitest_1.it)('should not mutate the original history', () => {
            const history = makeHistory(6);
            const originalMessages = history.messages.map((m) => ({ ...m }));
            redirector.recordPitch(history);
            // Original should be unchanged
            for (let i = 0; i < history.messages.length; i++) {
                (0, vitest_1.expect)(history.messages[i].metadata?.starsPitchMade).toBeUndefined();
            }
        });
        (0, vitest_1.it)('should preserve existing metadata on the message', () => {
            const history = makeHistory(4);
            // Manually set some metadata on last assistant
            const lastAssistantIdx = history.messages.length - 1;
            if (history.messages[lastAssistantIdx].role === 'assistant') {
                history.messages[lastAssistantIdx] = {
                    ...history.messages[lastAssistantIdx],
                    metadata: { starsAccepted: true },
                };
            }
            const updated = redirector.recordPitch(history);
            const lastAssistant = [...updated.messages].reverse().find((m) => m.role === 'assistant');
            (0, vitest_1.expect)(lastAssistant?.metadata?.starsPitchMade).toBe(true);
            (0, vitest_1.expect)(lastAssistant?.metadata?.starsAccepted).toBe(true);
        });
    });
    (0, vitest_1.describe)('recordAcceptance', () => {
        (0, vitest_1.it)('should mark the last pitched message as accepted', () => {
            let history = makeHistory(6);
            history = redirector.recordPitch(history);
            const updated = redirector.recordAcceptance(history);
            const pitchedMsg = updated.messages.find((m) => m.metadata?.starsPitchMade);
            (0, vitest_1.expect)(pitchedMsg?.metadata?.starsAccepted).toBe(true);
        });
        (0, vitest_1.it)('should not mutate the original history', () => {
            let history = makeHistory(6);
            history = redirector.recordPitch(history);
            const pitchedHistory = { ...history, messages: [...history.messages] };
            redirector.recordAcceptance(pitchedHistory);
            // The pitched message in pitchedHistory should still not have starsAccepted
            const pitched = pitchedHistory.messages.find((m) => m.metadata?.starsPitchMade);
            (0, vitest_1.expect)(pitched?.metadata?.starsAccepted).toBeUndefined();
        });
    });
    (0, vitest_1.describe)('getConversionStats', () => {
        (0, vitest_1.it)('should return zero stats for empty history', () => {
            const history = makeHistory(0);
            const stats = redirector.getConversionStats(history);
            (0, vitest_1.expect)(stats).toEqual({ pitches: 0, acceptances: 0, rate: 0 });
        });
        (0, vitest_1.it)('should count pitches and acceptances correctly', () => {
            const history = makeHistory(10);
            // Mark two messages as pitched, one as accepted
            history.messages[1] = { ...history.messages[1], metadata: { starsPitchMade: true } };
            history.messages[5] = { ...history.messages[5], metadata: { starsPitchMade: true, starsAccepted: true } };
            const stats = redirector.getConversionStats(history);
            (0, vitest_1.expect)(stats.pitches).toBe(2);
            (0, vitest_1.expect)(stats.acceptances).toBe(1);
            (0, vitest_1.expect)(stats.rate).toBe(0.5);
        });
        (0, vitest_1.it)('should return rate 0 when there are pitches but no acceptances', () => {
            const history = makeHistory(6);
            history.messages[1] = { ...history.messages[1], metadata: { starsPitchMade: true } };
            const stats = redirector.getConversionStats(history);
            (0, vitest_1.expect)(stats.pitches).toBe(1);
            (0, vitest_1.expect)(stats.acceptances).toBe(0);
            (0, vitest_1.expect)(stats.rate).toBe(0);
        });
    });
    (0, vitest_1.describe)('singleton', () => {
        (0, vitest_1.it)('should export a singleton instance', () => {
            (0, vitest_1.expect)(sales_redirect_js_1.salesRedirector).toBeInstanceOf(sales_redirect_js_1.SalesRedirector);
        });
    });
});
//# sourceMappingURL=sales-redirect.test.js.map