"""
Stratégie GENIUS: Trouve la pire config (qui perd le plus) et inverse-la !
Si une stratégie perd -50%, son inverse gagne +50% !
"""

import logging
import numpy as np
from apollo_client import ApolloDegenClient
from signals.short_term_signals import ShortTermSignalGenerator

logging.basicConfig(level=logging.WARNING)

print("\n" + "="*100)
print("🧠 STRATÉGIE GENIUS: Trouver la PIRE config et l'INVERSER")
print("="*100)

# Données
client = ApolloDegenClient()
df = client.get_klines('BTCUSDT', '1m', limit=1500)

signal_gen = ShortTermSignalGenerator()

# Test rapide de plusieurs configs pour trouver la PIRE
test_configs = [
    {'sl': 0.001, 'tp_ratio': 2, 'lev': 250},
    {'sl': 0.002, 'tp_ratio': 2, 'lev': 250},
    {'sl': 0.003, 'tp_ratio': 2, 'lev': 250},
    {'sl': 0.005, 'tp_ratio': 2, 'lev': 250},
    {'sl': 0.001, 'tp_ratio': 3, 'lev': 250},
    {'sl': 0.002, 'tp_ratio': 3, 'lev': 250},
    {'sl': 0.003, 'tp_ratio': 3, 'lev': 250},
    {'sl': 0.001, 'tp_ratio': 5, 'lev': 250},
    {'sl': 0.002, 'tp_ratio': 5, 'lev': 250},
]

print(f"\n🔍 Test de {len(test_configs)} configs pour trouver la PIRE...")

results = []

for cfg in test_configs:
    capital = 1000
    trades = []

    # Backtest avec signaux DIRECTS
    for i in range(100, len(df) - 50, 15):
        window_df = df.iloc[:i]
        signals = signal_gen.generate_signals(window_df, 'BTCUSDT')

        if not signals:
            continue

        signal = max(signals, key=lambda x: x.score)
        entry_price = df.iloc[i]['close']

        # SL/TP
        if signal.side == 'LONG':
            sl = entry_price * (1 - cfg['sl'])
            tp = entry_price * (1 + cfg['sl'] * cfg['tp_ratio'])
        else:
            sl = entry_price * (1 + cfg['sl'])
            tp = entry_price * (1 - cfg['sl'] * cfg['tp_ratio'])

        # Simuler sortie
        for j in range(i + 1, min(i + 50, len(df))):
            candle = df.iloc[j]
            exit_price = None

            if signal.side == 'LONG':
                if candle['low'] <= sl:
                    exit_price = sl
                elif candle['high'] >= tp:
                    exit_price = tp
            else:
                if candle['high'] >= sl:
                    exit_price = sl
                elif candle['low'] <= tp:
                    exit_price = tp

            if exit_price:
                pnl_pct = ((exit_price - entry_price) / entry_price) if signal.side == 'LONG' else ((entry_price - exit_price) / entry_price)
                pnl_usd = capital * 0.1 * cfg['lev'] * pnl_pct
                capital += pnl_usd
                trades.append({'pnl': pnl_usd, 'side': signal.side})
                break

    if len(trades) >= 5:
        total_return = ((capital - 1000) / 1000) * 100
        results.append({
            'config': cfg,
            'return': total_return,
            'trades': len(trades),
            'capital': capital,
            'trades_data': trades
        })

# Trouver la PIRE
worst = min(results, key=lambda x: x['return'])

print(f"\n🎯 PIRE CONFIG TROUVÉE:")
print(f"   SL: {worst['config']['sl']*100:.2f}%")
print(f"   TP ratio: {worst['config']['tp_ratio']}:1")
print(f"   Leverage: {worst['config']['lev']}x")
print(f"   Return: {worst['return']:.2f}% ❌")
print(f"   Trades: {worst['trades']}")

# Maintenant INVERSER cette config
print(f"\n🔄 INVERSION DE LA PIRE CONFIG...")
print("-"*100)

capital_inverse = 1000
trades_inverse = []

for i in range(100, len(df) - 50, 15):
    window_df = df.iloc[:i]
    signals = signal_gen.generate_signals(window_df, 'BTCUSDT')

    if not signals:
        continue

    signal = max(signals, key=lambda x: x.score)

    # 🔥 INVERSER LE SIGNAL 🔥
    inverse_side = 'SHORT' if signal.side == 'LONG' else 'LONG'

    entry_price = df.iloc[i]['close']

    # SL/TP pour le signal INVERSÉ
    if inverse_side == 'LONG':
        sl = entry_price * (1 - worst['config']['sl'])
        tp = entry_price * (1 + worst['config']['sl'] * worst['config']['tp_ratio'])
    else:
        sl = entry_price * (1 + worst['config']['sl'])
        tp = entry_price * (1 - worst['config']['sl'] * worst['config']['tp_ratio'])

    # Simuler sortie
    for j in range(i + 1, min(i + 50, len(df))):
        candle = df.iloc[j]
        exit_price = None

        if inverse_side == 'LONG':
            if candle['low'] <= sl:
                exit_price = sl
            elif candle['high'] >= tp:
                exit_price = tp
        else:
            if candle['high'] >= sl:
                exit_price = sl
            elif candle['low'] <= tp:
                exit_price = tp

        if exit_price:
            pnl_pct = ((exit_price - entry_price) / entry_price) if inverse_side == 'LONG' else ((entry_price - exit_price) / entry_price)
            pnl_usd = capital_inverse * 0.1 * worst['config']['lev'] * pnl_pct
            capital_inverse += pnl_usd
            trades_inverse.append({'pnl': pnl_usd, 'side': inverse_side})
            break

return_inverse = ((capital_inverse - 1000) / 1000) * 100
wins = len([t for t in trades_inverse if t['pnl'] > 0])
wr_inverse = wins / len(trades_inverse) * 100 if trades_inverse else 0

print(f"\n✅ RÉSULTATS APRÈS INVERSION:")
print(f"   Return: {return_inverse:+.2f}% {'✅' if return_inverse > 0 else '❌'}")
print(f"   Win Rate: {wr_inverse:.1f}%")
print(f"   Trades: {len(trades_inverse)}")
print(f"   Final Capital: ${capital_inverse:.2f}")

# Comparaison
print(f"\n" + "="*100)
print("📊 COMPARAISON AVANT/APRÈS INVERSION")
print("="*100)
print(f"{'Strategy':<30} | {'Return%':<12} | {'Trades':<10}")
print("-"*100)
print(f"{'PIRE config (direct)':<30} | {worst['return']:>11.2f}% | {worst['trades']:>10}")
print(f"{'MÊME config INVERSÉE':<30} | {return_inverse:>11.2f}% | {len(trades_inverse):>10}")

gain = return_inverse - worst['return']
print(f"\n💡 GAIN PAR INVERSION: {gain:+.2f}%")

if return_inverse > 10:
    print(f"\n🎉 SUCCÈS ! La config inversée est PROFITABLE !")
    print(f"\n📝 CONFIG À APPLIQUER:")
    print(f"   - Utiliser signaux de ShortTermSignalGenerator")
    print(f"   - INVERSER chaque signal (LONG → SHORT, SHORT → LONG)")
    print(f"   - SL: {worst['config']['sl']*100:.2f}%")
    print(f"   - TP: {worst['config']['sl']*100*worst['config']['tp_ratio']:.2f}% (ratio {worst['config']['tp_ratio']}:1)")
    print(f"   - Leverage: {worst['config']['lev']}x")
elif return_inverse > 0:
    print(f"\n⚠️  L'inversion améliore mais reste faiblement profitable")
else:
    print(f"\n❌ Même inversée, cette config reste perdante")
    print(f"   Il faut tester d'autres paramètres SL/TP")

print("="*100)
