from __future__ import annotations

import hashlib
import json
from datetime import datetime
from typing import Any
from zoneinfo import ZoneInfo

from backend.features.screener.cross_section import finalize_factor_rows
from backend.features.screener.engine import FACTOR_MINIMUM_COVERAGE
from backend.features.screener.technical import build_technical_rows

SHANGHAI = ZoneInfo("Asia/Shanghai")


def build_factor_snapshot(
    trade_date: str,
    inputs: dict[str, Any],
    coverage: dict[str, float],
    sources: list[str],
) -> dict[str, Any]:
    ready = {
        dataset: coverage.get(dataset, 0) >= minimum
        for dataset, minimum in FACTOR_MINIMUM_COVERAGE.items()
    }
    ready["limit_events"] = coverage.get("limit_events", 0) >= 1
    rows = finalize_factor_rows(build_technical_rows(trade_date, inputs, ready), ready)
    canonical = json.dumps(
        {"trade_date": trade_date, "coverage": coverage, "rows": rows},
        ensure_ascii=False,
        separators=(",", ":"),
        sort_keys=True,
    )
    version = hashlib.sha256(canonical.encode("utf-8")).hexdigest()[:16]
    return {
        "trade_date": trade_date,
        "version": version,
        "observed_at": datetime.now(SHANGHAI).isoformat(timespec="seconds"),
        "coverage": coverage,
        "sources": sorted(set(sources)),
        "rows": rows,
    }
