"""AutoPOE2 - Atlas Progression & Reward Service (Doc 70 / Chu Kỳ 6).
=====================================================================
Service tích hợp quản trị tiến trình Atlas và thẩm định phần thưởng hậu cần:
1. Tự động cập nhật đồ thị bản đồ Atlas (mark_node_completed, Frontier Expansion).
2. Tự động cấp điểm thưởng Cây Nội Tại Atlas (Atlas Tree Allocation DAG) qua AtlasTreePlanner.
3. Thẩm định và theo dõi tăng trưởng tài sản ròng tích lũy (Real-Time Net Worth Tracking) qua NetWorthEstimator.
4. Xuất báo cáo tổng kết tiến trình và phần thưởng (MapCompletionRewardResult) chuẩn Rule 5.

Tuân thủ nghiêm ngặt:
- Rule 1: Cold Path Tier 2 (Python 3.11).
- Rule 4: Module hóa độc lập, trần file < 500 dòng, không chèn mã cứng vào Coordinator.
- Rule 5: Empirical DoD & Báo cáo gắn nhãn [MÔ PHỎNG THUẬT TOÁN HEADLESS - KHÔNG PHẢI LIVE GAME].
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Dict, List, Optional

from src.assistant_tool.atlas.graph import (
    AtlasGraph,
    AtlasGraphNode,
    NodeProgressionState,
)
from src.assistant_tool.atlas.atlas_tree_planner import (
    AtlasPassiveNode,
    AtlasTreePlanner,
    TreePhase,
)
from src.assistant_tool.currency_exchange.net_worth_estimator import (
    NetWorthEstimator,
    NetWorthReport,
)


@dataclass
class MapCompletionRewardResult:
    """Kết quả tổng hợp phần thưởng và tiến trình sau khi hoàn thành một bản đồ."""
    map_node_id: str
    map_name: str
    map_tier: int
    bonus_completed: bool
    newly_allocated_passive: Optional[AtlasPassiveNode]
    total_atlas_passive_points: int
    current_tree_phase: str
    frontier_count: int
    atlas_completion_pct: float
    current_net_worth_chaos: float
    current_net_worth_divine: float
    delta_net_worth_chaos: float
    delta_net_worth_divine: float
    liquid_assets: Dict[str, int]
    timestamp: str = field(default_factory=lambda: datetime.now().isoformat())


class AtlasProgressionService:
    """Service điều phối tiến trình đồ thị Atlas và phần thưởng tài sản ròng."""

    def __init__(
        self,
        atlas_graph: Optional[AtlasGraph] = None,
        tree_planner: Optional[AtlasTreePlanner] = None,
        net_worth_estimator: Optional[NetWorthEstimator] = None,
    ):
        self.atlas_graph: AtlasGraph = (
            atlas_graph if atlas_graph is not None else AtlasGraph.create_canonical_atlas_graph(115)
        )
        self.tree_planner: AtlasTreePlanner = (
            tree_planner if tree_planner is not None else AtlasTreePlanner()
        )
        self.net_worth_estimator: NetWorthEstimator = (
            net_worth_estimator if net_worth_estimator is not None else NetWorthEstimator()
        )

        self._history: List[MapCompletionRewardResult] = []
        self._last_net_worth_chaos: float = 0.0
        self._last_net_worth_divine: float = 0.0
        self._initial_net_worth_recorded: bool = False

    @property
    def history(self) -> List[MapCompletionRewardResult]:
        return list(self._history)

    @property
    def total_maps_processed(self) -> int:
        return len(self._history)

    def on_map_completed(
        self,
        node_id: str,
        bonus_completed: bool = True,
        wallet: Optional[Dict[str, int]] = None,
        stash_items: Optional[List[Dict[str, Any]]] = None,
        current_gold: int = 0,
    ) -> MapCompletionRewardResult:
        """
        Xử lý sự kiện hoàn thành bản đồ:
        1. Cập nhật trạng thái đồ thị Atlas và kích hoạt Frontier Expansion.
        2. Nếu bonus_completed, tự động phân bổ điểm Cây Nội Tại tiếp theo theo DAG.
        3. Định giá tài sản ròng hiện tại và tính mức tăng trưởng (Delta) so với map trước.
        4. Lưu trữ lịch sử và trả về báo cáo kết quả.
        """
        # 1. Đánh dấu hoàn thành trên đồ thị Atlas
        node = self.atlas_graph.get_node(node_id)
        map_name = node.name if node else f"Unknown Map ({node_id})"
        map_tier = node.tier if node else 1

        self.atlas_graph.mark_node_completed(node_id, bonus=bonus_completed)
        frontier_nodes = self.atlas_graph.get_frontier_nodes()
        completion_stats = self.atlas_graph.get_completion_stats()

        # 2. Phân bổ điểm Cây Nội Tại Atlas nếu đạt bonus
        newly_allocated: Optional[AtlasPassiveNode] = None
        if bonus_completed:
            newly_allocated = self.tree_planner.allocate_next_point()

        tree_stats = self.tree_planner.get_tree_stats()

        # 3. Tính toán giá trị ròng ví & kho đồ
        wallet_data = wallet or {}
        stash_data = stash_items or []
        nw_report: NetWorthReport = self.net_worth_estimator.calculate_net_worth(
            wallet=wallet_data,
            stash_items=stash_data,
            current_gold=current_gold,
        )

        current_chaos = nw_report.total_net_worth_chaos
        current_divine = nw_report.total_net_worth_divine

        if not self._initial_net_worth_recorded:
            delta_chaos = 0.0
            delta_divine = 0.0
            self._initial_net_worth_recorded = True
        else:
            delta_chaos = current_chaos - self._last_net_worth_chaos
            delta_divine = current_divine - self._last_net_worth_divine

        self._last_net_worth_chaos = current_chaos
        self._last_net_worth_divine = current_divine

        liquid_assets = {
            "Chaos Orb": nw_report.liquid_chaos,
            "Divine Orb": nw_report.liquid_divine,
            "Mirror of Kalandra": nw_report.liquid_mirror,
            "Gold": nw_report.gold_balance,
        }

        # 4. Tạo kết quả tổng hợp
        result = MapCompletionRewardResult(
            map_node_id=node_id,
            map_name=map_name,
            map_tier=map_tier,
            bonus_completed=bonus_completed,
            newly_allocated_passive=newly_allocated,
            total_atlas_passive_points=tree_stats["total_allocated_points"],
            current_tree_phase=tree_stats["current_phase"],
            frontier_count=len(frontier_nodes),
            atlas_completion_pct=completion_stats["completion_rate"],
            current_net_worth_chaos=current_chaos,
            current_net_worth_divine=current_divine,
            delta_net_worth_chaos=delta_chaos,
            delta_net_worth_divine=delta_divine,
            liquid_assets=liquid_assets,
        )

        self._history.append(result)
        return result

    def format_reward_report(self, result: MapCompletionRewardResult) -> str:
        """Định dạng báo cáo tổng kết sau map chuẩn Rule 5 (ASCII-safe)."""
        lines = [
            "=" * 78,
            " [MO PHONG THUAT TOAN HEADLESS - KHONG PHAI LIVE GAME]",
            " BAO CAO TIEN TRINH ATLAS & PHAN THUONG HAU CAN (ATLAS REWARD SERVICE)",
            "=" * 78,
            f" Map Vua Hoan Thanh   : [{result.map_node_id}] {result.map_name} (Tier {result.map_tier})",
            f" Trang Thai Bonus      : {'DAT BONUS (+1 Atlas Point)' if result.bonus_completed else 'KHONG CO BONUS'}",
            f" Node Bien Moi (Frontier): {result.frontier_count} maps tiep theo da san sang",
            f" Tien Do Atlas Graph   : {result.atlas_completion_pct:.1f}%",
            "-" * 78,
            " TIEN TRINH CAY NOI TAI ATLAS (ATLAS PASSIVE TREE):",
            f"   * Tong diem da phan bo : {result.total_atlas_passive_points} / {self.tree_planner.total_nodes}",
            f"   * Giai doan cay hien tai: {result.current_tree_phase}",
        ]

        if result.newly_allocated_passive:
            p = result.newly_allocated_passive
            lines.extend([
                f"   * Diem vua mo khoa     : [Rank {p.priority_order}] {p.name} ({p.category})",
                f"     Hieu ung             : {p.stat_description}",
            ])
        else:
            lines.append("   * Diem vua mo khoa     : Khong co (Chua dat bonus hoac cay da full)")

        lines.extend([
            "-" * 78,
            " THAM DINH TAI SAN RONG (NET WORTH VALUATION):",
            f"   * Tong tai san rong    : {result.current_net_worth_chaos:,.1f} Chaos (~{result.current_net_worth_divine:.2f} Divine)",
            f"   * Tang truong map nay  : +{result.delta_net_worth_chaos:,.1f} Chaos (+{result.delta_net_worth_divine:.2f} Divine)",
            f"   * Tien mat kha dung    : {result.liquid_assets.get('Chaos Orb', 0)} C | {result.liquid_assets.get('Divine Orb', 0)} Div | {result.liquid_assets.get('Mirror of Kalandra', 0)} Mir",
            f"   * Quy vang (Gold)      : {result.liquid_assets.get('Gold', 0):,} Gold",
            "=" * 78,
        ])
        return "\n".join(lines)

    def get_aggregate_summary(self) -> Dict[str, Any]:
        """Tổng kết toàn bộ chu kỳ cày cuốc kể từ khi khởi động service."""
        total_maps = len(self._history)
        total_points = self.tree_planner.allocated_count
        tree_stats = self.tree_planner.get_tree_stats()
        graph_stats = self.atlas_graph.get_completion_stats()

        initial_chaos = self._history[0].current_net_worth_chaos if self._history else 0.0
        final_chaos = self._last_net_worth_chaos
        chaos_gained = max(0.0, final_chaos - initial_chaos)

        return {
            "total_maps_completed": total_maps,
            "total_passive_points": total_points,
            "tree_completion_pct": tree_stats["completion_pct"],
            "current_tree_phase": tree_stats["current_phase"],
            "atlas_graph_completion_pct": graph_stats["completion_rate"],
            "current_net_worth_chaos": final_chaos,
            "current_net_worth_divine": self._last_net_worth_divine,
            "cumulative_chaos_gain": chaos_gained,
        }

