#!/usr/bin/env python3
"""
Demo FreqAI - Démonstration des nouvelles fonctionnalités

Tests:
1. Outlier Detection
2. Auto-Retraining Adaptatif
3. Backtesting Adaptatif
4. Intégration complète

Usage:
    python demo_freqai.py
"""

import sys
import logging
from datetime import datetime, timedelta
import numpy as np
from typing import List

# Imports des nouveaux modules
from freqai_integration import get_freqai_manager
from outlier_detection import get_outlier_detector
from ai_adaptive_retrainer import get_adaptive_retrainer
from backtesting_adaptive import AdaptiveBacktester, compare_adaptive_vs_classic

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("Demo")


def generate_synthetic_data(days: int = 30) -> dict:
    """Générer des données synthétiques pour les tests"""
    logger.info(f"🔧 Génération de données synthétiques ({days} jours)...")
    
    # Prix de base
    base_price = 100.0
    prices = [base_price]
    
    # Générer mouvement brownien géométrique
    np.random.seed(42)
    for i in range(days * 24):  # 1 point par heure
        change = np.random.normal(0.0001, 0.005)  # 0.5% std
        new_price = prices[-1] * (1 + change)
        prices.append(new_price)
    
    # Volumes avec tendance
    base_volume = 1000000
    volumes = []
    for i in range(len(prices)):
        volume_change = np.random.normal(0, 0.1)
        volume = base_volume * (1 + volume_change)
        volumes.append(max(volume, 0))
    
    return {
        'prices': prices,
        'volumes': volumes,
        'timestamps': [datetime.now() - timedelta(hours=len(prices)-i) for i in range(len(prices))]
    }


def test_outlier_detection():
    """Test 1: Outlier Detection"""
    logger.info("\n" + "="*80)
    logger.info("TEST 1: OUTLIER DETECTION")
    logger.info("="*80)
    
    detector = get_outlier_detector()
    
    # Test 1.1: Données normales
    logger.info("\n📊 Test 1.1: Données normales")
    normal_prices = [100, 101, 100.5, 102, 101.5, 103, 102.5, 104, 103.5, 105,
                     104.5, 106, 105.5, 107, 106.5, 108, 107.5, 109, 108.5, 110]
    normal_volumes = [1000 + np.random.randint(-100, 100) for _ in range(20)]
    
    result = detector.detect_outlier(
        symbol="BTCUSDT",
        prices=normal_prices,
        volumes=normal_volumes,
        rsi=50,
        bb_position=0.5
    )
    
    logger.info(f"   • Outlier détecté: {result.is_outlier}")
    logger.info(f"   • Méthode: {result.method}")
    logger.info(f"   • Raison: {result.reason}")
    logger.info(f"   • Confidence: {result.confidence:.2%}")
    
    # Test 1.2: Volume spike
    logger.info("\n📊 Test 1.2: Volume Spike")
    spike_volumes = normal_volumes[:-1] + [10000]
    
    result = detector.detect_outlier(
        symbol="ETHUSDT",
        prices=normal_prices,
        volumes=spike_volumes,
        rsi=50,
        bb_position=0.5
    )
    
    logger.info(f"   • Outlier détecté: {result.is_outlier}")
    logger.info(f"   • Méthode: {result.method}")
    logger.info(f"   • Raison: {result.reason}")
    logger.info(f"   • Score: {result.score:.2f}")
    
    # Test 1.3: Price spike
    logger.info("\n📊 Test 1.3: Price Spike")
    spike_prices = normal_prices[:-1] + [150]
    
    result = detector.detect_outlier(
        symbol="BNBUSDT",
        prices=spike_prices,
        volumes=normal_volumes,
        rsi=80,
        bb_position=0.9
    )
    
    logger.info(f"   • Outlier détecté: {result.is_outlier}")
    logger.info(f"   • Méthode: {result.method}")
    logger.info(f"   • Raison: {result.reason}")
    logger.info(f"   • Confidence: {result.confidence:.2%}")
    
    # Test 1.4: Pump & Dump
    logger.info("\n📊 Test 1.4: Pump & Dump")
    pump_prices = [100, 105, 115, 130, 145, 140, 120, 105, 100, 98]
    pump_volumes = [1000, 2000, 5000, 10000, 12000, 8000, 3000, 2000, 1500, 1000]
    
    is_pump, reason = detector.detect_pump_dump(
        symbol="DOGEUSDT",
        prices=pump_prices + normal_prices[:10],
        volumes=pump_volumes + normal_volumes[:10]
    )
    
    logger.info(f"   • Pump&Dump détecté: {is_pump}")
    logger.info(f"   • Raison: {reason}")
    
    logger.info("\n✅ Test Outlier Detection terminé")


def test_adaptive_retraining():
    """Test 2: Auto-Retraining Adaptatif"""
    logger.info("\n" + "="*80)
    logger.info("TEST 2: AUTO-RETRAINING ADAPTATIF")
    logger.info("="*80)
    
    retrainer = get_adaptive_retrainer()
    
    # Vérifier si retraining nécessaire
    logger.info("\n🔍 Vérification nécessité de retraining...")
    should_retrain, reason = retrainer.should_retrain()
    
    logger.info(f"   • Retraining nécessaire: {should_retrain}")
    logger.info(f"   • Raison: {reason}")
    
    # État actuel
    logger.info(f"\n📊 État actuel:")
    logger.info(f"   • Dernier retraining: {retrainer.last_retrain or 'Jamais'}")
    logger.info(f"   • Total retrainings: {len(retrainer.retrain_history)}")
    logger.info(f"   • Dernier régime: {retrainer.last_market_regime or 'Inconnu'}")
    
    # Historique
    if retrainer.retrain_history:
        logger.info(f"\n📜 Historique des retrainings (derniers 5):")
        for i, entry in enumerate(retrainer.retrain_history[-5:], 1):
            logger.info(f"   {i}. {entry.get('timestamp', 'N/A')}")
            logger.info(f"      • Raison: {entry.get('reason', 'N/A')}")
            logger.info(f"      • Durée: {entry.get('duration', 0):.1f}s")
    
    logger.info("\n✅ Test Auto-Retraining terminé")


def test_backtesting_adaptive():
    """Test 3: Backtesting Adaptatif"""
    logger.info("\n" + "="*80)
    logger.info("TEST 3: BACKTESTING ADAPTATIF")
    logger.info("="*80)
    
    # Générer données synthétiques
    data = generate_synthetic_data(days=30)
    
    logger.info("\n🧪 Configuration backtest:")
    logger.info(f"   • Période: {data['timestamps'][0].date()} → {data['timestamps'][-1].date()}")
    logger.info(f"   • Data points: {len(data['prices'])}")
    logger.info(f"   • Capital initial: 10,000 USDT")
    logger.info(f"   • Retraining: tous les 7 jours")
    
    # Créer backtester
    backtester = AdaptiveBacktester(
        initial_capital=10000,
        retrain_interval_days=7
    )
    
    # Simuler des trades (version simplifiée)
    logger.info("\n⚙️ Simulation de trades...")
    logger.info("   (Version simplifiée - intégration complète nécessaire)")
    
    # Pour une vraie simulation, il faudrait:
    # 1. Charger les modèles IA
    # 2. Générer des signaux de trading
    # 3. Exécuter les trades
    # 4. Calculer les métriques
    
    # Ici, on montre juste la structure
    logger.info("\n📊 Exemple de métriques:")
    logger.info("   • Total Trades: 45")
    logger.info("   • Win Rate: 62.22%")
    logger.info("   • Net Profit: +842.50 USDT (+8.43%)")
    logger.info("   • Profit Factor: 1.85")
    logger.info("   • Max Drawdown: -3.24%")
    logger.info("   • Sharpe Ratio: 1.42")
    logger.info("   • Sortino Ratio: 2.13")
    logger.info("\n   ⚠️ Pour un backtest complet, utiliser:")
    logger.info("      python run_backtest_adaptive.py --start 2024-01-01 --end 2024-01-31")
    
    logger.info("\n✅ Test Backtesting terminé")


def test_freqai_integration():
    """Test 4: Intégration Complète"""
    logger.info("\n" + "="*80)
    logger.info("TEST 4: FREQAI INTEGRATION")
    logger.info("="*80)
    
    manager = get_freqai_manager()
    
    # Test 4.1: Vérification outlier sur trade simulé
    logger.info("\n📊 Test 4.1: Vérification outlier sur trade")
    normal_prices = [100, 101, 100.5, 102, 101.5, 103, 102.5, 104, 103.5, 105,
                     104.5, 106, 105.5, 107, 106.5, 108, 107.5, 109, 108.5, 110]
    normal_volumes = [1000 + np.random.randint(-100, 100) for _ in range(20)]
    
    should_block, analysis = manager.should_check_outliers(
        symbol="BTCUSDT",
        prices=normal_prices,
        volumes=normal_volumes,
        rsi=55,
        bb_position=0.6
    )
    
    logger.info(f"   • Bloquer ce trade: {should_block}")
    if analysis:
        logger.info(f"   • Analyse: {analysis.reason}")
    
    # Test 4.2: Check périodique
    logger.info("\n📊 Test 4.2: Check périodique (retraining)")
    results = manager.periodic_check()
    
    if results:
        logger.info("   • Retraining effectué!")
        logger.info(f"   • Raison: {results['reason']}")
        logger.info(f"   • Durée: {results['duration']:.1f}s")
    else:
        logger.info("   • Pas de retraining nécessaire")
    
    # Test 4.3: Statistiques
    logger.info("\n📊 Test 4.3: Statistiques du manager")
    manager.print_stats()
    
    logger.info("\n✅ Test Intégration terminé")


def main():
    """Exécuter tous les tests"""
    logger.info("\n" + "="*80)
    logger.info("🚀 DEMO FREQAI - NOUVELLES FONCTIONNALITÉS")
    logger.info("="*80)
    logger.info("\nModules testés:")
    logger.info("  1. Outlier Detection (pumps, flash crashes)")
    logger.info("  2. Auto-Retraining Adaptatif (48h ou performances)")
    logger.info("  3. Backtesting Adaptatif (simulation réaliste)")
    logger.info("  4. FreqAI Integration (orchestration)")
    logger.info("="*80)
    
    try:
        # Test 1: Outlier Detection
        test_outlier_detection()
        
        # Test 2: Auto-Retraining
        test_adaptive_retraining()
        
        # Test 3: Backtesting
        test_backtesting_adaptive()
        
        # Test 4: Intégration
        test_freqai_integration()
        
        # Résumé final
        logger.info("\n" + "="*80)
        logger.info("✅ TOUS LES TESTS TERMINÉS AVEC SUCCÈS")
        logger.info("="*80)
        logger.info("\n📚 Prochaines étapes:")
        logger.info("  1. Intégrer dans trading_bot.py:")
        logger.info("     from freqai_integration import get_freqai_manager")
        logger.info("     freqai = get_freqai_manager()")
        logger.info("")
        logger.info("  2. Dans trading_loop(), avant chaque trade:")
        logger.info("     should_block, _ = freqai.should_check_outliers(...)")
        logger.info("     if should_block: continue")
        logger.info("")
        logger.info("  3. Ajouter check périodique (toutes les heures):")
        logger.info("     freqai.periodic_check()")
        logger.info("")
        logger.info("  4. Lancer backtest complet:")
        logger.info("     python run_backtest_adaptive.py --days 30")
        logger.info("="*80)
        
    except Exception as e:
        logger.error(f"\n❌ Erreur pendant les tests: {e}", exc_info=True)
        return 1
    
    return 0


if __name__ == "__main__":
    sys.exit(main())
