"""
FreeExile Inventory & Storage Helper Routines.
Pure helper functions for slot search, stack merging, equipment compatibility, and container factories.
"""

import uuid
from typing import Dict, Optional, Tuple
from .inventory_types import (
    InventoryItem,
    EquipmentSlot,
    ItemType,
    CharacterInventory,
    StashTabType,
    StashTab,
    PersonalStash,
    MerchantStashTab,
    PlayerStorageContainer,
)


def try_merge_stack(
    slots: Dict[int, InventoryItem], item: InventoryItem
) -> Tuple[bool, Optional[int]]:
    """Attempts to merge item stack into existing matching item in slots."""
    if item.max_stack <= 1:
        return False, None

    for s_idx, existing in slots.items():
        if existing.item_id == item.item_id and existing.stack_count < existing.max_stack:
            space = existing.max_stack - existing.stack_count
            if item.stack_count <= space:
                existing.stack_count += item.stack_count
                return True, s_idx
            else:
                item.stack_count -= space
                existing.stack_count = existing.max_stack

    return False, None


def find_first_empty_slot(slots: Dict[int, InventoryItem], capacity: int) -> Optional[int]:
    """Finds first unused slot index in [0, capacity)."""
    for s_idx in range(capacity):
        if s_idx not in slots:
            return s_idx
    return None


def is_equipment_compatible(item_type: ItemType, equip_slot: EquipmentSlot) -> bool:
    """Validates if item type can be equipped in specified equipment slot."""
    weapon_slots = {
        EquipmentSlot.MAIN_HAND,
        EquipmentSlot.OFF_HAND,
        EquipmentSlot.SWAP_MAIN_HAND,
        EquipmentSlot.SWAP_OFF_HAND,
    }
    armor_slots = {
        EquipmentSlot.HELMET,
        EquipmentSlot.BODY_ARMOR,
        EquipmentSlot.GLOVES,
        EquipmentSlot.BOOTS,
        EquipmentSlot.BELT,
    }
    relic_slots = {
        EquipmentSlot.AMULET,
        EquipmentSlot.RING_1,
        EquipmentSlot.RING_2,
    }

    if item_type == ItemType.WEAPON:
        return equip_slot in weapon_slots
    if item_type == ItemType.ARMOR:
        return equip_slot in armor_slots
    if item_type == ItemType.RELIC:
        return equip_slot in relic_slots or equip_slot in armor_slots

    return False


def create_split_item(item: InventoryItem, count: int) -> InventoryItem:
    """Creates a split copy of a stackable item."""
    return InventoryItem(
        item_uuid=f"{item.item_uuid}_split_{uuid.uuid4().hex[:6]}",
        item_id=item.item_id,
        name=item.name,
        item_type=item.item_type,
        rarity=item.rarity,
        item_level=item.item_level,
        stack_count=count,
        max_stack=item.max_stack,
        affixes=list(item.affixes),
    )


def create_default_storage_container(account_id: str, character_id: str) -> PlayerStorageContainer:
    """Instantiates clean character inventory, 3 default stash tabs, and locked merchant tab."""
    inventory = CharacterInventory(
        account_id=account_id, character_id=character_id, capacity=40, slots={}, equipment={}
    )
    stash = PersonalStash(
        account_id=account_id,
        tabs={
            "tab_general": StashTab("tab_general", "Kho Chung", StashTabType.GENERAL, capacity=48),
            "tab_currency": StashTab("tab_currency", "Huyết Thạch & Tiền Tệ", StashTabType.CURRENCY, capacity=48),
            "tab_equipment": StashTab("tab_equipment", "Binh Khí & Thần Cốt", StashTabType.EQUIPMENT, capacity=48),
        }
    )
    merchant_stash = MerchantStashTab(
        account_id=account_id, is_unlocked=False, capacity=30, slots={}, tab_name="Hắc Thị Niêm Yết"
    )
    return PlayerStorageContainer(
        account_id=account_id, character_id=character_id,
        inventory=inventory, stash=stash, merchant_stash=merchant_stash
    )
