from __future__ import annotations

import logging
import time
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from opendeviationbar.config.backfill import BackfillConfig
    from opendeviationbar.config.resilience import ResilienceConfig
    from opendeviationbar.config.sidecar import SidecarConfig

logger = logging.getLogger(__name__)


def _resilience_cfg() -> ResilienceConfig:
    from opendeviationbar.config.resilience import ResilienceConfig

    return ResilienceConfig()


def _sidecar_cfg() -> SidecarConfig:
    from opendeviationbar.config.sidecar import SidecarConfig

    return SidecarConfig.from_env()


def _backfill_cfg() -> BackfillConfig:
    from opendeviationbar.config.backfill import BackfillConfig

    return BackfillConfig()


def _seed_trade_ids_from_clickhouse(
    engine: object,
    symbols: list[str],
    thresholds: list[int],
) -> None:
    """Seed StreamManager trade-ID tracker from ClickHouse last_agg_trade_id.

    Used by day-mode symbols only. Aion symbols use direct resume-TID
    seeding in _create_engine() --- no crossover override needed.
    """
    _rcfg = _resilience_cfg()
    for attempt in range(_rcfg.seed_max_attempts):
        try:
            from opendeviationbar.clickhouse.cache import OpenDeviationBarCache

            cache = OpenDeviationBarCache()
            seeded = 0
            for symbol in symbols:
                for threshold in thresholds:
                    try:
                        _ts, last_tid = cache.get_latest_bar_with_trade_id(
                            symbol, threshold
                        )
                        if last_tid is not None and last_tid > 0:
                            engine.seed_trade_id(symbol, threshold, last_tid)
                            seeded += 1
                    except (OSError, RuntimeError):
                        logger.debug(
                            "trade-ID seed query failed for %s@%d", symbol, threshold
                        )
        except (OSError, RuntimeError, ImportError):
            if attempt < _rcfg.seed_max_attempts - 1:
                logger.warning(
                    "trade-ID seeding attempt %d/%d failed, retrying in %ds",
                    attempt + 1,
                    _rcfg.seed_max_attempts,
                    _rcfg.seed_retry_delay_s,
                )
                time.sleep(_rcfg.seed_retry_delay_s)
            else:
                logger.warning(
                    "trade-ID seeding FAILED after %d attempts — "
                    "Rust gap detector will start unseeded",
                    _rcfg.seed_max_attempts,
                )
                _notify_seeding_failure()
        else:
            if seeded > 0:
                logger.info(
                    "seeded trade-ID continuity for %d pairs from ClickHouse", seeded
                )

            return  # success


def _notify_seeding_failure() -> None:
    """Send Telegram alert when trade-ID seeding fails after all retries."""
    try:
        from opendeviationbar.notify.telegram import _build_context_block, send_telegram

        msg = (
            "<b>⚠ Trade-ID Seeding Failed</b>\n"
            f"All {_resilience_cfg().seed_max_attempts} attempts failed. "
            "Rust gap detector starting unseeded — gaps after restart may not be detected."
            + _build_context_block("sidecar")
        )
        send_telegram(msg, disable_notification=False)
    except Exception:
        logger.exception("failed to send seeding failure notification")
