"""
Data Transfer Objects and Enums for FreeExile Endgame Infinite World Map & Content System.
Provides models for:
- EndGameStatus
- MapBiomeType
- ContentType (8 Savage Primal Encounters)
- MapNodeStatus
- MapContent
- MapNode
- AtlasWorldState
"""

from __future__ import annotations
from enum import Enum
from dataclasses import dataclass, field
from typing import List, Tuple, Optional, Dict, Any


class EndGameStatus(str, Enum):
    LOCKED = "LOCKED"
    ELIGIBLE = "ELIGIBLE"
    UNLOCKED = "UNLOCKED"


class MapBiomeType(str, Enum):
    BONE_STRAND = "BONE_STRAND"              # Bờ Đá Tàn Xương
    PUTRID_FEN = "PUTRID_FEN"                # Đầm Lầy Thối Rữa
    BONE_WASTES = "BONE_WASTES"              # Sa Cốt Hoang Mạc
    SLAUGHTER_RUINS = "SLAUGHTER_RUINS"      # Phế Tích Xẻ Thịt
    PRIMAL_ALTAR = "PRIMAL_ALTAR"            # Tế Đàn Man Hoang
    BILE_MIRE = "BILE_MIRE"                  # Vực Đầm Băng Độc
    GORGE_STARVED = "GORGE_STARVED"          # Vực Đói Nuốt Chửng
    BLOODFORGE = "BLOODFORGE"                # Miệng Lửa Nung Máu
    APEX_SLAUGHTER = "APEX_SLAUGHTER"        # Bệ Thờ Quỷ Đoạt Mệnh
    ABYSSAL_VOID = "ABYSSAL_VOID"            # Cõi Hư Không Tuyệt Địa


class ContentType(str, Enum):
    BLOOD_ALTAR = "BLOOD_ALTAR"              # Huyết Tế Trận
    ABYSSAL_FISSURE = "ABYSSAL_FISSURE"      # Khe Nứt Hư Không
    BONE_STRONGBOX = "BONE_STRONGBOX"        # Hòm Xương Ma Quỷ
    FERAL_ESSENCE = "FERAL_ESSENCE"          # Tàn Cốt Tinh Hoa
    SCOURGE_INCURSION = "SCOURGE_INCURSION"  # Thao Thiết Xâm Thực
    WARLORD_AMBUSH = "WARLORD_AMBUSH"        # Đột Kích Lãnh Chúa
    SMUGGLER_DEN = "SMUGGLER_DEN"            # Bí Thất Hắc Thị
    BEAST_HUNT = "BEAST_HUNT"                # Thần Thú Tế Đàn


class MapNodeStatus(str, Enum):
    UNREACHABLE = "UNREACHABLE"              # Bị sương mù che phủ
    DISCOVERED = "DISCOVERED"                # Đã phát hiện nhưng chưa thông đường
    ACCESSIBLE = "ACCESSIBLE"                # Có thể kích hoạt tại Bàn Kích Hoạt Tàn Đồ
    IN_PROGRESS = "IN_PROGRESS"              # Đang mở instance 6 cổng
    CLEARED = "CLEARED"                      # Đã hoàn thành, mở đường tới các node sau
    CORRUPTED = "CORRUPTED"                  # Dị biến tà huyết cực hạn


@dataclass(slots=True, frozen=True)
class MapContent:
    content_id: str
    content_type: ContentType
    name: str
    description: str
    difficulty_rating: int                   # 1 to 5 skulls
    reward_type: str                         # e.g., "Huyết Hồn Thạch", "Cổ Cốt Ấn", "Phôi Đồ iLvl 85+"
    spawn_coord: Tuple[float, float] = (0.0, 0.0)
    is_completed: bool = False

    def to_dict(self) -> Dict[str, Any]:
        return {
            "content_id": self.content_id,
            "content_type": self.content_type.value,
            "name": self.name,
            "description": self.description,
            "difficulty_rating": self.difficulty_rating,
            "reward_type": self.reward_type,
            "spawn_coord": list(self.spawn_coord),
            "is_completed": self.is_completed,
        }


@dataclass(slots=True, frozen=True)
class MapNode:
    node_id: str
    depth: int                               # Khoảng cách/tầng từ điểm khởi đầu (0 -> vô hạn)
    branch_index: int                        # Thứ tự nhánh
    grid_x: int                              # Tọa độ không gian bản đồ thế giới
    grid_y: int
    tier: int                                # Tier 1 - 16, 17+ (Über)
    biome: MapBiomeType
    name: str
    status: MapNodeStatus
    connected_node_ids: Tuple[str, ...]
    monster_level: int
    item_quantity_bonus_pct: int
    item_rarity_bonus_pct: int
    pack_size_bonus_pct: int
    affixes: Tuple[str, ...]
    boss_name: str
    contents: Tuple[MapContent, ...]
    completed_timestamp_ms: Optional[int] = None

    def to_dict(self) -> Dict[str, Any]:
        return {
            "node_id": self.node_id,
            "depth": self.depth,
            "branch_index": self.branch_index,
            "grid_x": self.grid_x,
            "grid_y": self.grid_y,
            "tier": self.tier,
            "biome": self.biome.value,
            "name": self.name,
            "status": self.status.value,
            "connected_node_ids": list(self.connected_node_ids),
            "monster_level": self.monster_level,
            "item_quantity_bonus_pct": self.item_quantity_bonus_pct,
            "item_rarity_bonus_pct": self.item_rarity_bonus_pct,
            "pack_size_bonus_pct": self.pack_size_bonus_pct,
            "affixes": list(self.affixes),
            "boss_name": self.boss_name,
            "contents": [c.to_dict() for c in self.contents],
            "completed_timestamp_ms": self.completed_timestamp_ms,
        }


@dataclass(slots=True)
class AtlasWorldState:
    player_id: str
    is_endgame_unlocked: bool = False
    world_seed: int = 12345
    current_origin_node_id: str = "node_d0_b0"
    unlocked_depth: int = 0
    nodes: Dict[str, MapNode] = field(default_factory=dict)
    total_maps_cleared: int = 0
    atlas_passive_points: int = 0
    active_node_id: Optional[str] = None
    created_timestamp_ms: int = 0

    def to_dict(self) -> Dict[str, Any]:
        return {
            "player_id": self.player_id,
            "is_endgame_unlocked": self.is_endgame_unlocked,
            "world_seed": self.world_seed,
            "current_origin_node_id": self.current_origin_node_id,
            "unlocked_depth": self.unlocked_depth,
            "nodes": {nid: n.to_dict() for nid, n in self.nodes.items()},
            "total_maps_cleared": self.total_maps_cleared,
            "atlas_passive_points": self.atlas_passive_points,
            "active_node_id": self.active_node_id,
            "created_timestamp_ms": self.created_timestamp_ms,
        }
