"""AutoPOE2 - Unit Tests Kiểm Chứng Zero-Day UI Verifier Pipeline.
====================================================================
Kiểm thử toàn diện:
1. Thẩm định cấu trúc UI trên artifact capture thật từ captures/ (20260914_003608_364_CLICKED_PIN_1280_560.png).
2. Kiểm chứng bất biến an toàn nút TRAVERSE (luôn nằm ở x <= 0.55 * w, không lấn túi đồ).
3. Kiểm chứng định vị Player Avatar và lưới Inventory 60 ô.
4. Kiểm chứng tương thích trên nhiều độ phân giải (1440p, 1080p, Windowed 1189x891).
5. Xuất và kiểm tra tính toàn vẹn của tệp JSON chẩn đoán.

Tuân thủ nghiêm ngặt:
- Rule 5: 100% artifact thật từ captures/.
- Rule 14: Quality Gate, 100% tests PASS.
"""

from __future__ import annotations

import json
import os
import tempfile
import unittest
from PIL import Image

from src.assistant_tool.vision_zero_day_verifier import (
    ComponentStatus,
    ZeroDayReport,
    ZeroDayUiVerifier,
)
from src.common.coordinate_transform import (
    RES_1080P,
    RES_1440P,
    RES_WINDOWED_DEFAULT,
)


class TestZeroDayUiVerifier(unittest.TestCase):
    """Test suite kiểm thử ZeroDayUiVerifier."""

    def setUp(self) -> None:
        self.captures_dir = os.path.join(os.path.dirname(__file__), "..", "captures")
        self.verifier = ZeroDayUiVerifier(target_resolution=RES_1440P)

    def test_verify_real_capture_atlas_ready(self) -> None:
        """Kiểm chứng thẩm định frame capture thật: 20260914_003608_364_CLICKED_PIN_1280_560.png."""
        capture_path = os.path.join(self.captures_dir, "20260914_003608_364_CLICKED_PIN_1280_560.png")
        if not os.path.exists(capture_path):
            self.skipTest("Không tìm thấy capture 20260914_003608_364_CLICKED_PIN_1280_560.png")

        report: ZeroDayReport = self.verifier.verify_ui_frame(capture_path)

        self.assertIsInstance(report, ZeroDayReport)
        self.assertEqual(report.resolution, (2560, 1440))
        self.assertTrue(report.is_patch_ready, f"Bản vá chưa sẵn sàng: {report.errors}")
        self.assertEqual(len(report.errors), 0)

        # 1. Kiểm tra thành phần Player Avatar
        self.assertIn("player_avatar", report.components)
        self.assertTrue(report.components["player_avatar"].is_valid)
        self.assertIsNotNone(report.components["player_avatar"].coordinates)

        # 2. Kiểm tra thành phần TRAVERSE Button (kháng bug x <= 0.55 * w)
        self.assertIn("traverse_button", report.components)
        trav = report.components["traverse_button"]
        self.assertTrue(trav.is_valid)
        self.assertLessEqual(trav.coordinates[0], int(2560 * 0.55))

        # 3. Kiểm tra Inventory Grid 60 ô
        self.assertIn("inventory_grid", report.components)
        self.assertTrue(report.components["inventory_grid"].is_valid)

        # 4. Kiểm tra Waystone Tray & Socket
        self.assertIn("waystone_tray", report.components)
        self.assertTrue(report.components["waystone_tray"].is_valid)

    def test_traverse_button_anti_enter_boundary_guarantee(self) -> None:
        """Kiểm chứng nút TRAVERSE không bao giờ lấn sang vùng túi đồ (x > 0.55 * w)."""
        dummy_img = Image.new("RGB", (1920, 1080), color=(10, 10, 10))
        verifier_1080p = ZeroDayUiVerifier(target_resolution=RES_1080P)
        report = verifier_1080p.verify_ui_frame(dummy_img)

        trav = report.components["traverse_button"]
        self.assertTrue(trav.is_valid)
        self.assertLessEqual(trav.coordinates[0], int(1920 * 0.55))

    def test_multi_resolution_scalability(self) -> None:
        """Kiểm chứng verifier chạy mượt mà trên các độ phân giải 1440p, 1080p, Windowed."""
        resolutions = [
            (2560, 1440),
            (1920, 1080),
            (1189, 891),
        ]

        for w, h in resolutions:
            frame = Image.new("RGB", (w, h), color=(15, 15, 15))
            v = ZeroDayUiVerifier(target_resolution=(w, h))
            rep = v.verify_ui_frame(frame)
            self.assertEqual(rep.resolution, (w, h))
            self.assertTrue(rep.is_patch_ready)

    def test_save_and_load_diagnostic_report(self) -> None:
        """Kiểm chứng xuất báo cáo JSON chẩn đoán đầy đủ thông tin."""
        frame = Image.new("RGB", (1920, 1080), color=(5, 5, 5))
        rep = self.verifier.verify_ui_frame(frame)

        with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as tf:
            temp_path = tf.name

        try:
            self.verifier.save_diagnostic_report(rep, temp_path)
            self.assertTrue(os.path.exists(temp_path))

            with open(temp_path, "r", encoding="utf-8") as f:
                data = json.load(f)

            self.assertIn("timestamp", data)
            self.assertIn("components", data)
            self.assertIn("is_patch_ready", data)
            self.assertTrue(data["is_patch_ready"])
        finally:
            if os.path.exists(temp_path):
                os.remove(temp_path)


if __name__ == "__main__":
    unittest.main()
