"""
FreeExile Map Progression Scaler & Labyrinth Dimension Architecture.
Computes authoritative world map dimensions, room counts, secret chambers,
and maze complexity strictly proportional to quest milestones and endgame tiers.
"""

from __future__ import annotations
import math
from dataclasses import dataclass
from typing import Dict, Optional, Tuple, Any


@dataclass(slots=True, frozen=True)
class MapScaleProfile:
    stage_id: str
    stage_name_vi: str
    stage_name_en: str
    level_min: int
    level_max: int
    grid_width: int
    grid_height: int
    min_rooms: int
    max_rooms: int
    secret_chambers: int
    pillar_totems: int
    branching_factor: float
    boss_distance_min: float
    is_labyrinth: bool
    content_mechanics_count: int

    @property
    def total_tiles(self) -> int:
        return self.grid_width * self.grid_height


PROGRESSION_PROFILES: Dict[str, MapScaleProfile] = {
    "ACT_I_ONBOARDING": MapScaleProfile(
        stage_id="ACT_I_ONBOARDING",
        stage_name_vi="Hồi I: Tân Thủ Bến Lưu Đày",
        stage_name_en="Act I: Outcast Onboarding",
        level_min=1,
        level_max=10,
        grid_width=60,
        grid_height=45,
        min_rooms=5,
        max_rooms=7,
        secret_chambers=0,
        pillar_totems=0,
        branching_factor=1.1,
        boss_distance_min=32.0,
        is_labyrinth=False,
        content_mechanics_count=1,
    ),
    "ACT_II_EXPLORATION": MapScaleProfile(
        stage_id="ACT_II_EXPLORATION",
        stage_name_vi="Hồi II: Đầm Lầy Bùn Nhục",
        stage_name_en="Act II: Miasma Swamps",
        level_min=11,
        level_max=25,
        grid_width=84,
        grid_height=64,
        min_rooms=8,
        max_rooms=12,
        secret_chambers=1,
        pillar_totems=1,
        branching_factor=1.4,
        boss_distance_min=55.0,
        is_labyrinth=False,
        content_mechanics_count=2,
    ),
    "ACT_III_SANDSTORM": MapScaleProfile(
        stage_id="ACT_III_SANDSTORM",
        stage_name_vi="Hồi III: Sa Mạc Bão Cát",
        stage_name_en="Act III: Crucible Sandstorm",
        level_min=26,
        level_max=45,
        grid_width=112,
        grid_height=84,
        min_rooms=12,
        max_rooms=18,
        secret_chambers=2,
        pillar_totems=2,
        branching_factor=1.8,
        boss_distance_min=80.0,
        is_labyrinth=False,
        content_mechanics_count=2,
    ),
    "ACT_IV_V_CRUCIBLE": MapScaleProfile(
        stage_id="ACT_IV_V_CRUCIBLE",
        stage_name_vi="Hồi IV-V: Trảm Thú Vực Sâu",
        stage_name_en="Act IV-V: Titan Depths",
        level_min=46,
        level_max=70,
        grid_width=148,
        grid_height=110,
        min_rooms=18,
        max_rooms=24,
        secret_chambers=3,
        pillar_totems=2,
        branching_factor=2.2,
        boss_distance_min=115.0,
        is_labyrinth=True,
        content_mechanics_count=3,
    ),
    "ENDGAME_WHITE_ATLAS": MapScaleProfile(
        stage_id="ENDGAME_WHITE_ATLAS",
        stage_name_vi="Tàn Đồ Sơ Kỳ (Tier 1-5)",
        stage_name_en="Endgame White Atlas (T1-5)",
        level_min=71,
        level_max=77,
        grid_width=176,
        grid_height=132,
        min_rooms=22,
        max_rooms=28,
        secret_chambers=3,
        pillar_totems=3,
        branching_factor=2.5,
        boss_distance_min=145.0,
        is_labyrinth=True,
        content_mechanics_count=3,
    ),
    "ENDGAME_YELLOW_RED_ATLAS": MapScaleProfile(
        stage_id="ENDGAME_YELLOW_RED_ATLAS",
        stage_name_vi="Tàn Đồ Trung Cao Kỳ (Tier 6-15)",
        stage_name_en="Endgame Yellow/Red Atlas (T6-15)",
        level_min=78,
        level_max=83,
        grid_width=208,
        grid_height=156,
        min_rooms=26,
        max_rooms=34,
        secret_chambers=4,
        pillar_totems=3,
        branching_factor=2.9,
        boss_distance_min=180.0,
        is_labyrinth=True,
        content_mechanics_count=4,
    ),
    "ENDGAME_PINNACLE_LABYRINTH": MapScaleProfile(
        stage_id="ENDGAME_PINNACLE_LABYRINTH",
        stage_name_vi="Đại Mê Cung Đỉnh Cao (Tier 16+)",
        stage_name_en="Pinnacle Über Labyrinth (T16+)",
        level_min=84,
        level_max=100,
        grid_width=240,
        grid_height=180,
        min_rooms=32,
        max_rooms=42,
        secret_chambers=6,
        pillar_totems=4,
        branching_factor=3.5,
        boss_distance_min=220.0,
        is_labyrinth=True,
        content_mechanics_count=5,
    ),
}


def calculate_map_scale_profile(
    level: int = 1,
    act_id: Optional[str] = None,
    map_tier: Optional[int] = None,
    zone_id: Optional[str] = None,
) -> MapScaleProfile:
    """Authoritatively computes the map scaling profile strictly proportional to progress."""
    if map_tier is not None and map_tier > 0:
        if map_tier >= 16:
            return PROGRESSION_PROFILES["ENDGAME_PINNACLE_LABYRINTH"]
        if map_tier >= 6:
            return PROGRESSION_PROFILES["ENDGAME_YELLOW_RED_ATLAS"]
        return PROGRESSION_PROFILES["ENDGAME_WHITE_ATLAS"]

    if act_id:
        act_upper = act_id.upper()
        if "ACT_V" in act_upper or "ACT_IV" in act_upper:
            return PROGRESSION_PROFILES["ACT_IV_V_CRUCIBLE"]
        if "ACT_III" in act_upper:
            return PROGRESSION_PROFILES["ACT_III_SANDSTORM"]
        if "ACT_II" in act_upper:
            return PROGRESSION_PROFILES["ACT_II_EXPLORATION"]
        return PROGRESSION_PROFILES["ACT_I_ONBOARDING"]

    if level >= 84:
        return PROGRESSION_PROFILES["ENDGAME_PINNACLE_LABYRINTH"]
    if level >= 78:
        return PROGRESSION_PROFILES["ENDGAME_YELLOW_RED_ATLAS"]
    if level >= 71:
        return PROGRESSION_PROFILES["ENDGAME_WHITE_ATLAS"]
    if level >= 46:
        return PROGRESSION_PROFILES["ACT_IV_V_CRUCIBLE"]
    if level >= 26:
        return PROGRESSION_PROFILES["ACT_III_SANDSTORM"]
    if level >= 11:
        return PROGRESSION_PROFILES["ACT_II_EXPLORATION"]

    return PROGRESSION_PROFILES["ACT_I_ONBOARDING"]


def get_zone_scaled_dimensions(
    zone_id: str,
    player_level: int = 1,
    map_tier: Optional[int] = None,
) -> Tuple[int, int, bool]:
    """Returns (width, height, is_labyrinth) for any zone given progression level."""
    profile = calculate_map_scale_profile(level=player_level, map_tier=map_tier, zone_id=zone_id)
    return profile.grid_width, profile.grid_height, profile.is_labyrinth
