from __future__ import annotations

import json
from datetime import datetime, timedelta, timezone
from typing import TYPE_CHECKING, Any, Callable

from backend.data.providers.ifind_client import IfindHttpClient
from backend.data.providers.tushare_client import TushareClient, TushareError

if TYPE_CHECKING:
    from database import ReviewDatabase


CHINA_TIMEZONE = timezone(timedelta(hours=8))

def _display_date(value: str) -> str:
    text = str(value or "").replace("-", "")
    if len(text) != 8:
        return str(value or "")
    return f"{text[:4]}-{text[4:6]}-{text[6:]}"


class MarketInsightsContextMixin:
    def __init__(
        self,
        database: ReviewDatabase,
        client: TushareClient,
        now_provider: Callable[[], datetime] | None = None,
        ifind: IfindHttpClient | None = None,
    ) -> None:
        self.database = database
        self.client = client
        self._now_provider = now_provider or (lambda: datetime.now(CHINA_TIMEZONE))
        self.ifind = ifind

    def _trade_context(self, requested_date: str) -> tuple[str, str]:
        """Resolve trading dates without making cached feature pages depend on Tushare uptime."""
        requested = str(requested_date or "").replace("-", "")
        try:
            return self.client.resolve_trade_context(requested)
        except TushareError:
            latest = self.database.get_latest_real_snapshot(requested) or {}
            trade_date = str(
                (latest.get("meta") or {}).get("trade_date")
                or latest.get("_snapshot_date")
                or requested
            ).replace("-", "")
            previous = self.database.get_latest_real_snapshot(trade_date, strictly_before=True) or {}
            previous_date = str(
                (previous.get("meta") or {}).get("trade_date")
                or previous.get("_snapshot_date")
                or ""
            ).replace("-", "")
            return trade_date, previous_date

    def _latest_feature_snapshot(self, kind: str, trade_date: str) -> dict[str, Any] | None:
        return self.database.get_latest_data_snapshot(kind, "", trade_date)

    def _stock_master(self) -> dict[str, dict[str, Any]]:
        rows = self.database.list_stock_master()
        if not rows:
            rows = self.client.query(
                "stock_basic",
                {"list_status": "L"},
                "ts_code,name,industry,market,list_date",
            )
            self.database.upsert_stock_master(rows)
            rows = self.database.list_stock_master()
        return {str(row.get("ts_code") or ""): row for row in rows}

    @staticmethod
    def _parse_concepts(value: Any) -> list[str]:
        if isinstance(value, list):
            return [str(item) for item in value if str(item).strip()]
        text = str(value or "").strip()
        if not text:
            return []
        try:
            parsed = json.loads(text)
            if isinstance(parsed, list):
                return [str(item) for item in parsed if str(item).strip()]
        except json.JSONDecodeError:
            pass
        return [part.strip() for part in text.split(",") if part.strip()]
