"""
Улучшенный спекулятивный анализ ВСЕХ тикеров MOEX (22.06.2026)
Использует T-Bank API (live prices + orderbook) + DB (история)
"""
import sys, os, json
sys.path.insert(0, os.path.dirname(__file__))

import pandas as pd
import numpy as np
from datetime import datetime

from src.db.connection import fetch_ohlcv_combined, get_connection
from src.indicators.calculations import calc_all_indicators
from src.analysis.tech_analysis import (
    detect_candlestick_patterns, detect_vsa_signals, find_key_levels,
    determine_trend, wyckoff_phase, generate_trade_signal,
)
from src.api.tbank import get_last_price, get_current_candle, get_order_book, analyze_order_book, _find_figi

MOEX_TICKERS = [
    'SBER', 'GAZP', 'LKOH', 'ROSN', 'NVTK', 'MGNT', 'TATN',
    'SNGS', 'PLZL', 'PHOR', 'NLMK', 'CHMF', 'GMKN', 'ALRS',
    'MTSS', 'VTBR', 'MOEX', 'FIVE', 'AFLT', 'POLY', 'RUAL',
    'SELG', 'IRAO', 'HYDR', 'MAGN', 'RASP', 'NMTP', 'FESH',
    'CBOM', 'TCSG', 'VKCO', 'YNDX', 'OZON', 'X5', 'ASTR',
]

def table_exists(ticker, tf):
    conn = get_connection()
    try:
        cursor = conn.cursor()
        cursor.execute(f"SHOW TABLES LIKE '{ticker}_{tf}'")
        return cursor.fetchone() is not None
    finally:
        conn.close()

def enhanced_analyze(ticker):
    """Улучшенный анализ с T-Bank API и OrderBook."""
    print(f"\n=== {ticker} ===")
    result = {
        'ticker': ticker,
        'error': None,
        'has_db_data': False,
        'tbank_price': None,
        'trend_w1': '—', 'trend_d1': '—', 'trend_h1': '—',
        'wyckoff_phase': '—', 'wyckoff_direction': '—',
        'signal': 'HOLD', 'confidence': 0,
        'entry': None, 'sl': None, 'tp': None, 'atr': None,
        'reasons': [],
        'levels_support': [], 'levels_resistance': [],
        'orderbook': None,
    }
    
    # 1. T-Bank API: current price + orderbook
    tbank_price = None
    ob = None
    ob_analysis = None
    
    try:
        tbank_price = get_last_price(ticker)
        if tbank_price:
            result['tbank_price'] = tbank_price
            print(f"  T-Bank price: {tbank_price:.2f}")
    except Exception as e:
        print(f"  T-Bank price error: {e}")
    
    try:
        ob = get_order_book(ticker, depth=20)
        ob_analysis = analyze_order_book(ob, large_order_threshold=3000)
        result['orderbook'] = {
            'bid': ob.best_bid, 'ask': ob.best_ask,
            'spread_pct': round(ob.spread_pct, 3),
            'imbalance': round(ob.imbalance_ratio, 2),
            'verdict': ob_analysis.verdict,
        }
        print(f"  OrderBook: bid={ob.best_bid} ask={ob.best_ask} "
              f"spread={ob.spread_pct:.3f}% imbalance={ob.imbalance_ratio:.2f} → {ob_analysis.verdict}")
    except Exception as e:
        print(f"  OrderBook error: {e}")

    # Текущие свечи из T-Bank API
    tbank_candles = {}
    for tf_name in ['W1', 'D1', 'H1']:
        try:
            cur_candle = get_current_candle(ticker, tf_name)
            if cur_candle:
                tbank_candles[tf_name] = cur_candle
                print(f"  Текущая {tf_name}: {cur_candle['Date']} "
                      f"O={cur_candle['Open']:.2f} H={cur_candle['High']:.2f} "
                      f"L={cur_candle['Low']:.2f} C={cur_candle['Close']:.2f}")
        except Exception:
            pass
    result['tbank_candles'] = tbank_candles
    
    # 2. DB data
    has_h1 = table_exists(ticker, 'H1')
    has_d1 = table_exists(ticker, 'D1')
    has_w1 = table_exists(ticker, 'W1')
    
    result['has_db_data'] = has_h1 or has_d1 or has_w1
    
    current_price = tbank_price
    
    if has_h1 or has_d1:
        try:
            df_h1 = fetch_ohlcv_combined(ticker, 'H1', limit=200) if has_h1 else pd.DataFrame()
            df_d1 = fetch_ohlcv_combined(ticker, 'D1', limit=200) if has_d1 else pd.DataFrame()
            df_w1 = fetch_ohlcv_combined(ticker, 'W1', limit=100) if has_w1 else pd.DataFrame()
            
            print(f"  DB: H1={len(df_h1)} D1={len(df_d1)} W1={len(df_w1)}")
            
            if current_price is None:
                if len(df_h1) > 0:
                    current_price = float(df_h1['Close'].iloc[-1])
                elif len(df_d1) > 0:
                    current_price = float(df_d1['Close'].iloc[-1])
            
            if len(df_h1) >= 20:
                df_h1 = calc_all_indicators(df_h1)
                df_h1 = detect_candlestick_patterns(df_h1)
                df_h1 = detect_vsa_signals(df_h1)
            if len(df_d1) >= 20:
                df_d1 = calc_all_indicators(df_d1)
                df_d1 = detect_candlestick_patterns(df_d1)
                df_d1 = detect_vsa_signals(df_d1)
            if len(df_w1) >= 20:
                df_w1 = calc_all_indicators(df_w1)
            
            # Trend analysis
            if len(df_w1) >= 20:
                trend_w1, adx_w1 = determine_trend(df_w1)
                result['trend_w1'] = trend_w1
                result['adx_w1'] = round(adx_w1, 1)
            if len(df_d1) >= 20:
                trend_d1, adx_d1 = determine_trend(df_d1)
                result['trend_d1'] = trend_d1
                result['adx_d1'] = round(adx_d1, 1)
            if len(df_h1) >= 20:
                trend_h1, adx_h1 = determine_trend(df_h1)
                result['trend_h1'] = trend_h1
                result['adx_h1'] = round(adx_h1, 1)
            
            # Wyckoff
            if len(df_w1) >= 20:
                wyckoff = wyckoff_phase(df_w1)
                result['wyckoff_phase'] = wyckoff['phase']
                result['wyckoff_direction'] = wyckoff.get('direction', '—')
                result['wyckoff_tr_low'] = wyckoff.get('tr_low')
                result['wyckoff_tr_high'] = wyckoff.get('tr_high')
            
            # Levels
            levels_h1 = find_key_levels(df_h1) if len(df_h1) >= 20 else {'support': [], 'resistance': []}
            levels_d1 = find_key_levels(df_d1) if len(df_d1) >= 20 else {'support': [], 'resistance': []}
            
            all_levels = {
                'support': list(set(levels_h1.get('support', []) + levels_d1.get('support', []))),
                'resistance': list(set(levels_h1.get('resistance', []) + levels_d1.get('resistance', []))),
            }
            if current_price:
                all_levels['support'] = sorted([x for x in all_levels['support'] if x < current_price], reverse=True)[:5]
                all_levels['resistance'] = sorted([x for x in all_levels['resistance'] if x > current_price])[:5]
            result['levels_support'] = all_levels['support']
            result['levels_resistance'] = all_levels['resistance']
            
            # Signal
            if current_price and len(df_h1) >= 20:
                signal = generate_trade_signal(
                    trend_w1=trend_w1 if 'trend_w1' in result and result['trend_w1'] != '—' else 'sideways',
                    trend_d1=trend_d1 if 'trend_d1' in result else 'sideways',
                    trend_h1=trend_h1 if 'trend_h1' in result else 'sideways',
                    phase=result['wyckoff_phase'],
                    levels=all_levels,
                    df_d1=df_d1,
                    df_h1=df_h1,
                    current_price=current_price,
                )
                result['signal'] = signal['signal']
                result['confidence'] = signal['confidence']
                result['entry'] = signal['entry']
                result['sl'] = signal['sl']
                result['tp'] = signal['tp']
                result['reasons'] = signal['reason']
                result['atr'] = signal.get('atr', 0)
            
            # Last candle info
            if len(df_h1) > 0:
                last_h1 = df_h1.iloc[-1]
                result['last_h1'] = {
                    'date': str(last_h1.get('Date', '')),
                    'time': str(last_h1.get('Time', '')),
                    'open': float(last_h1['Open']),
                    'high': float(last_h1['High']),
                    'low': float(last_h1['Low']),
                    'close': float(last_h1['Close']),
                    'volume': int(last_h1.get('Volume', 0)),
                    'vsa': str(last_h1.get('VSA_signal', '')),
                    'candle': str(last_h1.get('candle_pattern', '')),
                }
            if len(df_d1) > 0:
                last_d1 = df_d1.iloc[-1]
                result['last_d1'] = {
                    'date': str(last_d1.get('Date', '')),
                    'open': float(last_d1['Open']),
                    'high': float(last_d1['High']),
                    'low': float(last_d1['Low']),
                    'close': float(last_d1['Close']),
                    'volume': int(last_d1.get('Volume', 0)),
                    'vsa': str(last_d1.get('VSA_signal', '')),
                    'candle': str(last_d1.get('candle_pattern', '')),
                }
            
        except Exception as e:
            result['error'] = str(e)
            print(f"  DB error: {e}")
    
    # Finally add OB bias boost
    if result['orderbook'] and result['signal'] != 'HOLD':
        ob_verdict = result['orderbook']['verdict']
        if 'БЫЧИЙ' in ob_verdict and result['signal'] == 'BUY':
            result['confidence'] = min(90, result['confidence'] + 10)
            result['reasons'] = str(result.get('reasons', '')) + '; OrderBook бычий bias +10%'
        elif 'МЕДВЕЖИЙ' in ob_verdict and result['signal'] == 'SELL':
            result['confidence'] = min(90, result['confidence'] + 10)
            result['reasons'] = str(result.get('reasons', '')) + '; OrderBook медвежий bias +10%'
        elif 'БЫЧИЙ' in ob_verdict and result['signal'] == 'SELL':
            result['reasons'] = str(result.get('reasons', '')) + '; ⚠ OrderBook бычий bias противоречит SELL'
        elif 'МЕДВЕЖИЙ' in ob_verdict and result['signal'] == 'BUY':
            result['reasons'] = str(result.get('reasons', '')) + '; ⚠ OrderBook медвежий bias противоречит BUY'
    
    print(f"  → {result['signal']} (conf: {result['confidence']}%) | W1:{result['trend_w1']} D1:{result['trend_d1']} H1:{result['trend_h1']}")
    
    return result


def main():
    print("=" * 70)
    print("УЛУЧШЕННЫЙ ТЕХНИЧЕСКИЙ АНАЛИЗ MOEX (T-Bank API + DB)")
    print(f"Дата: {datetime.now().strftime('%Y-%m-%d %H:%M')}")
    print("=" * 70)
    
    results = []
    for ticker in MOEX_TICKERS:
        result = enhanced_analyze(ticker)
        results.append(result)
    
    # Summary
    print(f"\n{'='*70}")
    print("СВОДКА РЕЗУЛЬТАТОВ")
    print(f"{'='*70}")
    
    signals = {'BUY': [], 'SELL': [], 'HOLD': []}
    for r in results:
        sig = r.get('signal', 'HOLD')
        if sig in signals:
            signals[sig].append(r)
    
    print(f"BUY: {len(signals['BUY'])} | SELL: {len(signals['SELL'])} | HOLD: {len(signals['HOLD'])}")
    print()
    
    for sig_type in ['BUY', 'SELL']:
        tickers_sig = sorted(signals[sig_type], key=lambda x: x.get('confidence', 0), reverse=True)
        if tickers_sig:
            print(f"--- {sig_type} Signals ---")
            for r in tickers_sig:
                conf = r.get('confidence', 0)
                price = r.get('tbank_price') or r.get('entry', 0)
                ob_info = ''
                if r.get('orderbook'):
                    obv = r['orderbook']['verdict']
                    ob_info = f' | OB: {obv}'
                wyck = r.get('wyckoff_phase', '')
                print(f"  {r['ticker']:6s} conf={conf:3.0f}% price={price:>8.2f} | {wyck[:35]}{ob_info}")
    
    # Save
    output = {
        'timestamp': datetime.now().isoformat(),
        'results': results,
    }
    with open('/tmp/moex_enhanced_results.json', 'w') as f:
        json.dump(output, f, indent=2, ensure_ascii=False, default=str)
    print(f"\nРезультаты сохранены в /tmp/moex_enhanced_results.json")
    
    return results

if __name__ == '__main__':
    main()
