#!/usr/bin/env python3
"""
Sequential training of MoERegression models for all tickers.
Runs in serial (one ticker at a time) to avoid CUDA OOM on multi-GPU systems.
"""

import sys
import os
import time

# Определяем пути
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from config import MOEX_TICKERS, CRYPTO_TICKERS, FOREX_TICKERS, SHORT_TRAIN_DISABLED_MOEX
from models.moe_regression import MoERegression, CryptoMoERegression


def get_market_type(ticker: str) -> str:
    """Определяет тип рынка."""
    if ticker in ('BITCOIN', 'BITCOINC', 'ZCASH'):
        return 'crypto'
    elif ticker in ('EURUSD',):
        return 'forex'
    else:
        return 'moex'


def train_regression_model(ticker: str, verbose: bool = True) -> bool:
    """Обучает регрессионную модель для одного тикера."""
    market_type = get_market_type(ticker)
    model_class = CryptoMoERegression if market_type == 'crypto' else MoERegression

    if verbose:
        print(f'\n{"=" * 70}')
        print(f'  {market_type.upper()} MoERegression Training: {ticker}')
        print(f'{"=" * 70}\n')

    start_time = time.time()
    model = model_class(ticker)
    success = model.train(limit=None, verbose=verbose)

    if success:
        save_path = f'models/saved/{ticker.lower()}_moe_regression.joblib'
        model.save(save_path)
        elapsed = time.time() - start_time
        if verbose:
            print(f'\n✓ {ticker} trained successfully in {elapsed:.1f}s')
    else:
        elapsed = time.time() - start_time
        if verbose:
            print(f'\n✗ {ticker} training failed after {elapsed:.1f}s')

    return success


def main():
    """Обучает все модели последовательно."""
    all_tickers = MOEX_TICKERS + CRYPTO_TICKERS + FOREX_TICKERS
    print(f'\n{"=" * 70}')
    print(f'  MoERegression Sequential Training')
    print(f'{"=" * 70}')
    print(f'Total tickers: {len(all_tickers)}')
    print(f'  MOEX: {len(MOEX_TICKERS)}')
    print(f'  Crypto: {len(CRYPTO_TICKERS)}')
    print(f'  Forex: {len(FOREX_TICKERS)}')
    print(f'SHORT_TRAIN_DISABLED_MOEX: {SHORT_TRAIN_DISABLED_MOEX}')
    print(f'\nStarting training...\n')

    total_start = time.time()
    results = {}

    for ticker in all_tickers:
        success = train_regression_model(ticker)
        results[ticker] = success

    total_elapsed = time.time() - total_start

    # Сводка
    print(f'\n{"=" * 70}')
    print(f'  Training Summary')
    print(f'{"=" * 70}')
    successful = sum(1 for v in results.values() if v)
    failed = len(results) - successful
    print(f'Total: {len(results)} | Successful: {successful} | Failed: {failed}')
    print(f'Total time: {total_elapsed / 60:.1f} minutes')

    if failed > 0:
        print(f'\nFailed tickers:')
        for ticker, success in results.items():
            if not success:
                print(f'  ✗ {ticker}')


if __name__ == '__main__':
    main()
