import { ProStrategyEngine } from '../src/strategies/ProStrategyEngine.js';
import { IExchangeConnector, Candle } from '../src/connectors/types.js';
import { config } from '../src/config/index.js';
import logger from '../src/utils/logger.js';

// --- MOCK LIVE EXCHANGE ---
class LiveSimulationExchange implements IExchangeConnector {
    private currentTime = Date.now();
    private price = 50000;
    private trend = 1; // 1 = Up, -1 = Down

    async fetchOHLCV(symbol: string, timeframe: string, limit?: number): Promise<Candle[]> {
        // Generate a history of candles ending at 'currentTime'
        const candles: Candle[] = [];
        let tempPrice = this.price - (300 * 10); // Start back in time

        const count = limit || 100;

        for (let i = 0; i < count; i++) {
            // Add some "trend" bias based on our internal state
            const noise = (Math.random() - 0.5) * 50;
            const move = (this.trend * 50) + noise; // Stronger trend (was 20)

            tempPrice += move;

            candles.push({
                timestamp: this.currentTime - ((count - i) * getMs(timeframe)),
                open: tempPrice,
                high: tempPrice + 50,
                low: tempPrice - 50,
                close: tempPrice, // Close is what matters for EMA typically
                volume: 1000
            });
        }
        return candles;
    }

    // Helper to advance the simulation
    public tick() {
        this.currentTime += 60 * 60 * 1000; // Advance 1 hour
        this.price += this.trend * 100 + (Math.random() - 0.5) * 200; // Move price
    }

    public setTrend(dir: 1 | -1) {
        this.trend = dir;
    }
    async placeOrder(symbol: string, side: 'buy' | 'sell', qty: number, type: 'market' | 'limit'): Promise<any> {
        return { id: 'mock-sim-order' };
    }

    async getPosition(symbol: string): Promise<any> {
        return null;
    }
}

function getMs(tf: string): number {
    if (tf === '4h') return 4 * 60 * 60 * 1000;
    if (tf === '1h') return 1 * 60 * 60 * 1000;
    return 60000;
}

// --- MAIN RUNNER ---
async function runLiveSimulation() {
    console.log('🚀 INITIALIZING PRO STRATEGY LIVE SIMULATION...\n');

    // 1. Setup Mock Exchange
    const exchange = new LiveSimulationExchange();
    const engine = new ProStrategyEngine(exchange);

    // Mock Config
    config.PRO_STRATEGY.PARAMETERS.SESSION_WINDOWS = [{ start: 0, end: 24 }];
    config.PRO_STRATEGY.PARAMETERS.RSI_OVERBOUGHT = 99;

    console.log('--- PHASE 1: WARMUP (Generating Uptrend Data) ---');
    exchange.setTrend(1); // Uptrend

    // Simulate 5 "Ticks" (Hours) of trading
    for (let i = 1; i <= 5; i++) {
        console.log(`\n⏰ HOUR ${i}: Fetching Market Data...`);
        exchange.tick(); // Advance time/price

        const result = await engine.execute('BTC/USD');

        if (result?.passed) {
            const reason = result.reason || 'No reason';
            console.log(`✅ [Trade Taken] ${result.signal} | Reason: ${reason.split('\n')[0]}...`);
        } else {
            console.log(`⏸️ [Skipped] Reason: ${result?.reason}`);
        }

        // Sleep for effect
        await new Promise(r => setTimeout(r, 500));
    }

    console.log('\n--- PHASE 2: MARKET CRASH (Trend Reversal) ---');
    exchange.setTrend(-1); // Downtrend

    for (let i = 1; i <= 10; i++) { // Need enough ticks to bend the 4H EMA
        // Speed up simulation
        exchange.tick();
        exchange.tick();
        exchange.tick();
    }

    console.log(`\n⏰ HOUR 6 (After Crash): Checking Logic...`);
    const resultCrash = await engine.execute('BTC/USD');
    if (!resultCrash?.passed) {
        console.log(`✅ [Correctly Skipped] Market Crash filtered! Reason: ${resultCrash?.reason}`);
    } else {
        console.log(`❌ [BAD TRADE] Strategy bought during crash? Signal: ${resultCrash?.signal}`);
    }

    console.log('\n✨ SIMULATION COMPLETE');
}

runLiveSimulation();
