"""ADR-019 Phase 6：每日資料新鮮度主動巡檢。

每天 09:00 由 OpenClawBot scheduler 觸發，檢查 realtime_sales_monthly 最新資料
日期，若落後超過閾值就透過 EventRouter 主動發 Telegram 警告，避免用戶月初/
ETL 卡住才靠按按鈕踩坑發現。

EventRouter severity 對應：
- gap == 0：今日資料已進，靜默不發
- gap == 1：昨日資料齊全，info（不發或只 log）
- gap == 2~3：warning，可能 ETL 跑慢
- gap >= 4：alert（P2），ETL 大概率出問題
"""

from __future__ import annotations

from datetime import datetime, date
import logging

from services.event_router import dispatch_sync

logger = logging.getLogger("DataFreshnessProbe")

_DEFAULT_WARN_GAP_DAYS = 2
_DEFAULT_ALERT_GAP_DAYS = 4


def _query_latest_date():
    """獨立 import 避免循環依賴。回傳 'YYYY-MM-DD' 字串或 None。"""
    try:
        from routes.openclaw_bot_routes import latest_date
        return latest_date()
    except Exception as e:
        logger.warning(f"[DataFreshnessProbe] 取得 latest_date 失敗：{e}")
        return None


def _parse_date(s: str) -> date | None:
    if not s:
        return None
    try:
        return datetime.strptime(s.replace('/', '-'), '%Y-%m-%d').date()
    except (ValueError, AttributeError):
        return None


def run_data_freshness_probe(
    warn_gap_days: int = _DEFAULT_WARN_GAP_DAYS,
    alert_gap_days: int = _DEFAULT_ALERT_GAP_DAYS,
) -> dict:
    """主動巡檢一次，缺資料時透過 EventRouter 發通知。回傳 probe 結果摘要。"""
    today = date.today()
    latest_str = _query_latest_date()
    latest_dt = _parse_date(latest_str)

    result = {
        'today': today.isoformat(),
        'latest_date': latest_str,
        'gap_days': None,
        'severity': 'unknown',
        'notified': False,
    }

    if latest_dt is None:
        logger.error("[DataFreshnessProbe] 無法取得 latest_date — 視為嚴重異常")
        result['severity'] = 'alert'
        try:
            dispatch_sync({
                'source': 'OpenClawBot.DataFreshnessProbe',
                'event_type': 'data_freshness_unknown',
                'severity': 'alert',
                'title': '⚠️ 資料新鮮度巡檢失敗',
                'status': '無法取得 latest_date',
                'impact': 'P2 — 業績資料源不可達，所有報表 / NL 查詢可能失準',
                'summary': '請檢查 realtime_sales_monthly 表與 DB 連線。',
            })
            result['notified'] = True
        except Exception as e:
            logger.error(f"[DataFreshnessProbe] EventRouter dispatch 失敗：{e}")
        return result

    gap = (today - latest_dt).days
    result['gap_days'] = gap

    if gap <= 0:
        result['severity'] = 'success'
        logger.info(f"[DataFreshnessProbe] 資料齊全（latest={latest_dt}, today={today}）")
        return result

    if gap == 1:
        result['severity'] = 'info'
        logger.info(f"[DataFreshnessProbe] 落後 1 天（正常作息，ETL 通常隔天匯入）")
        return result

    if gap < warn_gap_days:
        result['severity'] = 'info'
        return result

    severity = 'alert' if gap >= alert_gap_days else 'warning'
    result['severity'] = severity

    try:
        dispatch_sync({
            'source': 'OpenClawBot.DataFreshnessProbe',
            'event_type': 'data_freshness_lag',
            'severity': severity,
            'title': f'📊 業績資料落後 {gap} 天',
            'status': f'最新資料：{latest_str}（今日：{today.isoformat()}）',
            'impact': (
                f'P2 — 月報/日報 PPT 與 NL 業績查詢可能空白或失準，'
                f'請檢查 realtime_sales_monthly ETL 任務（run_momo_task / run_auto_import_task）'
                if severity == 'alert' else
                f'P3 — 資料落後 {gap} 天，請確認 ETL 是否正常排程'
            ),
            'summary': f'gap={gap}d, latest={latest_str}',
            'payload': {
                'gap_days': gap,
                'latest_date': latest_str,
                'probe_at': datetime.now().isoformat(timespec='seconds'),
            },
        })
        result['notified'] = True
        logger.warning(
            f"[DataFreshnessProbe] {severity}: gap={gap}d, latest={latest_str} → notified"
        )
    except Exception as e:
        logger.error(f"[DataFreshnessProbe] EventRouter dispatch 失敗：{e}")

    return result
