"""
Primal Spiritual Stones & Runes Crafting Engine for FreeExile.
Implements the 7 core crafting stones of the Barter Economy:
1. Khai Linh Châu (Normal -> Magic)
2. Tinh Luyện Phù (Re-roll Magic)
3. Tạo Hóa Thạch (Normal -> Rare)
4. Hỗn Nguyên Thạch (Re-roll Rare)
5. Thần Tướng Phù (Add Affix to Rare)
6. Thiên Mệnh Đan (Re-roll Affix Numerical Ranges)
7. Thái Hư Càn Khôn Kính (Clone mirrored non-unique artifact)
"""

import uuid
import random
from enum import Enum
from typing import List, Optional, Tuple, Dict
from dataclasses import dataclass, field


class ItemRarity(Enum):
    PHAM_PHAM = "PHAM_PHAM"       # Common (Trắng)
    LINH_PHAM = "LINH_PHAM"       # Magic (Xanh Lam)
    CUC_PHAM = "CUC_PHAM"         # Rare (Cam/Vàng)
    THAN_THOAI = "THAN_THOAI"     # Unique (Đỏ)


class AffixType(Enum):
    PREFIX = "PREFIX"
    SUFFIX = "SUFFIX"


@dataclass
class Affix:
    name: str
    affix_type: AffixType
    stat_key: str
    min_val: int
    max_val: int
    current_val: int


@dataclass
class GearItem:
    item_uuid: str
    item_name: str
    item_level: int
    rarity: ItemRarity
    affixes: List[Affix] = field(default_factory=list)
    is_mirrored: bool = False


class CraftingEngine:
    AFFIX_POOL = [
        # Prefixes
        ("Cương Khí Sơ Cấp", AffixType.PREFIX, "phys_dmg", 10, 25),
        ("Cương Khí Trung Cấp", AffixType.PREFIX, "phys_dmg", 26, 50),
        ("Liệt Diễm Thiêu Thiên", AffixType.PREFIX, "fire_dmg", 15, 40),
        ("Hàn Băng Thấu Xương", AffixType.PREFIX, "cold_dmg", 15, 40),
        ("Chân Khí Hộ Thể", AffixType.PREFIX, "energy_shield", 30, 80),
        ("Khí Huyết Dồi Dào", AffixType.PREFIX, "max_hp", 40, 100),
        # Suffixes
        ("Thân Pháp Nhanh Nhẹn", AffixType.SUFFIX, "atk_speed", 5, 15),
        ("Bạo Kích Tất Sát", AffixType.SUFFIX, "crit_rate", 5, 12),
        ("Kháng Ngũ Hành", AffixType.SUFFIX, "all_res", 8, 20),
        ("Chân Khí Hồi Phục", AffixType.SUFFIX, "energy_regen", 2, 8),
        ("Khí Huyết Hồi Phục", AffixType.SUFFIX, "hp_regen", 3, 10)
    ]

    def _roll_random_affix(self, preferred_type: Optional[AffixType] = None) -> Affix:
        pool = self.AFFIX_POOL
        if preferred_type:
            pool = [a for a in pool if a[1] == preferred_type]
        name, a_type, stat_key, min_v, max_v = random.choice(pool)
        val = random.randint(min_v, max_v)
        return Affix(name=name, affix_type=a_type, stat_key=stat_key, min_val=min_v, max_val=max_v, current_val=val)

    def _check_mirrored(self, item: GearItem) -> Tuple[bool, str]:
        if item.is_mirrored:
            return False, "Mirrored artifacts are immutable and cannot be crafted further."
        return True, ""

    def apply_khai_linh_chau(self, item: GearItem) -> Tuple[bool, str]:
        """Khai Linh Châu (Awakening Pearl): Normal -> Magic with 1-2 affixes."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason

        if item.rarity != ItemRarity.PHAM_PHAM:
            return False, "Khai Linh Châu only works on Phàm Phẩm (Common) items."

        item.rarity = ItemRarity.LINH_PHAM
        affix_count = random.randint(1, 2)
        item.affixes = [self._roll_random_affix() for _ in range(affix_count)]
        return True, "Item successfully awakened into Linh Phẩm (Magic)."

    def apply_tinh_luyen_phu(self, item: GearItem) -> Tuple[bool, str]:
        """Tinh Luyện Phù (Refinement Rune): Re-rolls affixes on Magic item."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason

        if item.rarity != ItemRarity.LINH_PHAM:
            return False, "Tinh Luyện Phù only works on Linh Phẩm (Magic) items."

        affix_count = random.randint(1, 2)
        item.affixes = [self._roll_random_affix() for _ in range(affix_count)]
        return True, "Linh Phẩm affixes refined successfully."

    def apply_tao_hoa_thach(self, item: GearItem) -> Tuple[bool, str]:
        """Tạo Hóa Thạch (Creation Stone): Normal -> Rare with 4-6 affixes."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason

        if item.rarity != ItemRarity.PHAM_PHAM:
            return False, "Tạo Hóa Thạch only works on Phàm Phẩm (Common) items."

        item.rarity = ItemRarity.CUC_PHAM
        affix_count = random.randint(4, 6)
        item.affixes = [self._roll_random_affix() for _ in range(affix_count)]
        return True, "Item crafted into Cực Phẩm (Rare) with creation energy."

    def apply_hon_nguyen_thach(self, item: GearItem) -> Tuple[bool, str]:
        """Hỗn Nguyên Thạch (Primal Chaos Stone): Re-rolls all affixes on Rare item."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason

        if item.rarity != ItemRarity.CUC_PHAM:
            return False, "Hỗn Nguyên Thạch only works on Cực Phẩm (Rare) items."

        affix_count = random.randint(4, 6)
        item.affixes = [self._roll_random_affix() for _ in range(affix_count)]
        return True, "All affixes cleansed and re-rolled with primal chaos energy."

    def apply_thien_tuong_phu(self, item: GearItem) -> Tuple[bool, str]:
        """Thần Tướng Phù (Sovereign Sigil): Adds 1 affix to Rare item (max 6 affixes: 3 prefix, 3 suffix)."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason

        if item.rarity != ItemRarity.CUC_PHAM:
            return False, "Thần Tướng Phù only works on Cực Phẩm (Rare) items."

        prefixes = [a for a in item.affixes if a.affix_type == AffixType.PREFIX]
        suffixes = [a for a in item.affixes if a.affix_type == AffixType.SUFFIX]

        if len(prefixes) >= 3 and len(suffixes) >= 3:
            return False, "Item already has maximum number of affixes (6 affixes: 3 prefixes, 3 suffixes)."

        target_type = AffixType.PREFIX if len(prefixes) < 3 else AffixType.SUFFIX
        new_affix = self._roll_random_affix(preferred_type=target_type)
        item.affixes.append(new_affix)
        return True, f"Imbued item with sovereign affix '{new_affix.name}'."

    def apply_thien_menh_dan(self, item: GearItem) -> Tuple[bool, str]:
        """Thiên Mệnh Đan (Destiny Rune): Re-rolls numerical values within existing min-max ranges."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason

        if not item.affixes:
            return False, "Item has no affixes to re-roll."

        for affix in item.affixes:
            affix.current_val = random.randint(affix.min_val, affix.max_val)

        return True, "Affix numerical values re-rolled within their destiny bounds."

    def apply_thai_hu_kinh(self, item: GearItem) -> Tuple[Optional[GearItem], str]:
        """Thái Hư Càn Khôn Kính (Void Mirror): Clones non-unique item into mirrored duplicate."""
        if item.rarity == ItemRarity.THAN_THOAI:
            return None, "Thái Hư Kính cannot clone Thần Thoại (Unique) artifacts."
        if item.is_mirrored:
            return None, "Cannot clone an already mirrored artifact."

        clone_uuid = f"mirrored_{uuid.uuid4().hex[:12]}"
        cloned_affixes = [
            Affix(
                name=a.name,
                affix_type=a.affix_type,
                stat_key=a.stat_key,
                min_val=a.min_val,
                max_val=a.max_val,
                current_val=a.current_val
            )
            for a in item.affixes
        ]

        mirrored_item = GearItem(
            item_uuid=clone_uuid,
            item_name=f"{item.item_name} (Thái Hư Bản)",
            item_level=item.item_level,
            rarity=item.rarity,
            affixes=cloned_affixes,
            is_mirrored=True
        )
        return mirrored_item, "Mirrored duplicate successfully manifested from the void."

    def craft_agent_orb(
        self,
        target_tier: str,
        inventory_materials: Dict[str, int]
    ) -> Tuple[bool, str, Dict[str, int]]:
        """
        Synthesizes an Agent_Orb from Primal Spiritual Stones.
        Tier 1: 5x Khai Linh Châu + 1x Hỗn Nguyên Thạch
        Tier 2: 3x Hỗn Nguyên Thạch + 1x Thiên Mệnh Đan
        Tier 3: 1x Thái Hư Kính + 5x Thiên Mệnh Đan
        """
        recipes: Dict[str, Dict[str, int]] = {
            "item_agent_orb_tier1": {"curr_khai_linh_chau": 5, "curr_chaos_stone": 1},
            "item_agent_orb_tier2": {"curr_chaos_stone": 3, "curr_destiny_rune": 1},
            "item_agent_orb_tier3": {"curr_void_mirror": 1, "curr_destiny_rune": 5}
        }
        recipe = recipes.get(target_tier)
        if not recipe:
            return False, f"Unknown Agent Orb tier: {target_tier}", inventory_materials

        # Check sufficiency
        for mat_id, qty in recipe.items():
            if inventory_materials.get(mat_id, 0) < qty:
                return False, f"Thiếu nguyên liệu {mat_id} (cần {qty}, hiện có {inventory_materials.get(mat_id, 0)}).", inventory_materials

        # Deduct
        updated = inventory_materials.copy()
        for mat_id, qty in recipe.items():
            updated[mat_id] -= qty

        return True, f"Ngưng tụ thành công {target_tier} từ linh thạch hỗn mang.", updated

    # =========================================================================
    # Savage Primal Barter Aliases (PoE2 Spirit Realignment)
    # =========================================================================
    def apply_huyet_hon_thach(self, item: GearItem) -> Tuple[bool, str]:
        """Huyết Hồn Thạch: Transmute Normal->Magic if Phàm Phẩm, or Chaos reroll if Cực Phẩm."""
        if item.rarity == ItemRarity.PHAM_PHAM:
            return self.apply_khai_linh_chau(item)
        return self.apply_hon_nguyen_thach(item)

    def apply_co_cot_an(self, item: GearItem) -> Tuple[bool, str]:
        """Cổ Cốt Ấn: Regal Magic->Rare if Linh Phẩm, or Divine reroll bounds if Cực Phẩm."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason
        if item.rarity == ItemRarity.LINH_PHAM:
            item.rarity = ItemRarity.CUC_PHAM
            item.affixes.append(self._roll_random_affix())
            return True, "Item evolved into Cực Phẩm (Rare) with ancient bone brand."
        return self.apply_thien_menh_dan(item)

    def apply_uan_ma_thach(self, item: GearItem) -> Tuple[bool, str]:
        """Uẩn Ma Thạch: Scour affixes if crafted, or Normal->Rare creation if Phàm Phẩm."""
        can_craft, reason = self._check_mirrored(item)
        if not can_craft: return False, reason
        if item.affixes and item.rarity in (ItemRarity.LINH_PHAM, ItemRarity.CUC_PHAM):
            item.affixes.clear()
            item.rarity = ItemRarity.PHAM_PHAM
            return True, "Affixes cleansed and reset to Phàm Phẩm (Common)."
        return self.apply_tao_hoa_thach(item)

    def apply_hac_so_thach(self, item: GearItem) -> Tuple[bool, str]:
        """Hắc Sơ Thạch: Normal->Magic if Phàm Phẩm, or Reroll Tiers if already has affixes."""
        if item.rarity == ItemRarity.PHAM_PHAM:
            return self.apply_khai_linh_chau(item)
        return self.apply_thien_menh_dan(item)

    apply_u_minh_cot_dinh = apply_thien_tuong_phu
    apply_da_mai_huyet_ngan = apply_tinh_luyen_phu
    apply_huyet_anh_co_kinh = apply_thai_hu_kinh
    craft_feral_totem = craft_agent_orb


