"""
Unit tests for FreeExile Item Crafting Engine & Affix / Suffix Matrix.
Validates Path of Exile 2 style deterministic and stochastic currency crafting with Primal Stones.
"""

import unittest
from server.world.item_crafting_engine import (
    ItemCraftingEngine,
    ItemRarity,
    CraftingItem,
    AffixType,
    AffixMod,
    SpiritStoneCurrency,
)


class TestItemCraftingEngine(unittest.TestCase):
    def setUp(self):
        self.engine = ItemCraftingEngine()

    def test_transmute_normal_to_magic(self):
        item = CraftingItem(
            item_uuid="base_sword_001",
            base_name="Thanh Phong Kiếm Phôi",
            item_level=75,
            rarity=ItemRarity.NORMAL
        )

        success, msg, modified_item = self.engine.apply_currency(item, SpiritStoneCurrency.KHAI_LINH_CHAU)
        self.assertTrue(success, msg)
        self.assertEqual(modified_item.rarity, ItemRarity.MAGIC)
        self.assertTrue(1 <= len(modified_item.prefixes) + len(modified_item.suffixes) <= 2)

    def test_chaos_reroll_rare_item(self):
        # Create a rare item
        item = CraftingItem(
            item_uuid="rare_blade_001",
            base_name="Liệt Diễm Cuồng Đao",
            item_level=80,
            rarity=ItemRarity.RARE
        )
        # Seed with initial mods
        item.prefixes.append(AffixMod(mod_id="phys_dmg_pct", mod_name="Tăng Sát Thương Vật Lý", mod_type=AffixType.PREFIX, tier=1, value=120))
        item.suffixes.append(AffixMod(mod_id="crit_chance", mod_name="Tỉ Lệ Bạo Kích", mod_type=AffixType.SUFFIX, tier=1, value=35))

        success, msg, rerolled_item = self.engine.apply_currency(item, SpiritStoneCurrency.HON_NGUYEN_THACH)
        self.assertTrue(success, msg)
        self.assertEqual(rerolled_item.rarity, ItemRarity.RARE)
        total_mods = len(rerolled_item.prefixes) + len(rerolled_item.suffixes)
        self.assertTrue(3 <= total_mods <= 6, f"Expected 3-6 mods, got {total_mods}")

    def test_exalt_adds_new_affix_to_rare(self):
        item = CraftingItem(
            item_uuid="rare_armor_001",
            base_name="Thiên Tằm Khí Công Giáp",
            item_level=82,
            rarity=ItemRarity.RARE
        )
        item.prefixes.append(AffixMod(mod_id="max_life", mod_name="Sinh Lực Tối Đa", mod_type=AffixType.PREFIX, tier=1, value=110))
        item.suffixes.append(AffixMod(mod_id="fire_res", mod_name="Kháng Hỏa", mod_type=AffixType.SUFFIX, tier=1, value=45))

        initial_mod_count = len(item.prefixes) + len(item.suffixes)
        success, msg, exalted_item = self.engine.apply_currency(item, SpiritStoneCurrency.THIEN_MENH_DAN)
        self.assertTrue(success, msg)
        new_mod_count = len(exalted_item.prefixes) + len(exalted_item.suffixes)
        self.assertEqual(new_mod_count, initial_mod_count + 1)

    def test_exalt_rejects_when_affixes_are_full(self):
        item = CraftingItem(
            item_uuid="full_mod_ring",
            base_name="Thái Hư Giới Chỉ",
            item_level=85,
            rarity=ItemRarity.RARE
        )
        # Fill 3 prefixes
        for i in range(3):
            item.prefixes.append(AffixMod(mod_id=f"p_{i}", mod_name=f"Prefix {i}", mod_type=AffixType.PREFIX, tier=1, value=50))
        # Fill 3 suffixes
        for i in range(3):
            item.suffixes.append(AffixMod(mod_id=f"s_{i}", mod_name=f"Suffix {i}", mod_type=AffixType.SUFFIX, tier=1, value=30))

        success, msg, _ = self.engine.apply_currency(item, SpiritStoneCurrency.THIEN_MENH_DAN)
        self.assertFalse(success)
        self.assertIn("AFFIXES_FULL", msg)

    def test_annul_removes_single_random_affix(self):
        item = CraftingItem(
            item_uuid="annul_target_amulet",
            base_name="Bát Quái Hộ Thân Phù",
            item_level=84,
            rarity=ItemRarity.RARE
        )
        item.prefixes.append(AffixMod(mod_id="p1", mod_name="Tăng Khí Huyết", mod_type=AffixType.PREFIX, tier=1, value=80))
        item.prefixes.append(AffixMod(mod_id="p2", mod_name="Xuyên Giáp", mod_type=AffixType.PREFIX, tier=1, value=25))
        item.suffixes.append(AffixMod(mod_id="s1", mod_name="Tốc Độ Di Chuyển", mod_type=AffixType.SUFFIX, tier=1, value=15))

        success, msg, annulled_item = self.engine.apply_currency(item, SpiritStoneCurrency.THAN_TUONG_PHU)
        self.assertTrue(success, msg)
        self.assertEqual(len(annulled_item.prefixes) + len(annulled_item.suffixes), 2)

    def test_mirror_creates_immutable_replica(self):
        original = CraftingItem(
            item_uuid="god_tier_sword",
            base_name="Cửu Tiêu Long Ngâm Kiếm",
            item_level=100,
            rarity=ItemRarity.RARE
        )
        original.prefixes.append(AffixMod(mod_id="p1", mod_name="Bá Đạo Sát Thương", mod_type=AffixType.PREFIX, tier=1, value=250))
        original.suffixes.append(AffixMod(mod_id="s1", mod_name="Tốc Độ Đánh Điên Cuồng", mod_type=AffixType.SUFFIX, tier=1, value=50))

        success, msg, mirrored_copy = self.engine.apply_currency(original, SpiritStoneCurrency.THAI_HU_CAN_KHON_KINH)
        self.assertTrue(success, msg)
        self.assertTrue(mirrored_copy.is_mirrored)
        self.assertNotEqual(mirrored_copy.item_uuid, original.item_uuid)
        self.assertEqual(mirrored_copy.base_name, original.base_name)
        self.assertEqual(len(mirrored_copy.prefixes), len(original.prefixes))

        # Attempting to craft on a mirrored copy MUST FAIL
        success, msg, _ = self.engine.apply_currency(mirrored_copy, SpiritStoneCurrency.HON_NGUYEN_THACH)
        self.assertFalse(success)
        self.assertIn("CANNOT_MODIFY_MIRRORED_ITEM", msg)


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