"""
Unit tests for Wilderness Encounter Density and Spatial Pack Clustering.
Verifies zone encounter densities, minion radial distribution (1.2m - 3.2m),
endgame map tier pack scaling, and safe haven 0-pack guarantees.
"""

import math
import os
import sys
import pytest

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../server")))

from world.wilderness_encounter_engine import (
    WildernessEncounterEngine,
    ZONE_DENSITY_SPECS,
)
from world.monster_types import MonsterRank


class TestWildernessEncounterDensity:
    def test_outer_zones_have_configured_encounter_density(self) -> None:
        """Verifies each canonical outer wilderness zone has at least 3 packs configured."""
        engine = WildernessEncounterEngine()
        canonical_zones = [
            "zone_tang_kiem_nhai",
            "zone_ancient_sword_barrow",
            "zone_boundless_sandstorm",
            "zone_blood_scale_ruins",
        ]
        for z_id in canonical_zones:
            spec = engine.get_zone_density_spec(z_id)
            assert spec is not None, f"Missing density spec for {z_id}"
            assert spec["base_packs"] >= 3
            assert len(spec["native_genus"]) >= 2
            packs = engine.generate_zone_encounter_packs(z_id)
            assert len(packs) >= spec["base_packs"]

    def test_monster_pack_has_leader_and_minions(self) -> None:
        """Verifies generated packs contain 1 Rare leader and 3+ Common minions."""
        engine = WildernessEncounterEngine()
        packs = engine.generate_zone_encounter_packs("zone_tang_kiem_nhai")
        assert len(packs) > 0

        for pack in packs:
            assert pack.leader is not None
            assert pack.leader.is_pack_leader is True
            assert pack.leader.rank == MonsterRank.RARE
            assert len(pack.minions) >= 3
            for minion in pack.minions:
                assert minion.is_pack_leader is False
                assert minion.rank == MonsterRank.COMMON
                assert minion.pack_leader_id == pack.leader.monster_id

    def test_pack_minion_radial_clustering(self) -> None:
        """Verifies minions are placed radially around the leader within 1.2m - 3.5m."""
        engine = WildernessEncounterEngine()
        packs = engine.generate_zone_encounter_packs("zone_tang_kiem_nhai")
        pack = packs[0]

        runtime_states = engine.procedural_engine.create_pack_runtime_states(pack)
        leader_st = runtime_states[0]
        minion_states = runtime_states[1:]

        for m_st in minion_states:
            dist = math.hypot(m_st.current_x - leader_st.current_x, m_st.current_y - leader_st.current_y)
            assert 1.15 <= dist <= 3.5, f"Minion distance {dist:.2f}m outside radial cluster bounds [1.2m, 3.5m]"

    def test_endgame_tier_pack_scaling(self) -> None:
        """Verifies pack density scales upwards with endgame Map Tiers (T1 -> T16)."""
        engine = WildernessEncounterEngine()
        packs_t1 = engine.generate_zone_encounter_packs("zone_tang_kiem_nhai", map_tier=1)
        packs_t8 = engine.generate_zone_encounter_packs("zone_tang_kiem_nhai", map_tier=8)
        packs_t16 = engine.generate_zone_encounter_packs("zone_tang_kiem_nhai", map_tier=16)

        assert len(packs_t1) <= len(packs_t8) <= len(packs_t16)
        assert len(packs_t16) > len(packs_t1)

    def test_safe_haven_density_is_strictly_zero(self) -> None:
        """Verifies Safe Havens produce exactly 0 hostile monster packs."""
        engine = WildernessEncounterEngine()
        hideout_packs = engine.generate_zone_encounter_packs("zone_player_hideout")
        sanctuary_packs = engine.generate_zone_encounter_packs("zone_boundless_sanctuary")

        assert len(hideout_packs) == 0
        assert len(sanctuary_packs) == 0
