"""
Hộp Đen Lưu Trữ Telemetry & Sự Kiện Tử Vận (Blackbox Telemetry Recorder)
Duy trì Ring Buffer 120 ticks gần nhất phục vụ phân tích nguyên nhân tử vong (Root Cause Analysis).
"""

import json
import logging
import os
import time
from collections import deque
from typing import Any, Dict, List, Optional

from src.assistant_tool.core_shm_bridge import CoreTelemetrySnapshot

logger = logging.getLogger("BlackboxRecorder")


class BlackboxRecorder:
    """
    Bộ ghi đệm hộp đen Telemetry (Circular Ring Buffer).
    Lưu trữ 120 ticks gần nhất (tương đương 4-10 giây thực chiến trước sự kiện).
    """

    def __init__(self, capacity: int = 120, output_dir: str = "captures"):
        self.capacity = capacity
        self.output_dir = output_dir
        self.buffer: deque = deque(maxlen=capacity)
        self.last_export_path: Optional[str] = None
        os.makedirs(self.output_dir, exist_ok=True)

    def record_snapshot(self, snapshot: CoreTelemetrySnapshot) -> None:
        """Ghi nhận 1 snapshot từ ShmBridge vào Ring Buffer."""
        p = snapshot.player
        tick_data = {
            "snapshot_id": snapshot.snapshot_id,
            "timestamp_ms": snapshot.timestamp_ms or int(time.time() * 1000),
            "hp": p.current_hp,
            "max_hp": p.max_hp,
            "hp_pct": round(p.hp_percentage, 2),
            "mana": p.current_mana,
            "max_mana": p.max_mana,
            "es": p.current_es,
            "max_es": p.max_es,
            "spirit": p.current_spirit,
            "max_spirit": p.max_spirit,
            "pos_xyz": [round(p.pos_x, 2), round(p.pos_y, 2), round(p.pos_z, 2)],
            "monsters_count": snapshot.monsters_count,
            "items_count": snapshot.items_count,
            "portals_count": snapshot.portals_count,
            "area_name": snapshot.area_name,
            "area_level": snapshot.area_level,
        }
        self.buffer.append(tick_data)

    def get_recent_ticks(self, count: Optional[int] = None) -> List[Dict[str, Any]]:
        """Lấy danh sách các ticks gần nhất."""
        data = list(self.buffer)
        if count and count < len(data):
            return data[-count:]
        return data

    def export_blackbox(self, trigger_reason: str = "PLAYER_DEATH", extra_context: Optional[Dict[str, Any]] = None) -> str:
        """
        Khóa và kết xuất toàn bộ Ring Buffer ra tệp JSON phục vụ Reflection Critic.
        """
        ticks = list(self.buffer)
        if not ticks:
            logger.warning("[Blackbox] Ring buffer rỗng, không thể xuất blackbox.")
            return ""

        timestamp_str = time.strftime("%Y%m%d_%H%M%S")
        filename = f"blackbox_{trigger_reason.lower()}_{timestamp_str}.json"
        filepath = os.path.join(self.output_dir, filename)

        first_tick = ticks[0]
        last_tick = ticks[-1]
        hp_drop = first_tick.get("hp", 0) - last_tick.get("hp", 0)
        duration_ms = last_tick.get("timestamp_ms", 0) - first_tick.get("timestamp_ms", 0)

        payload = {
            "metadata": {
                "trigger_reason": trigger_reason,
                "exported_at": time.strftime("%Y/%m/%d %H:%M:%S"),
                "ticks_count": len(ticks),
                "duration_ms": duration_ms,
                "hp_drop_total": max(0, hp_drop),
                "area_name": last_tick.get("area_name", "Unknown"),
                "area_level": last_tick.get("area_level", 0),
                "extra_context": extra_context or {}
            },
            "telemetry_ticks": ticks
        }

        try:
            with open(filepath, "w", encoding="utf-8") as f:
                json.dump(payload, f, indent=2, ensure_ascii=False)
            self.last_export_path = filepath
            logger.info(f"[Blackbox] Đã lưu hộp đen tại: {filepath}")
            return filepath
        except Exception as e:
            logger.error(f"[Blackbox] Lỗi ghi file: {e}")
            return ""
