"""
Unit tests for Primal Spiritual Stones & Runes Crafting Engine in FreeExile.
Verifies all 7 crafting stones:
- Khai Linh Châu (Normal -> Magic)
- Tinh Luyện Phù (Re-roll Magic)
- Tạo Hóa Thạch (Normal -> Rare)
- Hỗn Nguyên Thạch (Re-roll Rare)
- Thần Tướng Phù (Add Affix to Rare)
- Thiên Mệnh Đan (Re-roll Affix Values within Tier)
- Thái Hư Càn Khôn Kính (Mirror non-unique item)
"""

import unittest
import sys
import os

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../server")))

from world.primal_stones_crafting import (
    CraftingEngine,
    GearItem,
    ItemRarity,
    AffixType,
    Affix
)


class TestPrimalStonesCrafting(unittest.TestCase):
    def setUp(self):
        self.engine = CraftingEngine()

    def test_khai_linh_chau_normal_to_magic(self):
        """Khai Linh Châu (Awakening Pearl) converts Common item into Magic with 1-2 affixes."""
        common_item = GearItem(
            item_uuid="item_sword_01",
            item_name="Bách Luyện Thiết Kiếm",
            item_level=50,
            rarity=ItemRarity.PHAM_PHAM # Common
        )
        success, msg = self.engine.apply_khai_linh_chau(common_item)
        self.assertTrue(success)
        self.assertEqual(common_item.rarity, ItemRarity.LINH_PHAM) # Magic
        self.assertTrue(1 <= len(common_item.affixes) <= 2)

    def test_tao_hoa_thach_normal_to_rare(self):
        """Tạo Hóa Thạch (Creation Stone) converts Common item into Rare with 4-6 affixes."""
        common_item = GearItem(
            item_uuid="item_blade_02",
            item_name="Huyền Thiết Trảm Đao",
            item_level=70,
            rarity=ItemRarity.PHAM_PHAM
        )
        success, msg = self.engine.apply_tao_hoa_thach(common_item)
        self.assertTrue(success)
        self.assertEqual(common_item.rarity, ItemRarity.CUC_PHAM) # Rare
        self.assertTrue(4 <= len(common_item.affixes) <= 6)

    def test_hon_nguyen_thach_reroll_rare(self):
        """Hỗn Nguyên Thạch (Primal Chaos Stone) cleanses and re-rolls all affixes on Rare item."""
        rare_item = GearItem(
            item_uuid="item_staff_03",
            item_name="Cửu Tiêu Lôi Đình Trượng",
            item_level=80,
            rarity=ItemRarity.CUC_PHAM,
            affixes=[
                Affix(name="Cương Khí Sơ Cấp", affix_type=AffixType.PREFIX, stat_key="phys_dmg", min_val=10, max_val=20, current_val=12),
                Affix(name="Nhanh Nhẹn", affix_type=AffixType.SUFFIX, stat_key="atk_speed", min_val=5, max_val=10, current_val=6)
            ]
        )
        original_affixes = [a.name for a in rare_item.affixes]

        success, msg = self.engine.apply_hon_nguyen_thach(rare_item)
        self.assertTrue(success)
        self.assertEqual(rare_item.rarity, ItemRarity.CUC_PHAM)
        self.assertTrue(4 <= len(rare_item.affixes) <= 6)

    def test_thien_menh_dan_rerolls_min_max_values(self):
        """Thiên Mệnh Đan (Destiny Rune) re-rolls numbers within range without altering affix names."""
        rare_item = GearItem(
            item_uuid="item_ring_04",
            item_name="Thiên Cương Chỉ Hoàn",
            item_level=75,
            rarity=ItemRarity.CUC_PHAM,
            affixes=[
                Affix(name="Chân Khí Hộ Thể", affix_type=AffixType.PREFIX, stat_key="energy_shield", min_val=50, max_val=100, current_val=52)
            ]
        )
        success, msg = self.engine.apply_thien_menh_dan(rare_item)
        self.assertTrue(success)
        # Affix name remains identical
        self.assertEqual(rare_item.affixes[0].name, "Chân Khí Hộ Thể")
        # Value is within [50, 100]
        self.assertTrue(50 <= rare_item.affixes[0].current_val <= 100)

    def test_thai_hu_kinh_creates_mirrored_copy(self):
        """Thái Hư Càn Khôn Kính (Mirror of Void) clones item perfectly and marks as mirrored."""
        god_tier_sword = GearItem(
            item_uuid="item_sword_masterpiece",
            item_name="Thái Hư Trảm Long Kiếm",
            item_level=100,
            rarity=ItemRarity.CUC_PHAM,
            affixes=[
                Affix(name="Thần Uy Vô Song", affix_type=AffixType.PREFIX, stat_key="phys_dmg", min_val=150, max_val=200, current_val=200),
                Affix(name="Cực Tốc", affix_type=AffixType.SUFFIX, stat_key="atk_speed", min_val=20, max_val=30, current_val=30)
            ]
        )
        mirrored_copy, msg = self.engine.apply_thai_hu_kinh(god_tier_sword)
        self.assertIsNotNone(mirrored_copy)
        self.assertNotEqual(mirrored_copy.item_uuid, god_tier_sword.item_uuid)
        self.assertTrue(mirrored_copy.is_mirrored)
        self.assertEqual(len(mirrored_copy.affixes), len(god_tier_sword.affixes))
        self.assertEqual(mirrored_copy.affixes[0].current_val, 200)

        # Mirrored item cannot be modified further!
        cannot_mod, _ = self.engine.apply_hon_nguyen_thach(mirrored_copy)
        self.assertFalse(cannot_mod)

    def test_craft_agent_orb_synthesis(self):
        """Verifies synthesizing Agent_Orb Tier 1 and Tier 2 from primal spiritual stones."""
        materials = {
            "curr_khai_linh_chau": 10,
            "curr_chaos_stone": 5,
            "curr_destiny_rune": 2
        }
        # Craft Tier 1 (requires 5 Khai Linh + 1 Chaos Stone)
        ok, msg, updated = self.engine.craft_agent_orb("item_agent_orb_tier1", materials)
        self.assertTrue(ok)
        self.assertEqual(updated["curr_khai_linh_chau"], 5)
        self.assertEqual(updated["curr_chaos_stone"], 4)

        # Insufficient materials failure
        insufficient = {"curr_khai_linh_chau": 1, "curr_chaos_stone": 0}
        fail_ok, fail_msg, _ = self.engine.craft_agent_orb("item_agent_orb_tier1", insufficient)
        self.assertFalse(fail_ok)
        self.assertIn("Thiếu nguyên liệu", fail_msg)

    def test_savage_primal_barter_aliases(self):
        """Verifies that Savage PoE2 aliases work seamlessly for all crafting stones."""
        item = GearItem(
            item_uuid="savage_axe_01",
            item_name="Hung Ma Rìu Rách",
            item_level=60,
            rarity=ItemRarity.PHAM_PHAM
        )
        # Hắc Sơ Thạch (Normal -> Magic)
        ok, _ = self.engine.apply_hac_so_thach(item)
        self.assertTrue(ok)
        self.assertEqual(item.rarity, ItemRarity.LINH_PHAM)

        # Uẩn Ma Thạch on normal
        norm_item = GearItem(item_uuid="axe_02", item_name="Đao Gỉ", item_level=50, rarity=ItemRarity.PHAM_PHAM)
        ok, _ = self.engine.apply_uan_ma_thach(norm_item)
        self.assertTrue(ok)
        self.assertEqual(norm_item.rarity, ItemRarity.CUC_PHAM)

        # Huyết Hồn Thạch (Chaos reroll)
        ok, _ = self.engine.apply_huyet_hon_thach(norm_item)
        self.assertTrue(ok)

        # Cổ Cốt Ấn (Divine roll)
        ok, _ = self.engine.apply_co_cot_an(norm_item)
        self.assertTrue(ok)

        # Huyết Ảnh Cổ Kính (Mirror)
        mirrored, _ = self.engine.apply_huyet_anh_co_kinh(norm_item)
        self.assertIsNotNone(mirrored)
        self.assertTrue(mirrored.is_mirrored)


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