"""Bộ kiểm thử cho Module Quản trị Màn hình Ảo (tests/test_virtual_display_manager.py)."""

import pytest
from unittest.mock import patch, MagicMock
from src.common.virtual_display_manager import (
    MonitorInfo,
    get_all_monitors,
    get_virtual_monitor,
    is_virtual_display_active,
    move_window_to_virtual_display,
    is_window_on_virtual_display,
    capture_virtual_display,
    capture_virtual_display_jpeg,
)


def test_monitor_info_geometry():
    m = MonitorInfo(
        device="DISPLAY1",
        left=2560,
        top=0,
        width=1920,
        height=1080,
        is_primary=False,
    )
    assert m.right == 4480
    assert m.bottom == 1080
    assert m.contains_point(2560, 0)
    assert m.contains_point(3000, 500)
    assert not m.contains_point(0, 0)
    assert not m.contains_point(4480, 1080)


def test_get_virtual_monitor_selection():
    mock_monitors = [
        MonitorInfo("DISPLAY1", 0, 0, 2560, 1440, True),
        MonitorInfo("DISPLAY2", 2560, 0, 1920, 1080, False),
    ]
    with patch("src.common.virtual_display_manager.get_all_monitors", return_value=mock_monitors):
        vm = get_virtual_monitor()
        assert vm is not None
        assert vm.left == 2560
        assert vm.width == 1920
        assert not vm.is_primary


def test_get_virtual_monitor_none():
    mock_monitors = [
        MonitorInfo("DISPLAY1", 0, 0, 2560, 1440, True),
    ]
    with patch("src.common.virtual_display_manager.get_all_monitors", return_value=mock_monitors):
        vm = get_virtual_monitor()
        assert vm is None
        assert not is_virtual_display_active()


def test_move_window_to_virtual_display_mock():
    mock_vm = MonitorInfo("DISPLAY2", 2560, 0, 1920, 1080, False)
    with patch("src.common.virtual_display_manager.get_virtual_monitor", return_value=mock_vm), \
         patch("ctypes.windll.user32.IsWindow", return_value=1), \
         patch("ctypes.windll.user32.IsIconic", return_value=0), \
         patch("ctypes.windll.user32.GetWindowLongW", return_value=0x14CF0000), \
         patch("ctypes.windll.user32.SetWindowLongW", return_value=0), \
         patch("ctypes.windll.user32.SetWindowPos", return_value=1) as mock_setpos:
        
        ok = move_window_to_virtual_display(12345, mock_vm, borderless=True)
        assert ok is True
        mock_setpos.assert_called_once()
        args = mock_setpos.call_args[0]
        assert args[0] == 12345
        assert args[2] == 2560 # left
        assert args[3] == 0    # top
        assert args[4] == 1920 # width
        assert args[5] == 1080 # height


def test_move_window_to_virtual_display_keep_size_mock():
    mock_vm = MonitorInfo("DISPLAY2", 2560, 0, 1920, 1080, False)
    with patch("src.common.virtual_display_manager.get_virtual_monitor", return_value=mock_vm), \
         patch("ctypes.windll.user32.IsWindow", return_value=1), \
         patch("ctypes.windll.user32.IsIconic", return_value=0), \
         patch("ctypes.windll.user32.SetWindowPos", return_value=1) as mock_setpos:
        
        ok = move_window_to_virtual_display(12345, mock_vm, borderless=False, keep_size=True)
        assert ok is True
        mock_setpos.assert_called_once()
        args = mock_setpos.call_args[0]
        assert args[0] == 12345
        assert args[2] == 2560 # left
        assert args[3] == 0    # top
        assert args[4] == 0    # width ignored with SWP_NOSIZE
        assert args[5] == 0    # height ignored with SWP_NOSIZE


def test_is_window_on_virtual_display_mock():
    mock_vm = MonitorInfo("DISPLAY2", 2560, 0, 1920, 1080, False)
    
    with patch("src.common.virtual_display_manager.get_virtual_monitor", return_value=mock_vm), \
         patch("src.common.virtual_display_manager.get_window_bounds", return_value=(2600, 100, 4400, 1000)):
        
        on_vd = is_window_on_virtual_display(12345, mock_vm)
        assert on_vd is True


def test_live_hardware_monitors():
    monitors = get_all_monitors()
    assert len(monitors) >= 1
    primary = [m for m in monitors if m.is_primary]
    assert len(primary) == 1
