# app/src/integrations/exchange/market_stream.py

from __future__ import annotations

import asyncio
from src.core.config import load_settings
from src.integrations.exchange.service import ExchangeService
from src.integrations.exchange.ws_client import ExchangeWebSocketClient
from src.market_data.acquisition.adapters.dzengi.websocket import (
    DzengiWebSocketQuoteAdapter,
)
from src.market_data.acquisition.exceptions import (
    MarketDataAcquisitionError,
)
from src.storage.quote_store import (
    QUOTE_RUNTIME_SOURCE_NAME,
    get_quote_store,
)
from src.trading.journal.service import JournalService


# запускает постоянный websocket-поток рынка и обновляет Quote Store
async def start_market_stream() -> None:
    settings = load_settings()
    journal = JournalService()

    if not settings.exchange_enabled:
        return

    while True:
        try:
            service = ExchangeService()
            validation = service.validate_symbol(settings.default_symbol)

            if not validation.is_valid:
                await asyncio.sleep(10)
                continue

            symbol = validation.normalized_symbol
            client = ExchangeWebSocketClient()
            adapter = DzengiWebSocketQuoteAdapter()

            journal.log_info(
                "market_ws_started",
                "WebSocket market stream запущен.",
                {"symbol": symbol},
            )

            async for message in client.stream_depth(symbol):
                try:
                    quote = adapter.map_message(message)
                except MarketDataAcquisitionError:
                    continue

                if quote.symbol.strip().upper() != symbol.strip().upper():
                    continue

                get_quote_store().set(
                    QUOTE_RUNTIME_SOURCE_NAME,
                    quote,
                    runtime_key="default",
                )

        except asyncio.CancelledError:
            raise

        except Exception as exc:
            try:
                journal.log_warning(
                    "market_ws_reconnect",
                    f"WebSocket market stream будет переподключен: {exc}",
                    {"raw_error": str(exc)},
                )
            except Exception:
                pass

            await asyncio.sleep(5)