"""
Unit Tests for Waystone Auto-Crafter & Stage 3 Map Device Preparation (Doc 43 / Doc 48 / Doc 56)
================================================================================================
Kiểm thử toàn diện các bất biến kiến trúc:
- INV-CRAFT-WAYSTONE-01: CẤM TUYỆT ĐỐI dùng Orb of Alchemy lên Rare / Unique.
- INV-MAP-NO-BRICK: Phát hiện và xử lý mod cấm gây tử trận (Reflect, no regen...).
- Stage 3 Map Device Readiness: Đảm bảo Waystone nạp vào Map Device luôn đạt độ hiếm Magic/Rare tối ưu.
- Fail-Closed on Unknown: Từ chối ngay lập tức khi không rõ thông tin hoặc ở khu vực không an toàn.
- Resource Cascade: Hết Orb of Alchemy -> Kích hoạt Ange Exchange phím '/'.
"""

import pytest
from src.assistant_tool.pickit.waystone_crafter import (
    WaystoneAutoCrafter,
    WaystoneItem,
    WaystoneRarity,
    CraftAction,
    CraftResult,
)


class TestWaystoneCrafterCore:
    """Kiểm thử hạt nhân đánh giá và bất biến INV-CRAFT-WAYSTONE-01."""

    def test_inv_craft_waystone_01_rare_rejection(self):
        crafter = WaystoneAutoCrafter()

        # Rare Waystone (Rarity 2) -> BẮT BUỘC SKIP_CRAFT
        rare_ws = WaystoneItem(
            name="Deserted Waystone",
            tier=15,
            rarity=WaystoneRarity.RARE,
            inventory_col=0,
            inventory_row=0,
            affix_count=4,
        )
        action_rare = crafter.evaluate_craft_action(rare_ws, alchemy_count=10)
        assert action_rare == CraftAction.SKIP_CRAFT, "INV-CRAFT-WAYSTONE-01: Rare Waystone không được phép craft!"

        # Unique Waystone (Rarity 3) -> BẮT BUỘC SKIP_CRAFT
        unique_ws = WaystoneItem(
            name="Unique Map Waystone",
            tier=16,
            rarity=WaystoneRarity.UNIQUE,
            inventory_col=1,
            inventory_row=0,
        )
        action_unique = crafter.evaluate_craft_action(unique_ws, alchemy_count=10)
        assert action_unique == CraftAction.SKIP_CRAFT, "Unique Waystone không được phép craft!"

    def test_craft_normal_and_magic_waystones(self):
        crafter = WaystoneAutoCrafter()

        # Normal Waystone (White, Rarity 0) -> APPLY_ALCHEMY
        white_ws = WaystoneItem(
            name="Deserted Waystone",
            tier=15,
            rarity=WaystoneRarity.NORMAL,
            inventory_col=0,
            inventory_row=0,
        )
        action_white = crafter.evaluate_craft_action(white_ws, alchemy_count=5)
        assert action_white == CraftAction.APPLY_ALCHEMY

        # Magic Waystone (Blue, Rarity 1) -> APPLY_ALCHEMY
        magic_ws = WaystoneItem(
            name="Fortress Waystone",
            tier=14,
            rarity=WaystoneRarity.MAGIC,
            inventory_col=2,
            inventory_row=0,
        )
        action_magic = crafter.evaluate_craft_action(magic_ws, alchemy_count=5)
        assert action_magic == CraftAction.APPLY_ALCHEMY

    def test_craft_triggers_ange_when_out_of_alchemy(self):
        crafter = WaystoneAutoCrafter()
        white_ws = WaystoneItem(
            name="Deserted Waystone",
            tier=15,
            rarity=WaystoneRarity.NORMAL,
            inventory_col=0,
            inventory_row=0,
        )
        action_no_alch = crafter.evaluate_craft_action(white_ws, alchemy_count=0)
        assert action_no_alch == CraftAction.TRIGGER_ANGE

    def test_craft_fail_closed_on_unknown_or_unsafe(self):
        crafter = WaystoneAutoCrafter()

        # Unknown rarity -> ABORT_SAFETY
        unknown_ws = WaystoneItem(
            name="Unknown Waystone",
            tier=15,
            rarity=WaystoneRarity.UNKNOWN,
            inventory_col=0,
            inventory_row=0,
        )
        action_unk = crafter.evaluate_craft_action(unknown_ws, alchemy_count=5)
        assert action_unk == CraftAction.ABORT_SAFETY

        # Không ở khu an toàn (bị quái vật bao vây) -> ABORT_SAFETY
        normal_ws = WaystoneItem(
            name="Normal Waystone",
            tier=15,
            rarity=WaystoneRarity.NORMAL,
            inventory_col=0,
            inventory_row=0,
        )
        action_danger = crafter.evaluate_craft_action(normal_ws, alchemy_count=5, is_in_safe_area=False)
        assert action_danger == CraftAction.ABORT_SAFETY

    def test_craft_simulation_success(self):
        crafter = WaystoneAutoCrafter()
        white_ws = WaystoneItem(
            name="Deserted Waystone",
            tier=15,
            rarity=WaystoneRarity.NORMAL,
            inventory_col=0,
            inventory_row=0,
        )
        res = crafter.execute_craft_simulation(white_ws, alchemy_count=5, simulate_success=True)
        assert res.success is True
        assert res.initial_rarity == WaystoneRarity.NORMAL
        assert res.final_rarity == WaystoneRarity.RARE


class TestWaystoneBrickModAndReroll:
    """Kiểm thử phòng vệ Brick Mod (INV-MAP-NO-BRICK)."""

    def test_craft_brick_mod_detection_and_actions(self):
        crafter = WaystoneAutoCrafter()

        # Waystone chứa mod Reflect Physical Damage -> BRICK
        brick_ws = WaystoneItem(
            name="Deserted Waystone (Reflect)",
            tier=15,
            rarity=WaystoneRarity.RARE,
            inventory_col=0,
            inventory_row=0,
            mods_text="Monsters reflect 18% of Physical Damage\n40% increased Monster Pack Size",
        )
        is_brick, red_mods = crafter.is_brick_waystone(brick_ws.mods_text)
        assert is_brick is True
        assert len(red_mods) > 0

        # Nếu có Orb of Scouring và Alchemy -> REROLL_SCOUR_ALCH
        act_reroll = crafter.evaluate_craft_action(brick_ws, alchemy_count=5, scour_count=5)
        assert act_reroll == CraftAction.REROLL_SCOUR_ALCH

        # Nếu hết Scour -> SKIP_DANGEROUS
        act_skip = crafter.evaluate_craft_action(brick_ws, alchemy_count=5, scour_count=0)
        assert act_skip == CraftAction.SKIP_DANGEROUS

    def test_safe_waystone_no_brick(self):
        crafter = WaystoneAutoCrafter()
        safe_ws = WaystoneItem(
            name="Deserted Waystone (Safe)",
            tier=15,
            rarity=WaystoneRarity.RARE,
            inventory_col=0,
            inventory_row=0,
            mods_text="80% increased Quantity of Items found in this Area\n25% increased Monster Pack Size",
        )
        is_brick_safe, _ = crafter.is_brick_waystone(safe_ws.mods_text)
        assert is_brick_safe is False
        act_safe = crafter.evaluate_craft_action(safe_ws, alchemy_count=5, scour_count=5)
        assert act_safe == CraftAction.SKIP_CRAFT


class TestStage3MapDeviceReadiness:
    """Kiểm thử tính tối ưu của Waystone nạp vào Map Device (Stage 3)."""

    def test_is_optimal_for_map_device(self):
        crafter = WaystoneAutoCrafter()

        # 1. Normal Waystone -> Chưa tối ưu (cần nâng cấp Magic/Rare)
        normal_ws = WaystoneItem(
            name="Deserted Waystone",
            tier=15,
            rarity=WaystoneRarity.NORMAL,
            inventory_col=0,
            inventory_row=0,
        )
        opt_normal, msg_normal = crafter.is_optimal_for_map_device(normal_ws)
        assert opt_normal is False
        assert "chưa được nâng cấp" in msg_normal

        # 2. Magic Waystone -> Tối ưu
        magic_ws = WaystoneItem(
            name="Fortress Waystone",
            tier=15,
            rarity=WaystoneRarity.MAGIC,
            inventory_col=1,
            inventory_row=0,
            mods_text="30% increased Monster Pack Size",
        )
        opt_magic, msg_magic = crafter.is_optimal_for_map_device(magic_ws)
        assert opt_magic is True
        assert "tối ưu" in msg_magic

        # 3. Rare Waystone an toàn -> Tối ưu
        rare_ws = WaystoneItem(
            name="Creek Waystone",
            tier=15,
            rarity=WaystoneRarity.RARE,
            inventory_col=2,
            inventory_row=0,
            mods_text="75% increased Item Quantity\n35% increased Monster Pack Size",
        )
        opt_rare, msg_rare = crafter.is_optimal_for_map_device(rare_ws)
        assert opt_rare is True
        assert "tối ưu" in msg_rare

        # 4. Brick Rare Waystone -> Không tối ưu (INV-MAP-NO-BRICK)
        brick_ws = WaystoneItem(
            name="Dangerous Waystone",
            tier=15,
            rarity=WaystoneRarity.RARE,
            inventory_col=3,
            inventory_row=0,
            mods_text="Monsters reflect 18% of Physical Damage",
        )
        opt_brick, msg_brick = crafter.is_optimal_for_map_device(brick_ws)
        assert opt_brick is False
        assert "Brick Mod" in msg_brick

        # 5. Unknown Waystone -> Fail-Closed
        unk_ws = WaystoneItem(
            name="Corrupt Data Waystone",
            tier=15,
            rarity=WaystoneRarity.UNKNOWN,
            inventory_col=4,
            inventory_row=0,
        )
        opt_unk, msg_unk = crafter.is_optimal_for_map_device(unk_ws)
        assert opt_unk is False
        assert "Fail-Closed" in msg_unk

    def test_prepare_optimal_waystone_upgrades_normal(self):
        """Stage 3 tự động nâng cấp viên Normal thành Rare trước khi nạp Map Device."""
        crafter = WaystoneAutoCrafter()
        white_ws = WaystoneItem(
            name="Mineshaft Waystone",
            tier=15,
            rarity=WaystoneRarity.NORMAL,
            inventory_col=0,
            inventory_row=0,
        )
        upgraded, res = crafter.prepare_optimal_waystone(white_ws, alchemy_count=10)
        assert res.success is True
        assert upgraded.rarity == WaystoneRarity.RARE
        assert upgraded.affix_count >= 4

        # Sau khi nâng cấp, viên đá phải đạt chuẩn tối ưu cho Map Device
        is_opt, _ = crafter.is_optimal_for_map_device(upgraded)
        assert is_opt is True

    def test_prepare_optimal_waystone_keeps_rare(self):
        """Stage 3 giữ nguyên viên Rare an toàn, không tốn Alchemy."""
        crafter = WaystoneAutoCrafter()
        rare_ws = WaystoneItem(
            name="Marsh Waystone",
            tier=15,
            rarity=WaystoneRarity.RARE,
            inventory_col=1,
            inventory_row=0,
            mods_text="20% increased Monster Pack Size",
        )
        kept, res = crafter.prepare_optimal_waystone(rare_ws, alchemy_count=10)
        assert res.success is True
        assert res.action == CraftAction.SKIP_CRAFT
        assert kept.rarity == WaystoneRarity.RARE

