#!/usr/bin/env python3
import sys
import argparse
import logging
from config import WaveStrategyConfig, DB_CONFIG
from database import DatabaseManager
from scheduler import TradingBotService
from backtester import Backtester
from optimizer import ParameterOptimizer, OptimizationConfig
from param_store import ParameterStore

logger = logging.getLogger(__name__)

def setup_logging(level: str = 'INFO'):
    log_level = getattr(logging, level.upper(), logging.INFO)
    root = logging.getLogger()
    root.handlers = []
    handler = logging.StreamHandler(sys.stderr)
    handler.setFormatter(logging.Formatter('%(asctime)s | %(levelname)-8s | %(name)s | %(message)s'))
    root.setLevel(log_level)
    root.addHandler(handler)

def run_backtest(config: WaveStrategyConfig, args):
    db = DatabaseManager(DB_CONFIG)
    bt = Backtester(config, db)
    bt.exchange.set_risk_params(risk_percent=config.risk_calc_percent, lot_size=config.position_lot_size)
    
    report = bt.run(
        instruments=config.INSTRUMENTS if hasattr(config, 'INSTRUMENTS') else db.get_available_instruments(),
        timeframes=['H1','D1','W1'], 
        start_date=args.start, 
        end_date=args.end
    )
    
    # 🔑 Генерация отчетов
    bt.generate_reports(report)
    
    print(f"\n📊 WinRate: {report.metrics.get('win_rate')}% | "
          f"PF: {report.metrics.get('profit_factor')} | "
          f"P&L: ${report.metrics.get('total_pnl'):.2f}")

def run_optimize(config: WaveStrategyConfig, args):
    db = DatabaseManager(DB_CONFIG)
    opt_cfg = OptimizationConfig(n_jobs=1 if args.no_parallel else -1)
    optimizer = ParameterOptimizer(config, db, opt_cfg)
    
    instruments = [i.strip().upper() for i in args.opt_instruments.split(',')] if args.opt_instruments else db.get_available_instruments()
    timeframes = [tf.strip().upper() for tf in args.opt_timeframes.split(',')] if args.opt_timeframes else ['H1', 'D1', 'W1']
    optimizer.optimize_all(instruments, timeframes, args.opt_start, args.opt_end)

def run_service(config: WaveStrategyConfig):
    store = ParameterStore()
    instruments = getattr(config, 'INSTRUMENTS', None) or DatabaseManager(DB_CONFIG).get_available_instruments()
    
    for inst in instruments:
        for tf in config.TIMEFRAMES:
            opt = store.load(inst, tf)
            if opt:
                print(f"📥 {inst}_{tf}: ATR={opt.atr_period} SL={opt.sl_atr_multiplier}× fitness={opt.fitness_score:.3f}")
                
    bot = TradingBotService(config, DB_CONFIG)
    bot.exchange.set_risk_params(risk_percent=config.risk_calc_percent, lot_size=config.position_lot_size)
    bot.run_blocking()

def parse_args():
    p = argparse.ArgumentParser(description='🤖 Wave Range Trading Bot')
    mode = p.add_mutually_exclusive_group(required=True)
    mode.add_argument('--backtest', action='store_true')
    mode.add_argument('--optimize', action='store_true')
    mode.add_argument('--service', action='store_true')
    
    p.add_argument('--start', type=str, help='Дата начала (YYYY-MM-DD)')
    p.add_argument('--end', type=str, help='Дата окончания')
    p.add_argument('--instruments', type=str, help='Инструменты через запятую')
    p.add_argument('--opt-instruments', type=str)
    p.add_argument('--opt-timeframes', type=str)
    p.add_argument('--opt-start', type=str)
    p.add_argument('--opt-end', type=str)
    p.add_argument('--no-parallel', action='store_true')
    p.add_argument('--log-level', default='INFO', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'])
    p.add_argument('--risk-percent', type=float, default=2.0)
    p.add_argument('--lot-size', type=float, default=1.0)
    return p.parse_args()

def main():
    args = parse_args()
    config = WaveStrategyConfig()
    config.risk_calc_percent = args.risk_percent
    config.position_lot_size = args.lot_size
    
    if args.instruments:
        config.INSTRUMENTS = [i.strip().upper() for i in args.instruments.split(',')]

    setup_logging(args.log_level)

    if args.backtest:
        run_backtest(config, args)
    elif args.optimize:
        run_optimize(config, args)
    else:
        run_service(config)

if __name__ == '__main__':
    main()