"""
Item system for STARWASTE
Defines all items, their properties, and types
"""

from enum import Enum
from dataclasses import dataclass
from typing import Optional, Dict, Any
from shared.utils import console


class ItemType(Enum):
    """Types of items in the game"""
    # Resources (Tier 1)
    RESOURCE_SCRAP = "resource_scrap"
    RESOURCE_WOOD = "resource_wood"
    RESOURCE_STONE = "resource_stone"
    RESOURCE_METAL = "resource_metal"
    RESOURCE_CIRCUITS = "resource_circuits"
    
    # Resources (Tier 2)
    RESOURCE_STEEL = "resource_steel"
    RESOURCE_COPPER = "resource_copper"
    RESOURCE_COAL = "resource_coal"
    
    # Resources (Tier 3)
    RESOURCE_ALIEN_ALLOY = "resource_alien_alloy"
    RESOURCE_QUANTUM_CORE = "resource_quantum_core"
    
    # Tools
    TOOL_PICKAXE = "tool_pickaxe"
    TOOL_AXE = "tool_axe"
    TOOL_DRILL = "tool_drill"
    
    # Weapons - Melee
    WEAPON_MELEE_SCRAP_SWORD = "weapon_melee_scrap_sword"
    WEAPON_MELEE_STEEL_BLADE = "weapon_melee_steel_blade"
    WEAPON_MELEE_PLASMA_SWORD = "weapon_melee_plasma_sword"
    
    # Weapons - Ranged
    WEAPON_RANGED_PISTOL = "weapon_ranged_pistol"
    WEAPON_RANGED_RIFLE = "weapon_ranged_rifle"
    WEAPON_RANGED_SHOTGUN = "weapon_ranged_shotgun"
    
    # Armor
    ARMOR_HELMET_SCRAP = "armor_helmet_scrap"
    ARMOR_CHEST_SCRAP = "armor_chest_scrap"
    ARMOR_LEGS_SCRAP = "armor_legs_scrap"
    
    # Building materials
    BUILDING_SCRAP_WALL = "building_scrap_wall"
    BUILDING_SCRAP_FLOOR = "building_scrap_floor"
    BUILDING_SCRAP_DOOR = "building_scrap_door"
    
    # Furniture
    FURNITURE_CHEST = "furniture_chest"
    FURNITURE_WORKBENCH = "furniture_workbench"
    FURNITURE_SMELTER = "furniture_smelter"
    
    # Consumables
    CONSUMABLE_HEALTH_PACK = "consumable_health_pack"
    CONSUMABLE_ENERGY_CELL = "consumable_energy_cell"


class ItemCategory(Enum):
    """Categories for item organization"""
    RESOURCE = "resource"
    TOOL = "tool"
    WEAPON = "weapon"
    ARMOR = "armor"
    BUILDING = "building"
    FURNITURE = "furniture"
    CONSUMABLE = "consumable"


class EquipmentSlot(Enum):
    """Equipment slots where items can be equipped"""
    NONE = "none"
    HELMET = "helmet"
    CHEST = "chest"
    LEGS = "legs"
    WEAPON = "weapon"
    TOOL = "tool"
    ACCESSORY = "accessory"
    JETPACK = "jetpack"
    SHIELD = "shield"


@dataclass
class ItemStats:
    """Stats for weapons, tools, and armor"""
    damage: int = 0
    attack_speed: float = 1.0  # attacks per second
    mining_speed: float = 1.0  # mining efficiency
    armor: int = 0
    durability: int = -1  # -1 = infinite
    max_durability: int = -1
    range: float = 1.0  # attack/mining range in tiles


@dataclass
class Item:
    """Base item definition"""
    item_id: str  # unique identifier (same as ItemType value)
    name: str  # display name
    description: str
    category: ItemCategory
    stack_size: int = 99  # max stack size
    equipment_slot: EquipmentSlot = EquipmentSlot.NONE
    stats: Optional[ItemStats] = None
    sprite: Optional[str] = None  # sprite path (future)
    tier: int = 1  # tech tier (1-4)
    
    def __post_init__(self):
        if self.stats is None and self.category in [ItemCategory.WEAPON, ItemCategory.TOOL, ItemCategory.ARMOR]:
            self.stats = ItemStats()
    
    def to_dict(self) -> Dict[str, Any]:
        """Serialize item to dict for network transmission"""
        data = {
            "item_id": self.item_id,
            "name": self.name,
            "description": self.description,
            "category": self.category.value,
            "stack_size": self.stack_size,
            "equipment_slot": self.equipment_slot.value,
            "tier": self.tier,
        }
        if self.stats:
            data["stats"] = {
                "damage": self.stats.damage,
                "attack_speed": self.stats.attack_speed,
                "mining_speed": self.stats.mining_speed,
                "armor": self.stats.armor,
                "durability": self.stats.durability,
                "max_durability": self.stats.max_durability,
                "range": self.stats.range,
            }
        return data
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "Item":
        """Deserialize item from dict"""
        stats = None
        if "stats" in data:
            stats = ItemStats(**data["stats"])
        
        return cls(
            item_id=data["item_id"],
            name=data["name"],
            description=data["description"],
            category=ItemCategory(data["category"]),
            stack_size=data["stack_size"],
            equipment_slot=EquipmentSlot(data["equipment_slot"]),
            stats=stats,
            sprite=data.get("sprite"),
            tier=data["tier"],
        )


# ============================================================================
# ITEM REGISTRY - All items in the game
# ============================================================================

ITEM_REGISTRY: Dict[str, Item] = {}


def register_item(item: Item):
    """Register an item in the global registry"""
    ITEM_REGISTRY[item.item_id] = item


def get_item(item_id: str) -> Optional[Item]:
    """Get item by ID from registry"""
    return ITEM_REGISTRY.get(item_id)


# ============================================================================
# TIER 1: SCRAP ERA (Early Game)
# ============================================================================

# --- Resources ---
register_item(Item(
    item_id=ItemType.RESOURCE_SCRAP.value,
    name="Scrap Metal",
    description="Rusty metal pieces from destroyed robots. Basic building material.",
    category=ItemCategory.RESOURCE,
    stack_size=99,
    tier=1,
))

register_item(Item(
    item_id=ItemType.RESOURCE_WOOD.value,
    name="Wood",
    description="Old wooden planks. Surprisingly still usable.",
    category=ItemCategory.RESOURCE,
    stack_size=99,
    sprite="assets/items/generated/item_drops_64/wood_drop.png",
    tier=1,
))

register_item(Item(
    item_id=ItemType.RESOURCE_STONE.value,
    name="Stone",
    description="Basic stone chunks. Heavy but durable.",
    category=ItemCategory.RESOURCE,
    stack_size=99,
    sprite="assets/items/generated/item_drops_64/stone_drop.png",
    tier=1,
))

register_item(Item(
    item_id=ItemType.RESOURCE_METAL.value,
    name="Metal Ore",
    description="Raw metal ore. Needs refining but valuable.",
    category=ItemCategory.RESOURCE,
    stack_size=99,
    tier=1,
))

register_item(Item(
    item_id=ItemType.RESOURCE_CIRCUITS.value,
    name="Broken Circuits",
    description="Damaged electronic circuits. Might be salvageable.",
    category=ItemCategory.RESOURCE,
    stack_size=99,
    tier=1,
))

# --- Tools ---
register_item(Item(
    item_id=ItemType.TOOL_PICKAXE.value,
    name="Scrap Pickaxe",
    description="Makeshift pickaxe for mining stone and scrap.",
    category=ItemCategory.TOOL,
    stack_size=1,
    equipment_slot=EquipmentSlot.TOOL,
    stats=ItemStats(
        mining_speed=1.0,
        range=1.5,
        durability=100,
        max_durability=100,
    ),
    tier=1,
))

register_item(Item(
    item_id=ItemType.TOOL_AXE.value,
    name="Scrap Axe",
    description="Crude axe for chopping wood.",
    category=ItemCategory.TOOL,
    stack_size=1,
    equipment_slot=EquipmentSlot.TOOL,
    stats=ItemStats(
        mining_speed=1.2,
        range=1.5,
        durability=100,
        max_durability=100,
    ),
    tier=1,
))

# --- Weapons (Melee) ---
register_item(Item(
    item_id=ItemType.WEAPON_MELEE_SCRAP_SWORD.value,
    name="Scrap Sword",
    description="A blade made from sharp scrap metal. Better than fists!",
    category=ItemCategory.WEAPON,
    stack_size=1,
    equipment_slot=EquipmentSlot.WEAPON,
    stats=ItemStats(
        damage=15,
        attack_speed=1.2,
        range=2.0,
        durability=150,
        max_durability=150,
    ),
    tier=1,
))

# --- Armor ---
register_item(Item(
    item_id=ItemType.ARMOR_HELMET_SCRAP.value,
    name="Scrap Helmet",
    description="Makeshift helmet from salvaged panels. Basic protection.",
    category=ItemCategory.ARMOR,
    stack_size=1,
    equipment_slot=EquipmentSlot.HELMET,
    stats=ItemStats(
        armor=5,
        durability=200,
        max_durability=200,
    ),
    tier=1,
))

register_item(Item(
    item_id=ItemType.ARMOR_CHEST_SCRAP.value,
    name="Scrap Chestplate",
    description="Heavy scrap metal chest armor. Protects vital organs.",
    category=ItemCategory.ARMOR,
    stack_size=1,
    equipment_slot=EquipmentSlot.CHEST,
    stats=ItemStats(
        armor=10,
        durability=300,
        max_durability=300,
    ),
    tier=1,
))

register_item(Item(
    item_id=ItemType.ARMOR_LEGS_SCRAP.value,
    name="Scrap Leggings",
    description="Scrap metal leg protection. Slows you down a bit.",
    category=ItemCategory.ARMOR,
    stack_size=1,
    equipment_slot=EquipmentSlot.LEGS,
    stats=ItemStats(
        armor=8,
        durability=250,
        max_durability=250,
    ),
    tier=1,
))

# --- Building Materials ---
register_item(Item(
    item_id=ItemType.BUILDING_SCRAP_WALL.value,
    name="Scrap Wall",
    description="Basic wall made from scrap metal. Blocks movement.",
    category=ItemCategory.BUILDING,
    stack_size=99,
    tier=1,
))

register_item(Item(
    item_id=ItemType.BUILDING_SCRAP_FLOOR.value,
    name="Scrap Floor",
    description="Metal floor panel. Makes your base look civilized.",
    category=ItemCategory.BUILDING,
    stack_size=99,
    tier=1,
))

register_item(Item(
    item_id=ItemType.BUILDING_SCRAP_DOOR.value,
    name="Scrap Door",
    description="A door that actually opens. Revolutionary!",
    category=ItemCategory.BUILDING,
    stack_size=99,
    tier=1,
))

# --- Furniture ---
register_item(Item(
    item_id=ItemType.FURNITURE_CHEST.value,
    name="Storage Chest",
    description="Basic storage container. Holds 20 slots.",
    category=ItemCategory.FURNITURE,
    stack_size=10,
    tier=1,
))

register_item(Item(
    item_id=ItemType.FURNITURE_WORKBENCH.value,
    name="Basic Workbench",
    description="Essential crafting station for Tier 1 items.",
    category=ItemCategory.FURNITURE,
    stack_size=1,
    tier=1,
))

# --- Consumables ---
register_item(Item(
    item_id=ItemType.CONSUMABLE_HEALTH_PACK.value,
    name="Scrap Med-Kit",
    description="Makeshift medical supplies. Restores 50 HP.",
    category=ItemCategory.CONSUMABLE,
    stack_size=20,
    tier=1,
))


# ============================================================================
# TIER 2: REFINED ERA (Mid Game) - Placeholder for now
# ============================================================================

register_item(Item(
    item_id=ItemType.RESOURCE_STEEL.value,
    name="Steel Plate",
    description="Refined steel. Much stronger than scrap.",
    category=ItemCategory.RESOURCE,
    stack_size=99,
    tier=2,
))

register_item(Item(
    item_id=ItemType.WEAPON_MELEE_STEEL_BLADE.value,
    name="Steel Blade",
    description="A proper sword forged from steel.",
    category=ItemCategory.WEAPON,
    stack_size=1,
    equipment_slot=EquipmentSlot.WEAPON,
    stats=ItemStats(
        damage=35,
        attack_speed=1.5,
        range=2.5,
        durability=300,
        max_durability=300,
    ),
    tier=2,
))


# ============================================================================
# HELPER FUNCTIONS
# ============================================================================

def get_items_by_category(category: ItemCategory) -> list[Item]:
    """Get all items in a specific category"""
    return [item for item in ITEM_REGISTRY.values() if item.category == category]


def get_items_by_tier(tier: int) -> list[Item]:
    """Get all items of a specific tier"""
    return [item for item in ITEM_REGISTRY.values() if item.tier == tier]


def print_item_registry():
    """Debug: Print all registered items"""
    console.print(f"\n{'='*60}")
    console.print(f"ITEM REGISTRY - {len(ITEM_REGISTRY)} items registered")
    console.print(f"{'='*60}")
    
    for tier in range(1, 5):
        tier_items = get_items_by_tier(tier)
        if tier_items:
            console.print(f"\n🔧 TIER {tier} ({len(tier_items)} items)")
            for item in tier_items:
                stats_str = ""
                if item.stats:
                    stats_str = f" | Dmg:{item.stats.damage} Armor:{item.stats.armor}"
                console.print(f"  • {item.name:30} [{item.category.value}]{stats_str}")


if __name__ == "__main__":
    # Test item system
    print_item_registry()
    
    # Test serialization
    console.print("\n\nTesting serialization:")
    sword = get_item(ItemType.WEAPON_MELEE_SCRAP_SWORD.value)
    console.print(f"\nOriginal: {sword}")
    
    serialized = sword.to_dict()
    console.print(f"\nSerialized: {serialized}")
    
    deserialized = Item.from_dict(serialized)
    console.print(f"\nDeserialized: {deserialized}")
