# app/src/trading/auto/service.py

from __future__ import annotations

import asyncio

from src.core.types import JsonDict
from src.trading.auto.auto_lifecycle import AutoLifecycleMixin
from src.trading.auto.state import AutoTradeState


class AutoTradeService(AutoLifecycleMixin):

    # GLOBAL SERVICE STATE
    # единый runtime state автоторговли
    # хранит:
    # - сигналы
    # - market context
    # - execution context
    # - PnL открытой позиции и реализованный PnL
    # - lifecycle
    # - protection state
    _state = AutoTradeState()

    # background asyncio loop task
    # нужен для continuous auto-trading worker
    # None -> loop не запущен
    _loop_task: asyncio.Task | None = None

    # интервал между auto-trading циклами
    # run_cycle() вызывается каждые N секунд
    _loop_interval_seconds: int = 5

    # SIGNAL CONFIRMATION ENGINE
    # минимальное количество одинаковых BUY/SELL подряд
    # чтобы сигнал считался подтвержденным
    _confirm_repeats: int = 2

    # минимальное время удержания сигнала
    # перед execution
    _confirm_min_duration_seconds: int = 10

    # EXECUTION CONFIDENCE RULES
    # минимальный confidence для READY state
    # ниже -> сигнал не считается готовым
    _ready_confidence = 0.45

    # минимальный execution confidence
    # для реального допуска execution engine
    _execution_confidence_required_score = 0.65

    # RUNTIME TTL
    # время жизни signal runtime
    # после ttl сигнал считается устаревшим
    _signal_ttl_seconds: int = 90

    # время жизни market analysis runtime
    # после ttl market context считается stale
    _market_analysis_ttl_seconds: int = 180

    # последний logged runtime expiration key
    # нужен чтобы не спамить одинаковыми логами
    _last_logged_runtime_expired_key: str | None = None

    # SIGNAL MEMORY
    # уникальный ключ последнего сигнала
    # используется для deduplication
    _last_signal_key: str | None = None

    # последнее signal значение:
    # BUY / SELL / HOLD
    _last_signal_value: str | None = None

    # последнее объяснение сигнала
    _last_signal_reason: str = ""

    # confidence последнего сигнала
    _last_signal_confidence: float = 0.0

    # полный payload последнего signal анализа
    # содержит market metrics / indicators / runtime info
    _last_signal_payload: JsonDict | None = None

    # monotonic timestamp начала сигнала
    # нужен для confirmation timing
    _last_signal_started_at: float | None = None

    # количество одинаковых сигналов подряд
    # используется confirmation engine
    _same_signal_count: int = 0

    # EXECUTION SNAPSHOT VALIDATION
    # максимальный допустимый возраст execution snapshot
    # старше -> snapshot stale
    _max_snapshot_age_seconds: float = 5.0

    # warning threshold snapshot age
    # выше -> degraded execution quality
    _warning_snapshot_age_seconds: float = 2.0

    # SPREAD RISK THRESHOLDS
    # asset-specific spread thresholds
    #
    # warning_enter:
    #   warning при входе
    #
    # warning_exit:
    #   warning при выходе
    #
    # block_enter:
    #   полный блок входа
    #
    # block_exit:
    #   полный блок выхода
    _spread_thresholds_by_asset: dict[str, dict[str, float]] = {
        "BTC": {
            "warning_enter": 0.08,
            "warning_exit": 0.06,
            "block_enter": 0.15,
            "block_exit": 0.12,
        },
        "ETH": {
            "warning_enter": 0.10,
            "warning_exit": 0.08,
            "block_enter": 0.18,
            "block_exit": 0.15,
        },
        "LTC": {
            "warning_enter": 0.18,
            "warning_exit": 0.14,
            "block_enter": 0.35,
            "block_exit": 0.28,
        },
        "XRP": {
            "warning_enter": 0.20,
            "warning_exit": 0.16,
            "block_enter": 0.40,
            "block_exit": 0.32,
        },
    }

    # default spread thresholds
    # используются если asset не найден
    _default_spread_thresholds: dict[str, float] = {
        "warning_enter": 0.12,
        "warning_exit": 0.09,
        "block_enter": 0.25,
        "block_exit": 0.20,
    }

    # последний logged execution quality key
    # нужен чтобы не спамить одинаковыми warning/block logs
    _last_logged_execution_quality_key: str | None = None