/**
 * Test suite for Stream Runtime Persistence Bug
 * Tests that stream runtime is correctly reset when switching between different streamers
 */

const assert = require('assert');

// Mock dependencies
class MockIO {
    emit() {}
}

class MockDB {
    setSetting() {}
    getSetting() { return null; }
    getGift() { return null; }
    getGiftCatalog() { return []; }
    updateGiftCatalog() { return 0; }
    logEvent() {}
}

class MockLogger {
    info() {}
    warn() {}
    error() {}
    debug() {}
}

// Load the TikTokConnector class
const TikTokConnector = require('../modules/tiktok.js');

// Simple test runner
console.log('🧪 Running Stream Runtime Switching Tests...\n');

let passed = 0;
let failed = 0;

const testSuites = [
    {
        name: 'Stream Runtime Persistence',
        tests: [
            { name: 'Stream start time should be cleared when switching to a different streamer', fn: () => {
                const connector = new TikTokConnector(new MockIO(), new MockDB(), new MockLogger());
                
                // Simulate first connection
                connector.currentUsername = 'streamer_a';
                connector._persistedStreamStart = Date.now() - 3600000; // 1 hour ago
                connector.streamStartTime = connector._persistedStreamStart;
                connector._earliestEventTime = connector._persistedStreamStart;
                
                // Store the old values to verify they get cleared
                const oldStreamStart = connector.streamStartTime;
                const oldPersistedStart = connector._persistedStreamStart;
                const oldEarliestEvent = connector._earliestEventTime;
                
                // Verify values are set
                assert.ok(oldStreamStart !== null, 'Stream start time should be set');
                assert.ok(oldPersistedStart !== null, 'Persisted start time should be set');
                assert.ok(oldEarliestEvent !== null, 'Earliest event time should be set');
                
                // Manually test the logic that would happen in connect()
                // This simulates connecting to a different streamer
                const previousUsername = connector.currentUsername;
                const newUsername = 'streamer_b';
                
                // This is the fix we implemented
                if (previousUsername && previousUsername !== newUsername) {
                    connector.streamStartTime = null;
                    connector._persistedStreamStart = null;
                    connector._earliestEventTime = null;
                }
                
                // Verify values are cleared
                assert.strictEqual(connector.streamStartTime, null, 'Stream start time should be cleared');
                assert.strictEqual(connector._persistedStreamStart, null, 'Persisted start time should be cleared');
                assert.strictEqual(connector._earliestEventTime, null, 'Earliest event time should be cleared');
            }},
            
            { name: 'Stream start time should be preserved when reconnecting to the same streamer', fn: () => {
                const connector = new TikTokConnector(new MockIO(), new MockDB(), new MockLogger());
                
                // Simulate first connection
                connector.currentUsername = 'streamer_a';
                connector._persistedStreamStart = Date.now() - 3600000; // 1 hour ago
                connector.streamStartTime = connector._persistedStreamStart;
                connector._earliestEventTime = connector._persistedStreamStart;
                
                // Store the old values
                const oldStreamStart = connector.streamStartTime;
                const oldPersistedStart = connector._persistedStreamStart;
                const oldEarliestEvent = connector._earliestEventTime;
                
                // Manually test the logic that would happen in connect()
                // This simulates reconnecting to the same streamer
                const previousUsername = connector.currentUsername;
                const newUsername = 'streamer_a'; // Same streamer
                
                // This is the fix we implemented - should NOT clear when same streamer
                if (previousUsername && previousUsername !== newUsername) {
                    connector.streamStartTime = null;
                    connector._persistedStreamStart = null;
                    connector._earliestEventTime = null;
                }
                
                // Verify values are preserved
                assert.strictEqual(connector.streamStartTime, oldStreamStart, 'Stream start time should be preserved');
                assert.strictEqual(connector._persistedStreamStart, oldPersistedStart, 'Persisted start time should be preserved');
                assert.strictEqual(connector._earliestEventTime, oldEarliestEvent, 'Earliest event time should be preserved');
            }},
            
            { name: 'Stream start time should be cleared when first username is null', fn: () => {
                const connector = new TikTokConnector(new MockIO(), new MockDB(), new MockLogger());
                
                // Simulate first connection (no previous username)
                connector.currentUsername = null;
                connector._persistedStreamStart = null;
                connector.streamStartTime = null;
                connector._earliestEventTime = null;
                
                // Manually test the logic that would happen in connect()
                const previousUsername = connector.currentUsername; // null
                const newUsername = 'streamer_a';
                
                // This is the fix we implemented
                if (previousUsername && previousUsername !== newUsername) {
                    connector.streamStartTime = null;
                    connector._persistedStreamStart = null;
                    connector._earliestEventTime = null;
                }
                
                // Verify values remain null (condition not met because previousUsername is null)
                assert.strictEqual(connector.streamStartTime, null, 'Stream start time should remain null');
                assert.strictEqual(connector._persistedStreamStart, null, 'Persisted start time should remain null');
                assert.strictEqual(connector._earliestEventTime, null, 'Earliest event time should remain null');
            }},
        ]
    },
];

// Run all tests
testSuites.forEach(suite => {
    console.log(`\n📦 ${suite.name}`);
    console.log('─'.repeat(50));
    
    suite.tests.forEach(test => {
        try {
            test.fn();
            console.log(`  ✅ ${test.name}`);
            passed++;
        } catch (error) {
            console.log(`  ❌ ${test.name}`);
            console.log(`     Error: ${error.message}`);
            if (error.stack) {
                console.log(`     ${error.stack.split('\n').slice(1, 3).join('\n     ')}`);
            }
            failed++;
        }
    });
});

// Print summary
console.log('\n' + '='.repeat(50));
console.log(`📊 Test Results: ${passed} passed, ${failed} failed`);
console.log('='.repeat(50) + '\n');

// Exit with appropriate code
process.exit(failed > 0 ? 1 : 0);
