"""
Refactoring script for ai_predictor.py
Replaces 3 complex blocks with clean, readable logic based on 4 buy conditions.
"""

NEW_DETECT_BLOCK = '''                # ══════════════════════════════════════════════════════════════════════
                # DÉTECTION SIGNAL D'ACHAT — LOGIQUE CLAIRE
                # 4 conditions obligatoires, toutes requises simultanément:
                #   1. bb_position < 0.40 → prix dans la zone basse des BB (vrai creux)
                #   2. EMA haussier       → EMA9 vient de croiser / dépasser EMA21
                #   3. vol_ratio >= 1.3   → volume réel au-dessus de la moyenne
                #   4. momentum + RSI     → momentum_3 > 0.15% ET rsi < 55
                # ══════════════════════════════════════════════════════════════════════

                bb_position       = item.features.get('bb_position', 0.5)
                ema_diff          = item.features.get('ema_diff', 0)
                ema_slope         = item.features.get('ema_slope', 0)
                ema_trend_bearish = item.features.get('ema_trend_bearish', 0)
                momentum_3        = item.features.get('momentum_3', 0)
                momentum_5        = item.features.get('momentum_5', 0)
                rsi               = item.features.get('rsi', 50)
                ema_cross_bullish = item.features.get('ema_cross_bullish', 0)
                ema_cross_fresh   = item.features.get('ema_cross_fresh', 0)
                consec_green      = item.features.get('consec_green_candles', 0)

                # Volume ratio — pression d'achat réelle
                vol_ratio = (
                    volumes[-1] / (np.mean(volumes[-20:]) + 1e-10)
                    if (volumes is not None and len(volumes) >= 20) else 1.0
                )
                item.features['vol_ratio'] = vol_ratio

                # ── Surveillance BTC pour détecter les crashs marché
                if symbol == 'BTCUSDT':
                    AIPredictor._btc_momentum = momentum_5
                    AIPredictor._last_market_check = datetime.now()
                    _crash_regime = self._get_market_regime()
                    _crash_m5 = {'BULL_STRONG': -0.05, 'BULL_WEAK': -0.04, 'NEUTRAL': -0.03, 'BEAR': -0.02}.get(_crash_regime, -0.03)
                    _crash_m3 = {'BULL_STRONG': -0.03, 'BULL_WEAK': -0.025, 'NEUTRAL': -0.02, 'BEAR': -0.015}.get(_crash_regime, -0.02)
                    is_btc_crashing   = (momentum_5 < _crash_m5 and momentum_3 < _crash_m3)
                    is_btc_recovering = (momentum_3 > 0 or momentum_5 > 0)
                    if is_btc_crashing:
                        if not AIPredictor._market_crash_mode:
                            logger.warning(f"🚨 CRASH MARCHÉ! BTC Mom5={momentum_5:.2f}% Mom3={momentum_3:.2f}% - Achats BLOQUÉS!")
                        AIPredictor._market_crash_mode = True
                    elif is_btc_recovering:
                        if AIPredictor._market_crash_mode:
                            logger.warning(f"✅ FIN CRASH - BTC en reprise: Mom3={momentum_3:.2f}% Mom5={momentum_5:.2f}% - Achats DÉBLOQUÉS!")
                        AIPredictor._market_crash_mode = False

                # ── Condition 1: Prix dans la zone basse des BB
                signal_bb_low = bb_position < 0.40

                # ── Condition 2: Croisement EMA haussier
                # Valide si cross EMA très récent (1-2 bougies),
                # ou si EMA9 vient de passer au-dessus d'EMA21 (diff faible + pente montante)
                signal_ema_cross = (
                    ema_cross_bullish == 1 or
                    (ema_diff > -0.10 and ema_diff < 0.40 and ema_slope > 0.10 and ema_trend_bearish == 0)
                )

                # ── Condition 3: Volume au-dessus de la moyenne
                signal_volume = vol_ratio >= 1.3

                # ── Condition 4: Momentum positif + RSI non surachat
                signal_momentum = momentum_3 > 0.15 and rsi < 55

                # ── Signal global: 4/4 conditions simultanées
                is_buy_signal = signal_bb_low and signal_ema_cross and signal_volume and signal_momentum

                # ── Signal fort: croisement très frais + volume puissant + 2+ bougies vertes consécutives
                is_strong_signal = is_buy_signal and (
                    ema_cross_fresh == 1 and
                    vol_ratio >= 1.8 and
                    rsi < 50 and
                    consec_green >= 2
                )

                # ── Attribution pattern et statut
                if is_strong_signal:
                    item.pattern = 'CREUX_REBOUND'
                    item.status  = 'ready'
                    strength_bonus = min(20, int((vol_ratio - 1.3) * 15))
                    item.score = min(100, item.score + strength_bonus)
                    logger.info(
                        f"🔥 {symbol}: SIGNAL FORT — BB={bb_position:.2f} "
                        f"EMA_diff={ema_diff:.2f}% VOL={vol_ratio:.1f}x "
                        f"RSI={rsi:.0f} Mom={momentum_3:.2f}% Score={item.score}"
                    )
                elif is_buy_signal:
                    item.pattern = 'CREUX_REBOUND'
                    item.status  = 'ready'
                    logger.info(
                        f"✅ {symbol}: SIGNAL ACHAT — BB={bb_position:.2f} "
                        f"EMA_diff={ema_diff:.2f}% VOL={vol_ratio:.1f}x "
                        f"RSI={rsi:.0f} Mom={momentum_3:.2f}% Score={item.score}"
                    )
                else:
                    item.pattern = 'NEUTRAL'
                    item.status  = 'watching'
                    if item.score >= 50:
                        missing = []
                        if not signal_bb_low:    missing.append(f"BB={bb_position:.2f}>0.40")
                        if not signal_ema_cross: missing.append(f"EMA_cross❌(diff={ema_diff:.2f}%,slope={ema_slope:.2f})")
                        if not signal_volume:    missing.append(f"VOL={vol_ratio:.1f}x<1.3")
                        if not signal_momentum:  missing.append(f"Mom={momentum_3:.2f}%/RSI={rsi:.0f}")
                        logger.debug(f"⏳ {symbol}: WATCHING — manque: {', '.join(missing)}")
'''

NEW_CREUX_WATCHLIST_BLOCK = '''                        # PRIORITÉ #0: Pattern CREUX_REBOUND — résultat du signal propre.
                        # Les 4 conditions (BB<0.40 + EMA cross + VOL>=1.3 + Mom>0.15 + RSI<55)
                        # ont été validées dans analyze_symbol — on fait confiance au résultat.
                        if item.pattern == 'CREUX_REBOUND':
                            if not is_crash:
                                smart_data['signal']   = 'ACHAT'
                                smart_data['eligible'] = True
                                item_data['smart_status'] = 'CREUX_REBOUND'
                                logger.info(
                                    f"✅ {symbol}: CREUX_REBOUND → ACHAT "
                                    f"(RSI={rsi_val:.0f} Mom={momentum_3_val:.2%} "
                                    f"VOL={vol_ratio_val:.1f}x)"
                                )
                            else:
                                smart_data['signal']   = 'NO_BUY'
                                smart_data['eligible'] = False
                                item_data['smart_status'] = 'Crash actif (CREUX_REBOUND bloqué)'
'''

NEW_CLASSIC_BLOCK = '''        # === SCORING BASÉ SUR LES PATTERNS — VERSION SIMPLIFIÉE ===
        # Même logique 4-conditions que le chemin advanced scorer

        bb_position_c       = features.get('bb_position', 0.5)
        ema_diff_c          = features.get('ema_diff', 0)
        ema_slope_c         = features.get('ema_slope', 0)
        ema_trend_bearish_c = features.get('ema_trend_bearish', 0)
        momentum_3_c        = features.get('momentum_3', 0)
        momentum_5_c        = features.get('momentum_5', 0)
        rsi_c               = features.get('rsi', 50)
        ema_cross_bullish_c = features.get('ema_cross_bullish', 0)
        ema_cross_fresh_c   = features.get('ema_cross_fresh', 0)
        consec_green_c      = features.get('consec_green_candles', 0)

        vol_ratio_c = (
            volumes[-1] / (np.mean(volumes[-20:]) + 1e-10)
            if (volumes is not None and len(volumes) >= 20) else 1.0
        )
        features['vol_ratio'] = vol_ratio_c

        signal_bb_low_c     = bb_position_c < 0.40
        signal_ema_cross_c  = (
            ema_cross_bullish_c == 1 or
            (ema_diff_c > -0.10 and ema_diff_c < 0.40 and ema_slope_c > 0.10 and ema_trend_bearish_c == 0)
        )
        signal_volume_c     = vol_ratio_c >= 1.3
        signal_momentum_c   = momentum_3_c > 0.15 and rsi_c < 55
        is_buy_signal_c     = signal_bb_low_c and signal_ema_cross_c and signal_volume_c and signal_momentum_c
        is_strong_signal_c  = is_buy_signal_c and (ema_cross_fresh_c == 1 and vol_ratio_c >= 1.8 and rsi_c < 50 and consec_green_c >= 2)

        if is_strong_signal_c:
            item.pattern = 'CREUX_REBOUND'
            item.score   = min(100, item.score + min(20, int((vol_ratio_c - 1.3) * 15)))
            item.status  = 'ready'
        elif is_buy_signal_c:
            item.pattern = 'CREUX_REBOUND'
            item.status  = 'ready'
        else:
            item.pattern = 'NEUTRAL'
            item.status  = 'watching' if item.score >= 50 else 'low_potential'

'''

# ── Read source
with open('ai_predictor.py', 'r') as f:
    lines = f.readlines()

total = len(lines)
print(f"Total lines: {total}")

# ── Block 1: analyze_symbol strategy section (lines 1269→2415, 0-indexed: 1268→2414)
# Keep lines 0..1268 and 2415..end, insert NEW_DETECT_BLOCK between them
BLOCK1_START = 1270 - 1  # line 1270 (start of # ANALYSE DES STRATÉGIES)
BLOCK1_END   = 2415 - 1  # line 2415 (last line before "                return item")

# Verify boundaries
assert '# ANALYSE DES STRAT' in lines[BLOCK1_START], f"Expected strategy start at {BLOCK1_START+1}: {lines[BLOCK1_START]!r}"
# End line is the last line of the _bearish_cycle_active block
print(f"Block1 end line content: {lines[BLOCK1_END]!r}")

new_lines = lines[:BLOCK1_START] + [NEW_DETECT_BLOCK] + lines[BLOCK1_END+1:]
print(f"After block1: {len(new_lines)} lines (removed {total - len(new_lines) + len(NEW_DETECT_BLOCK.splitlines())} and added {len(NEW_DETECT_BLOCK.splitlines())})")

# ── Block 2: classic fallback scoring (lines 2433→2951 in original, but now shifted)
# Find new positions after block1 replacement
def find_line(lines, text, start=0):
    for i in range(start, len(lines)):
        if text in lines[i]:
            return i
    return -1

block2_start = find_line(new_lines, '# === SCORING BASÉ SUR LES PATTERNS ===')
assert block2_start != -1, "Could not find classic fallback start"
# Find the TOP 20 bonus comment that closes the scoring section
block2_end = find_line(new_lines, '# BONUS TOP 20: Prioriser les cryptos à forte capitalisation', block2_start)
assert block2_end != -1, "Could not find classic fallback end"
print(f"Classic fallback: lines {block2_start+1}→{block2_end} in new file")

new_lines = new_lines[:block2_start] + [NEW_CLASSIC_BLOCK] + new_lines[block2_end:]
print(f"After block2: {len(new_lines)} lines")

# ── Block 3: get_watchlist CREUX_REBOUND priority block (lines 3704→3747 in original, now shifted)
block3_start = find_line(new_lines, '# 🔥 PRIORITÉ #0: Pattern CREUX_REBOUND détecté = ACHAT IMMÉDIAT!')
assert block3_start != -1, "Could not find CREUX_REBOUND priority block"
block3_end = find_line(new_lines, '# 🆕 FIX 28/01 14h50: BLOCAGE ACHATS TARDIFS', block3_start)
assert block3_end != -1, "Could not find CREUX_REBOUND block end"
print(f"CREUX_REBOUND watchlist block: lines {block3_start+1}→{block3_end} in new file")

new_lines = new_lines[:block3_start] + [NEW_CREUX_WATCHLIST_BLOCK] + new_lines[block3_end:]
print(f"After block3: {len(new_lines)} lines")

# ── Write result
with open('ai_predictor.py', 'w') as f:
    f.writelines(new_lines)

print("Done. Run: python3 -c \"import ast; ast.parse(open('ai_predictor.py').read()); print('OK')\"")
