"""Real-time data collection system with WebSocket support."""

import asyncio
from decimal import Decimal
from typing import Dict, Optional, Callable, List
from datetime import datetime
from sqlalchemy import select
from src.core.database import get_database, MarketData
from src.core.logger import get_logger
from .pricing_service import get_pricing_service

logger = get_logger(__name__)


class DataCollector:
    """Collects real-time market data using the unified pricing service."""
    
    def __init__(self):
        """Initialize data collector."""
        self.db = get_database()
        self.logger = get_logger(__name__)
        self._callbacks: Dict[str, List[Callable]] = {}
        self._running = False
        self._pricing_service = get_pricing_service()
    
    def subscribe(
        self,
        exchange_id: Optional[int] = None,
        symbol: str = "",
        callback: Optional[Callable] = None
    ):
        """Subscribe to real-time data.
        
        Args:
            exchange_id: Exchange ID (deprecated, kept for backward compatibility)
            symbol: Trading symbol
            callback: Callback function(data)
        """
        if not symbol or not callback:
            logger.warning("subscribe called without symbol or callback")
            return
        
        key = f"pricing:{symbol}"
        if key not in self._callbacks:
            self._callbacks[key] = []
        self._callbacks[key].append(callback)
        
        # Subscribe via pricing service
        def wrapped_callback(data):
            """Wrap callback to maintain backward compatibility."""
            for cb in self._callbacks.get(key, []):
                try:
                    cb(data)
                except Exception as e:
                    logger.error(f"Callback error for {symbol}: {e}")
        
        self._pricing_service.subscribe_ticker(symbol, wrapped_callback)
    
    async def store_ohlcv(
        self,
        exchange: str,
        symbol: str,
        timeframe: str,
        ohlcv_data: List[List]
    ):
        """Store OHLCV data in database.
        
        Args:
            exchange: Exchange name (can be provider name like 'CCXT-Kraken' or 'CoinGecko')
            symbol: Trading symbol
            timeframe: Timeframe
            ohlcv_data: List of [timestamp, open, high, low, close, volume]
        """
        async with self.db.get_session() as session:
            try:
                for candle in ohlcv_data:
                    timestamp = datetime.fromtimestamp(candle[0] / 1000)
                    
                    # Check if already exists
                    stmt = select(MarketData).filter_by(
                        exchange=exchange,
                        symbol=symbol,
                        timeframe=timeframe,
                        timestamp=timestamp
                    )
                    result = await session.execute(stmt)
                    existing = result.scalar_one_or_none()
                    
                    if not existing:
                        market_data = MarketData(
                            exchange=exchange,
                            symbol=symbol,
                            timeframe=timeframe,
                            timestamp=timestamp,
                            open=Decimal(str(candle[1])),
                            high=Decimal(str(candle[2])),
                            low=Decimal(str(candle[3])),
                            close=Decimal(str(candle[4])),
                            volume=Decimal(str(candle[5]))
                        )
                        session.add(market_data)
                
                await session.commit()
            except Exception as e:
                await session.rollback()
                logger.error(f"Failed to store OHLCV data: {e}")
    
    def get_ohlcv_from_pricing_service(
        self,
        symbol: str,
        timeframe: str = '1h',
        since: Optional[datetime] = None,
        limit: int = 100
    ) -> List[List]:
        """Get OHLCV data from pricing service.
        
        Args:
            symbol: Trading symbol
            timeframe: Timeframe
            since: Start datetime
            limit: Number of candles
            
        Returns:
            List of OHLCV candles
        """
        return self._pricing_service.get_ohlcv(symbol, timeframe, since, limit)


# Global data collector
_data_collector: Optional[DataCollector] = None


def get_data_collector() -> DataCollector:
    """Get global data collector instance."""
    global _data_collector
    if _data_collector is None:
        _data_collector = DataCollector()
    return _data_collector

