"""
Unit Test Suite for FreeExile PC Desktop Web Client Layout & DOM Architecture.
Verifies:
- 100vw x 100vh Fullscreen layout with zero scrollbars/overflow
- Absolute elimination of mobile simulation artifacts (.iphone-frame, #simulator-bar)
- Hidden dummy joystick DOM elements to prevent canvas_renderer null-dereference
- Base href tag linking shared webapp assets without duplication
- Grimdark Action HUD (Dual Fluid Orbs, Central Action Bar, Minimap, Chat Dock)
- Dedicated dev server configuration (tools/serve_web_pc.py on port 8089)
- Zero regression on mobile webapp (client/webapp/index.html)
"""

from __future__ import annotations
import inspect
import os
import re
import sys
from pathlib import Path
import pytest

PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
WEB_PC_DIR = PROJECT_ROOT / "client" / "web_pc"
INDEX_HTML = WEB_PC_DIR / "index.html"
CSS_MAIN = WEB_PC_DIR / "css" / "pc_main.css"
CSS_HUD = WEB_PC_DIR / "css" / "pc_hud.css"
CSS_MODALS = WEB_PC_DIR / "css" / "pc_modals.css"
SERVE_PC_PY = PROJECT_ROOT / "tools" / "serve_web_pc.py"
MOBILE_INDEX_HTML = PROJECT_ROOT / "client" / "webapp" / "index.html"


class TestPcWebClientLayoutUnit:
    """Verifies PC web client layout contracts, DOM elements, and server config."""

    def test_css_files_exist_and_enforce_zero_scrollbars(self) -> None:
        """Verifies CSS files exist, enforce overflow:hidden, and respect line caps."""
        for css_file in [CSS_MAIN, CSS_HUD, CSS_MODALS]:
            assert css_file.exists(), f"{css_file.name} must exist"
            lines = css_file.read_text(encoding="utf-8").splitlines()
            assert len(lines) <= 350, f"{css_file.name} ({len(lines)} lines) exceeds soft cap"

        main_content = CSS_MAIN.read_text(encoding="utf-8")
        assert "overflow: hidden" in main_content
        assert "margin: 0" in main_content

    def test_serve_web_pc_configuration(self) -> None:
        """Verifies tools/serve_web_pc.py exists, uses port 8089, and routes properly."""
        assert SERVE_PC_PY.exists(), "serve_web_pc.py must exist"
        content = SERVE_PC_PY.read_text(encoding="utf-8")
        assert "8089" in content, "serve_web_pc.py must default to port 8089"
        assert "WEBAPP_DIR" in content, "serve_web_pc.py must reference WEBAPP_DIR"
        assert "PC_DIR" in content, "serve_web_pc.py must reference PC_DIR"

    def test_html_base_href_and_viewport_architecture(self) -> None:
        """Verifies index.html has base href ../webapp/ and full-screen #app-viewport."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        assert '<base href="../webapp/">' in content
        assert 'id="app-viewport"' in content
        assert 'id="game-canvas"' in content

    def test_mobile_artifacts_elimination(self) -> None:
        """Verifies zero mobile chassis elements exist in PC index.html."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        assert "iphone-frame" not in content, "No .iphone-frame allowed in PC client"
        assert 'id="simulator-bar"' not in content, "No #simulator-bar allowed in PC client"
        assert 'id="mode-iphone"' not in content, "No mobile mode buttons allowed"

    def test_dummy_joystick_guard_presence(self) -> None:
        """Verifies hidden dummy joystick DOM exists to prevent null dereference."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        assert 'id="joystick-zone"' in content
        assert 'id="joystick-stick"' in content
        # Must be hidden or display:none so not visible to user
        assert ("display:none" in content or "display: none" in content or "hidden" in content)

    def test_grimdark_action_hud_structure(self) -> None:
        """Verifies dual fluid orbs, central action bar slots, and exp bar."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        # Dual Orbs
        assert 'id="life-orb-canvas"' in content
        assert 'id="mana-orb-canvas"' in content
        # Flask slots 1 to 5
        for i in range(1, 6):
            assert f'id="skill-flask-{i}"' in content
        # Martial skills Q, W, E, R
        for k in ["q", "w", "e", "r"]:
            assert f'id="skill-{k}"' in content
        # Mouse slots
        assert 'id="skill-lmb"' in content
        assert 'id="skill-rmb"' in content
        # Dodge and EXP
        assert 'id="skill-dodge"' in content
        assert 'id="player-exp-bar"' in content

    def test_minimap_and_telemetry_hud(self) -> None:
        """Verifies top-right minimap and telemetry header in index.html."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        assert 'id="minimap-canvas"' in content
        assert 'id="minimap-zone-label"' in content
        assert 'id="minimap-coords"' in content
        assert 'id="hud-fps"' in content
        assert 'id="hud-ping"' in content

    def test_collapsible_chat_dock_structure(self) -> None:
        """Verifies collapsible chat dock with ticker and expanded panel."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        assert 'id="chat-dock"' in content
        assert 'id="chat-minimized-bar"' in content
        assert 'id="chat-expanded-panel"' in content
        assert 'id="chat-input"' in content
        assert 'id="chat-send-btn"' in content

    def test_floating_tooltip_and_pause_overlay(self) -> None:
        """Verifies #game-tooltip and #overlay-pause are present in DOM."""
        if not INDEX_HTML.exists():
            pytest.skip("index.html is being written by worker_m1")
        content = INDEX_HTML.read_text(encoding="utf-8")
        assert 'id="game-tooltip"' in content
        assert 'id="tooltip-title"' in content
        assert 'id="tooltip-desc"' in content
        assert 'id="overlay-pause"' in content

    def test_zero_mobile_webapp_regression(self) -> None:
        """Verifies mobile webapp at client/webapp/index.html is completely unmodified."""
        assert MOBILE_INDEX_HTML.exists()
        mobile_content = MOBILE_INDEX_HTML.read_text(encoding="utf-8")
        assert "iphone-frame" in mobile_content, "Mobile webapp must retain .iphone-frame"
        assert 'id="simulator-bar"' in mobile_content, "Mobile webapp must retain simulator bar"
        assert 'id="joystick-zone"' in mobile_content, "Mobile webapp must retain touch joystick"
