"""AutoPOE2 - Unit test xác thực tính nhất quán toán học Isometric giữa C++ và Python (SSoT Parity).
Kiểm tra world_to_screen_isometric và world_to_wasd trong src/common/coordinate_transform.py.
"""

import math
import pytest
from src.common.coordinate_transform import (
    world_to_screen_isometric,
    world_to_wasd,
    ScreenPoint,
    WasdVector,
)


def test_world_to_wasd_screen_directions():
    """Kiểm tra 4 hướng màn hình thuần túy W, A, S, D (tương ứng với góc nghiêng 45 độ thế giới)."""
    # Màn hình hướng Lên (Up/W thuần túy): dx=10.0, dy=10.0
    up, left, down, right = world_to_wasd(10.0, 10.0)
    assert up is True
    assert down is False
    assert left is False
    assert right is False

    # Màn hình hướng Xuống (Down/S thuần túy): dx=-10.0, dy=-10.0
    up, left, down, right = world_to_wasd(-10.0, -10.0)
    assert up is False
    assert down is True
    assert left is False
    assert right is False

    # Màn hình hướng Phải (Right/D thuần túy): dx=10.0, dy=-10.0
    up, left, down, right = world_to_wasd(10.0, -10.0)
    assert up is False
    assert down is False
    assert left is False
    assert right is True

    # Màn hình hướng Trái (Left/A thuần túy): dx=-10.0, dy=10.0
    up, left, down, right = world_to_wasd(-10.0, 10.0)
    assert up is False
    assert down is False
    assert left is True
    assert right is False


def test_world_to_wasd_cardinal_directions():
    """Kiểm tra 4 trục chính thế giới tương ứng với tổ hợp 2 phím WASD trong góc nhìn Isometric 45 độ."""
    # North thế giới (+Y): Chiếu lên màn hình là hướng Tây-Bắc -> Phím W + A
    up, left, down, right = world_to_wasd(0.0, 10.0)
    assert up is True
    assert left is True
    assert down is False
    assert right is False

    # South thế giới (-Y): Chiếu lên màn hình là hướng Đông-Nam -> Phím S + D
    up, left, down, right = world_to_wasd(0.0, -10.0)
    assert down is True
    assert right is True
    assert up is False
    assert left is False


def test_world_to_wasd_deadzone():
    """Kiểm tra vùng chết (deadzone) không phát phím khi khoảng cách quá nhỏ."""
    up, left, down, right = world_to_wasd(0.001, 0.001, deadzone=0.05)
    assert not any([up, left, down, right])

    up, left, down, right = world_to_wasd(0.0, 0.0)
    assert not any([up, left, down, right])


def test_world_to_screen_isometric_projection():
    """Kiểm tra phép chiếu Isometric từ vector delta sang pixel màn hình."""
    # Điểm gốc tại tâm màn hình (dx=0, dy=0)
    tx, ty = world_to_screen_isometric(0.0, 0.0, screen_w=1920.0, screen_h=1080.0)
    assert math.isclose(tx, 960.0, abs_tol=1e-3)
    assert math.isclose(ty, 540.0, abs_tol=1e-3)

    # Tiến lên phía Bắc (+Y): ty phải nhỏ hơn 540 (hướng lên trên màn hình)
    tx, ty = world_to_screen_isometric(0.0, 100.0, dist=100.0, screen_w=1920.0, screen_h=1080.0)
    # targetY = 540 - (0 + 1) * 100 * 0.45 = 540 - 45 = 495.0
    assert math.isclose(ty, 495.0, abs_tol=1e-3)
    # targetX = 960 + (0 - 1) * 100 * 0.70710678 = 960 - 70.71 = 889.289
    assert math.isclose(tx, 960.0 - 100.0 * 0.70710678, abs_tol=1e-3)


def test_world_to_screen_isometric_clamping():
    """Kiểm tra giới hạn biên an toàn (Screen Boundary Clamping)."""
    # Vector cực lớn phải bị clamp vào khoảng an toàn [margin, screen - margin]
    tx, ty = world_to_screen_isometric(10000.0, 10000.0, screen_w=1920.0, screen_h=1080.0, margin=50.0)
    assert 50.0 <= tx <= 1920.0 - 50.0
    assert 50.0 <= ty <= 1080.0 - 50.0
