#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Analyse Détaillée des Performances par Pattern
==============================================

Ce script analyse TOUS les patterns du code et affiche:
- Fréquence d'utilisation
- Win Rate
- P&L moyen
- Meilleurs/Pires trades
- Recommandations d'optimisation
"""

import json
import re
from collections import defaultdict
from datetime import datetime, timedelta

# Couleurs console
class Colors:
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    BLUE = '\033[94m'
    CYAN = '\033[96m'
    MAGENTA = '\033[95m'
    RESET = '\033[0m'
    BOLD = '\033[1m'


def load_trade_history():
    """Charge l'historique des trades"""
    try:
        with open('trade_history.json', 'r', encoding='utf-8') as f:
            return json.load(f)
    except:
        return []


def load_logs():
    """Charge les logs du bot"""
    try:
        with open('trading_bot.log', 'r', encoding='utf-8') as f:
            return f.readlines()
    except:
        return []


def analyze_pattern_performance(trades):
    """Analyse les performances par pattern"""
    pattern_stats = defaultdict(lambda: {
        'count': 0,
        'wins': 0,
        'losses': 0,
        'total_pnl': 0.0,
        'trades': [],
        'avg_duration_minutes': 0,
        'best_trade': None,
        'worst_trade': None
    })
    
    for trade in trades:
        pattern = trade.get('pattern', 'UNKNOWN')
        pnl_pct = trade.get('pnl_pct', 0)
        
        stats = pattern_stats[pattern]
        stats['count'] += 1
        stats['total_pnl'] += pnl_pct
        stats['trades'].append(trade)
        
        if pnl_pct > 0:
            stats['wins'] += 1
        else:
            stats['losses'] += 1
        
        # Meilleur/Pire trade
        if stats['best_trade'] is None or pnl_pct > stats['best_trade']['pnl_pct']:
            stats['best_trade'] = trade
        if stats['worst_trade'] is None or pnl_pct < stats['worst_trade']['pnl_pct']:
            stats['worst_trade'] = trade
        
        # Durée moyenne
        if 'entry_time' in trade and 'exit_time' in trade:
            try:
                entry = datetime.fromisoformat(trade['entry_time'])
                exit = datetime.fromisoformat(trade['exit_time'])
                duration = (exit - entry).total_seconds() / 60
                stats['avg_duration_minutes'] += duration
            except:
                pass
    
    # Calculer moyennes
    for pattern, stats in pattern_stats.items():
        if stats['count'] > 0:
            stats['win_rate'] = (stats['wins'] / stats['count']) * 100
            stats['avg_pnl'] = stats['total_pnl'] / stats['count']
            if stats['avg_duration_minutes'] > 0:
                stats['avg_duration_minutes'] /= stats['count']
    
    return pattern_stats


def extract_pattern_definitions_from_code():
    """Extrait les définitions de patterns depuis ai_predictor.py"""
    patterns = {}
    
    try:
        with open('ai_predictor.py', 'r', encoding='utf-8') as f:
            content = f.read()
            
            # Chercher tous les patterns définis
            pattern_matches = re.finditer(r'is_(\w+)\s*=\s*\(', content)
            for match in pattern_matches:
                pattern_name = match.group(1).upper()
                patterns[pattern_name] = {'defined': True}
            
            # Chercher les patterns assignés (item.pattern = "XXX")
            pattern_assigns = re.finditer(r'item\.pattern\s*=\s*["\'](\w+)["\']', content)
            for match in pattern_assigns:
                pattern_name = match.group(1)
                if pattern_name not in patterns:
                    patterns[pattern_name] = {'defined': True}
    
    except Exception as e:
        print(f"{Colors.RED}Erreur lecture ai_predictor.py: {e}{Colors.RESET}")
    
    return patterns


def get_pattern_priority():
    """Retourne la priorité des patterns (ordre d'évaluation)"""
    return {
        'CREUX_REBOUND': -2,
        'STRONG_UPTREND': -1,
        'EARLY_BREAKOUT': 0,
        'CONSOLIDATION_BREAKOUT': 1,
        'EMA_BULLISH': 2,
        'CROSSOVER_IMMINENT': 3,
        'SQUEEZE_BREAKOUT': 4,
        'VOLUME_REVERSAL': 4,
        'RSI_REVERSAL': 4,
        'PULLBACK': 5,
        'OTHER': 99
    }


def print_pattern_details(pattern, stats, code_patterns):
    """Affiche les détails d'un pattern"""
    win_rate = stats['win_rate']
    avg_pnl = stats['avg_pnl']
    count = stats['count']
    
    # Couleur selon performance
    if win_rate >= 60:
        color = Colors.GREEN
        status = "✅ EXCELLENT"
    elif win_rate >= 50:
        color = Colors.CYAN
        status = "✓ BON"
    elif win_rate >= 40:
        color = Colors.YELLOW
        status = "⚠️ MOYEN"
    else:
        color = Colors.RED
        status = "❌ FAIBLE"
    
    print(f"\n{color}{'─' * 80}{Colors.RESET}")
    print(f"{color}{Colors.BOLD}Pattern: {pattern}{Colors.RESET} {status}")
    print(f"{color}{'─' * 80}{Colors.RESET}")
    
    # Statistiques générales
    print(f"  📊 Trades: {count}")
    print(f"  {'🟢' if win_rate >= 50 else '🔴'} Win Rate: {win_rate:.1f}% ({stats['wins']}W / {stats['losses']}L)")
    print(f"  💰 P&L Moyen: {avg_pnl:+.2f}%")
    print(f"  📈 P&L Total: {stats['total_pnl']:+.2f}%")
    
    if stats['avg_duration_minutes'] > 0:
        hours = stats['avg_duration_minutes'] / 60
        print(f"  ⏱️  Durée moy: {hours:.1f}h ({stats['avg_duration_minutes']:.0f}min)")
    
    # Meilleur/Pire trade
    if stats['best_trade']:
        best = stats['best_trade']
        print(f"  🏆 Meilleur: {best['symbol']} {best['pnl_pct']:+.2f}%")
    
    if stats['worst_trade']:
        worst = stats['worst_trade']
        print(f"  💔 Pire: {worst['symbol']} {worst['pnl_pct']:+.2f}%")
    
    # Présence dans le code
    if pattern in code_patterns:
        print(f"  ✅ Défini dans le code")
    else:
        print(f"  ⚠️ Non trouvé dans ai_predictor.py (ancien pattern?)")


def print_recommendations(pattern_stats):
    """Affiche les recommandations d'optimisation"""
    print(f"\n{Colors.CYAN}{'═' * 80}{Colors.RESET}")
    print(f"{Colors.BOLD}{Colors.CYAN}RECOMMANDATIONS D'OPTIMISATION{Colors.RESET}")
    print(f"{Colors.CYAN}{'═' * 80}{Colors.RESET}\n")
    
    # Patterns à désactiver (Win Rate < 30%)
    weak_patterns = [(p, s) for p, s in pattern_stats.items() if s['win_rate'] < 30 and s['count'] >= 5]
    if weak_patterns:
        print(f"{Colors.RED}❌ PATTERNS À DÉSACTIVER (Win Rate < 30%):{Colors.RESET}")
        for pattern, stats in sorted(weak_patterns, key=lambda x: x[1]['win_rate']):
            print(f"   • {pattern}: {stats['win_rate']:.1f}% WR, {stats['count']} trades, {stats['avg_pnl']:+.2f}% avg")
        print()
    
    # Patterns à optimiser (Win Rate 30-45%)
    medium_patterns = [(p, s) for p, s in pattern_stats.items() if 30 <= s['win_rate'] < 45 and s['count'] >= 5]
    if medium_patterns:
        print(f"{Colors.YELLOW}⚠️  PATTERNS À OPTIMISER (Win Rate 30-45%):{Colors.RESET}")
        for pattern, stats in sorted(medium_patterns, key=lambda x: x[1]['win_rate']):
            print(f"   • {pattern}: {stats['win_rate']:.1f}% WR, {stats['count']} trades, {stats['avg_pnl']:+.2f}% avg")
        print()
    
    # Patterns excellents (Win Rate > 60%)
    strong_patterns = [(p, s) for p, s in pattern_stats.items() if s['win_rate'] >= 60]
    if strong_patterns:
        print(f"{Colors.GREEN}✅ PATTERNS EXCELLENTS (Win Rate > 60%):{Colors.RESET}")
        for pattern, stats in sorted(strong_patterns, key=lambda x: -x[1]['win_rate']):
            print(f"   • {pattern}: {stats['win_rate']:.1f}% WR, {stats['count']} trades, {stats['avg_pnl']:+.2f}% avg")
        print()
    
    # Patterns peu utilisés (< 5 trades)
    rare_patterns = [(p, s) for p, s in pattern_stats.items() if s['count'] < 5]
    if rare_patterns:
        print(f"{Colors.BLUE}ℹ️  PATTERNS PEU UTILISÉS (< 5 trades):{Colors.RESET}")
        for pattern, stats in sorted(rare_patterns, key=lambda x: x[1]['count']):
            print(f"   • {pattern}: {stats['count']} trades seulement")
        print()


def main():
    print(f"\n{Colors.CYAN}{'═' * 80}{Colors.RESET}")
    print(f"{Colors.BOLD}{Colors.CYAN}ANALYSE DÉTAILLÉE DES PATTERNS - RAPPORT COMPLET{Colors.RESET}")
    print(f"{Colors.CYAN}{'═' * 80}{Colors.RESET}\n")
    
    # Charger données
    trades = load_trade_history()
    code_patterns = extract_pattern_definitions_from_code()
    
    if not trades:
        print(f"{Colors.RED}❌ Aucun trade dans l'historique{Colors.RESET}")
        return
    
    print(f"📊 Analyse de {len(trades)} trades")
    print(f"📝 {len(code_patterns)} patterns définis dans le code\n")
    
    # Analyser performances
    pattern_stats = analyze_pattern_performance(trades)
    
    # Trier par fréquence d'utilisation
    sorted_patterns = sorted(pattern_stats.items(), key=lambda x: x[1]['count'], reverse=True)
    
    # Afficher détails de chaque pattern
    for pattern, stats in sorted_patterns:
        print_pattern_details(pattern, stats, code_patterns)
    
    # Recommandations
    print_recommendations(pattern_stats)
    
    # Résumé global
    print(f"{Colors.CYAN}{'═' * 80}{Colors.RESET}")
    print(f"{Colors.BOLD}{Colors.CYAN}RÉSUMÉ GLOBAL{Colors.RESET}")
    print(f"{Colors.CYAN}{'═' * 80}{Colors.RESET}\n")
    
    total_trades = len(trades)
    total_wins = sum(1 for t in trades if t.get('pnl_pct', 0) > 0)
    global_wr = (total_wins / total_trades) * 100 if total_trades > 0 else 0
    total_pnl = sum(t.get('pnl_pct', 0) for t in trades)
    avg_pnl = total_pnl / total_trades if total_trades > 0 else 0
    
    print(f"📊 Total Trades: {total_trades}")
    print(f"{'🟢' if global_wr >= 50 else '🔴'} Win Rate Global: {global_wr:.1f}%")
    print(f"💰 P&L Moyen: {avg_pnl:+.3f}%")
    print(f"📈 P&L Total: {total_pnl:+.2f}%")
    print(f"🎯 Patterns Utilisés: {len(pattern_stats)}")
    
    # Patterns actifs vs définis
    active_patterns = set(pattern_stats.keys())
    defined_patterns = set(code_patterns.keys())
    unused_patterns = defined_patterns - active_patterns
    
    if unused_patterns:
        print(f"\n{Colors.YELLOW}⚠️  {len(unused_patterns)} patterns définis mais jamais utilisés:{Colors.RESET}")
        for p in sorted(unused_patterns):
            print(f"   • {p}")
    
    print(f"\n{Colors.CYAN}{'═' * 80}{Colors.RESET}\n")


if __name__ == "__main__":
    main()
