from __future__ import annotations

from typing import Any

from backend.data.numbers import finite_number as _number
from backend.features.screener.catalog import REGIMES
from backend.features.screener.indicators import _regime_reason
from backend.features.sentiment.engine import build_sentiment_history, latest_contiguous_history
from database import ReviewDatabase


class RegimeDetector:
    def __init__(self, database: ReviewDatabase) -> None:
        self.database = database

    def detect_regime(self, trade_date: str) -> dict[str, Any]:
        series = latest_contiguous_history(
            build_sentiment_history(self.database.list_snapshot_payloads(trade_date, 260))
        )
        if not series:
            return {
                "id": "repair", "label": REGIMES["repair"], "confidence": 25,
                "reason": "复盘快照不足，暂按中性修复处理。", "evidence": [], "history": [],
            }
        current = series[-1]
        previous = series[-2] if len(series) > 1 else current
        score = _number(current.get("score"))
        previous_score = _number(previous.get("score"))
        delta = score - previous_score
        seal_rate = _number(current.get("seal_rate"))
        limit_up = _number(current.get("limit_up_count"))
        broken = _number(current.get("broken_count"))
        regime = next(
            (key for key, label in REGIMES.items() if label == current.get("phase")),
            "divergence",
        )
        confidence = min(92, 45 + len(series[-8:]) * 5 + min(abs(delta), 12))
        evidence = [
            f"情绪温度 {score:.0f}，较前一交易日 {delta:+.0f}，{current.get('direction') or '持平'}",
            f"封板率 {seal_rate:.1f}%",
            f"涨停 {limit_up:.0f} 家，炸板 {broken:.0f} 家",
        ]
        return {
            "id": regime,
            "label": REGIMES[regime],
            "confidence": round(confidence),
            "reason": _regime_reason(regime),
            "evidence": evidence,
            "history": [
                {"trade_date": item["trade_date"], "score": _number(item.get("score"))}
                for item in series[-8:]
            ],
        }
