"""
AI Provider 版本追蹤器 — 每小時探測 5 Provider 並寫入 DB，偵測版本變更

職責：
  - 排程呼叫 probe_all_providers()
  - 與 DB 最後一筆比對，判斷 changed 旗標
  - 寫入 AIProviderVersionHistory
  - 若有 changed → 記錄 warning log（P3.2.3 alerter 後續整合）

# 2026-04-27 P3.2.2 by Claude
"""
from __future__ import annotations

import asyncio

import structlog

logger = structlog.get_logger(__name__)


class ModelVersionTracker:
    """每小時探測所有 AI Provider 版本並寫入 DB"""

    async def run_probe_cycle(self) -> dict:
        """執行一輪探測：probe → 比對上一筆 → 寫入 DB

        Returns:
            dict with keys:
              - probed  : int  — 成功探測的 provider 數
              - changed : list[str] — 版本有變更的 provider names
        """
        from src.db.base import get_db_context
        from src.db.models import AIProviderVersionHistory
        from src.services.model_version_probe import probe_all_providers
        from sqlalchemy import desc, select

        results = await probe_all_providers()
        changed_providers: list[str] = []

        async with get_db_context() as db:
            for info in results:
                # 取最近一筆比對
                stmt = (
                    select(AIProviderVersionHistory)
                    .where(AIProviderVersionHistory.provider == info.provider)
                    .order_by(desc(AIProviderVersionHistory.captured_at))
                    .limit(1)
                )
                last = (await db.execute(stmt)).scalar_one_or_none()

                changed = (
                    last is None
                    or last.version != info.version
                    or last.digest != info.digest
                )

                if changed:
                    changed_providers.append(info.provider)

                db.add(
                    AIProviderVersionHistory(
                        provider=info.provider,
                        model=info.model,
                        version=info.version,
                        digest=info.digest,
                        captured_at=info.captured_at,
                        prev_version=last.version if last else None,
                        changed=changed,
                    )
                )

            await db.commit()

        if changed_providers:
            logger.warning(
                "provider_version_changed",
                changed=changed_providers,
                total_probed=len(results),
            )
            # P3.2.3: Telegram 告警（dedup 1h/provider）
            try:
                from src.services.failover_alerter import get_failover_alerter
                await get_failover_alerter().alert_provider_version_changed(
                    changed_providers=changed_providers,
                    probed=len(results),
                )
            except Exception as _alert_err:
                logger.warning("provider_version_alert_failed", error=str(_alert_err))
        else:
            logger.info(
                "provider_version_stable",
                total_probed=len(results),
            )

        return {"probed": len(results), "changed": changed_providers}


# =============================================================================
# Singleton
# =============================================================================

_tracker: ModelVersionTracker | None = None


def get_model_version_tracker() -> ModelVersionTracker:
    """取得 ModelVersionTracker singleton"""
    global _tracker
    if _tracker is None:
        _tracker = ModelVersionTracker()
    return _tracker
