"""
Unit test suite for Milestone 2: Target Dummy Immortality, Loot Prevention,
and Telemetry Engine in FreeExile PoE2 Architecture.
"""

from pathlib import Path
import pytest


class TestMilestone2TargetDummyAndTelemetry:
    """Verifies Milestone 2 implementation requirements across client modules."""

    def test_target_dummy_telemetry_file_exists(self) -> None:
        """target_dummy_telemetry.js must exist in client/webapp/js/engine/."""
        telemetry_file = Path("client/webapp/js/engine/target_dummy_telemetry.js")
        assert telemetry_file.exists(), "target_dummy_telemetry.js must exist"

    def test_target_dummy_telemetry_interface_contract(self) -> None:
        """target_dummy_telemetry.js must implement PROJECT.md interface contracts."""
        content = Path("client/webapp/js/engine/target_dummy_telemetry.js").read_text(encoding="utf-8")
        assert "recordHit(" in content, "Must implement recordHit(damage, isCrit, timestamp)"
        assert "getTelemetry(" in content, "Must implement getTelemetry()"
        assert "reset(" in content, "Must implement reset()"
        assert "currentDps" in content, "Must compute currentDps"
        assert "peakDps" in content, "Must track peakDps"
        assert "comboCount" in content, "Must track comboCount"
        assert "maxHit" in content, "Must track maxHit"
        assert "totalDamage" in content, "Must track totalDamage"

    def test_target_dummy_telemetry_hygiene_line_cap(self) -> None:
        """target_dummy_telemetry.js must strictly be <= 250 lines."""
        lines = Path("client/webapp/js/engine/target_dummy_telemetry.js").read_text(encoding="utf-8").splitlines()
        assert len(lines) <= 250, f"target_dummy_telemetry.js must be <= 250 lines, got {len(lines)}"

    def test_monster_system_dummy_immortality_and_anchor(self) -> None:
        """monster_system.js must clamp dummy HP and anchor coordinates strictly to originWx, originWy."""
        content = Path("client/webapp/js/engine/monster_system.js").read_text(encoding="utf-8")
        assert "m.isDummy" in content
        assert "m.hp = m.maxHp" in content, "Must clamp dummy hp to maxHp"
        assert "m.wx = m.originWx" in content, "Must anchor wx strictly to originWx (zero drift)"
        assert "m.wy = m.originWy" in content, "Must anchor wy strictly to originWy (zero drift)"

    def test_combat_skills_dummy_loot_and_quest_prevention(self) -> None:
        """combat_skills.js must prevent dummy destruction from dropping loot or counting quest kills."""
        content = Path("client/webapp/js/engine/combat_skills.js").read_text(encoding="utf-8")
        assert "!target.isDummy" in content or "target.isDummy" in content
        assert "TargetDummyTelemetry" in content, "combat_skills.js must record hit on TargetDummyTelemetry"

    def test_monster_loot_dropper_guards_against_dummy(self) -> None:
        """monster_loot_dropper.js must immediately return empty array if monster.isDummy is true."""
        content = Path("client/webapp/js/engine/monster_loot_dropper.js").read_text(encoding="utf-8")
        assert "isDummy" in content, "spawnMonsterLoot must guard against dummy entities"

    def test_client_spawner_safe_haven_gate(self) -> None:
        """spawnQAEnemy in monster_system.js must reject hostile mob spawning in safe havens."""
        content = Path("client/webapp/js/engine/monster_system.js").read_text(encoding="utf-8")
        assert "zone_player_hideout" in content
        assert "zone_boundless_sanctuary" in content

    def test_worldmap_teleport_flushes_ground_drops_and_projectiles(self) -> None:
        """teleportToZone in worldmap_dungeons.js must flush groundDrops and flying projectiles."""
        content = Path("client/webapp/js/ui/worldmap_dungeons.js").read_text(encoding="utf-8")
        assert "groundDrops.length = 0" in content or "groundDrops" in content, "Must flush groundDrops on zone transition"

    def test_hideout_map_portal_calls_teleport_to_zone(self) -> None:
        """enterMapPortal in hideout_gates.js must dispatch teleportToZone on portal traversal."""
        content = Path("client/webapp/js/ui/hideout_gates.js").read_text(encoding="utf-8")
        assert "teleportToZone" in content, "enterMapPortal must call teleportToZone"

    def test_all_modified_files_comply_with_hard_cap(self) -> None:
        """All modified files must strictly comply with the 500-line hard cap."""
        files_to_check = [
            "client/webapp/js/engine/monster_system.js",
            "client/webapp/js/engine/combat_skills.js",
            "client/webapp/js/engine/monster_loot_dropper.js",
            "client/webapp/js/ui/worldmap_dungeons.js",
            "client/webapp/js/ui/hideout_gates.js"
        ]
        for rel_path in files_to_check:
            p = Path(rel_path)
            if p.exists():
                lines = p.read_text(encoding="utf-8").splitlines()
                assert len(lines) <= 500, f"{rel_path} exceeded 500 lines hard cap ({len(lines)} lines)"
