#!/usr/bin/env python3
"""
``result_report`` 按 simulator 槽位的读/写适配；枚举写入前的摘要整形亦在本模块。

保持 ``cache_service.SimulatorResDbCacheService`` 仅负责表操作。
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional, Tuple

from core.modules.strategy.enums import Simulator

from .cache_service import SimulatorResDbCacheService
from .report_slot_disk_hydrate import (
    attach_enum_opportunities_field,
    compact_capital_slot_for_cache,
    compact_enum_slot_for_cache,
    hydrate_capital_slot,
    hydrate_enum_slot,
)


def sanitize_enum_payload_for_snapshot(payload: Dict[str, Any]) -> Dict[str, Any]:
    """浅拷贝并去掉值为 ``None`` 的顶层键，便于 JSON 落库。"""
    raw = dict(payload or {})
    return {k: v for k, v in raw.items() if v is not None}


def lookup_enum_cache(
    strategy_name: str,
    settings_finger_print_id: str,
    env_fingerprint_id: str,
) -> Optional[Tuple[List[Dict[str, Any]], int]]:
    """双指纹命中且 ``result_report.enum`` 为非空 dict 时返回 ``([payload], workbench_version)``。"""
    sn = str(strategy_name).strip()
    sfp = str(settings_finger_print_id or "").strip()
    efp = str(env_fingerprint_id or "").strip()
    svc = SimulatorResDbCacheService()
    row = svc.load_cache_by_fingerprints(sn, sfp, efp)
    if not row:
        return None
    wb_version = int((row or {}).get("version") or 0)
    rr = dict((row or {}).get("result_report") or {})
    slot = rr.get("enum")
    if not isinstance(slot, dict) or not slot:
        return None
    hydrated = attach_enum_opportunities_field(hydrate_enum_slot(sn, slot))
    if not isinstance(hydrated, dict) or not hydrated:
        return None
    return ([hydrated], wb_version)


def persist_enum_snapshot(
    strategy_name: str,
    *,
    settings_snapshot_api: Dict[str, Any],
    report_enum: Dict[str, Any],
    settings_fingerprint_id: str,
    env_fingerprint_id: str,
) -> int:
    """写入或合并 ``enum`` 槽位。"""
    slim = compact_enum_slot_for_cache(str(strategy_name).strip(), dict(report_enum or {}))
    return SimulatorResDbCacheService().set_cache(
        strategy_name=str(strategy_name),
        settings_snapshot=dict(settings_snapshot_api or {}),
        simulator=Simulator.ENUMERATOR,
        simulator_report=slim,
        settings_fingerprint_id=str(settings_fingerprint_id or "").strip(),
        env_fingerprint_id=str(env_fingerprint_id or "").strip(),
    )


def lookup_price_factor_cache(
    strategy_name: str,
    settings_finger_print_id: str,
    env_fingerprint_id: str,
) -> Optional[Tuple[Dict[str, Any], int]]:
    """双指纹命中且 ``result_report.price_factor`` 为非空 dict 时返回 ``(payload, workbench_version)``。"""
    svc = SimulatorResDbCacheService()
    row = svc.load_cache_by_fingerprints(
        str(strategy_name),
        str(settings_finger_print_id or "").strip(),
        str(env_fingerprint_id or "").strip(),
    )
    if not row:
        return None
    wb_version = int((row or {}).get("version") or 0)
    rr = dict((row or {}).get("result_report") or {})
    slot = rr.get("price_factor")
    if not isinstance(slot, dict) or not slot:
        return None
    return (slot, wb_version)


def persist_price_factor_snapshot(
    strategy_name: str,
    *,
    settings_snapshot_api: Dict[str, Any],
    report_price_factor: Dict[str, Any],
    settings_fingerprint_id: str,
    env_fingerprint_id: str,
) -> int:
    """写入或合并 ``price_factor`` 槽位。"""
    return SimulatorResDbCacheService().set_cache(
        strategy_name=str(strategy_name),
        settings_snapshot=dict(settings_snapshot_api or {}),
        simulator=Simulator.PRICE_FACTOR,
        simulator_report=dict(report_price_factor or {}),
        settings_fingerprint_id=str(settings_fingerprint_id or "").strip(),
        env_fingerprint_id=str(env_fingerprint_id or "").strip(),
    )


def lookup_capital_allocation_cache(
    strategy_name: str,
    settings_finger_print_id: str,
    env_fingerprint_id: str,
) -> Optional[Tuple[Dict[str, Any], int]]:
    """双指纹命中且 ``result_report.capital_allocation`` 为非空 dict 时返回 ``(payload, workbench_version)``。"""
    svc = SimulatorResDbCacheService()
    row = svc.load_cache_by_fingerprints(
        str(strategy_name),
        str(settings_finger_print_id or "").strip(),
        str(env_fingerprint_id or "").strip(),
    )
    if not row:
        return None
    wb_version = int((row or {}).get("version") or 0)
    rr = dict((row or {}).get("result_report") or {})
    slot = rr.get("capital_allocation")
    if not isinstance(slot, dict) or not slot:
        return None
    hydrated = hydrate_capital_slot(str(strategy_name).strip(), slot)
    return (hydrated, wb_version)


def persist_capital_allocation_snapshot(
    strategy_name: str,
    *,
    settings_snapshot_api: Dict[str, Any],
    report_capital_allocation: Dict[str, Any],
    settings_fingerprint_id: str,
    env_fingerprint_id: str,
    capital_output_version_dir: Optional[str] = None,
) -> int:
    """写入或合并 ``capital_allocation`` 槽位。"""
    sn = str(strategy_name).strip()
    raw = dict(report_capital_allocation or {})
    to_save = raw
    vd = str(capital_output_version_dir or "").strip()
    if vd:
        to_save = compact_capital_slot_for_cache(sn, raw, capital_output_version_dir=vd)
    return SimulatorResDbCacheService().set_cache(
        strategy_name=str(strategy_name),
        settings_snapshot=dict(settings_snapshot_api or {}),
        simulator=Simulator.CAPITAL_ALLOCATION,
        simulator_report=to_save,
        settings_fingerprint_id=str(settings_fingerprint_id or "").strip(),
        env_fingerprint_id=str(env_fingerprint_id or "").strip(),
    )


__all__ = [
    "lookup_capital_allocation_cache",
    "lookup_enum_cache",
    "lookup_price_factor_cache",
    "persist_capital_allocation_snapshot",
    "persist_enum_snapshot",
    "persist_price_factor_snapshot",
    "sanitize_enum_payload_for_snapshot",
]
