"""
Equipment router.
Auto-generated from main.py migration.
"""
from fastapi import APIRouter, HTTPException, Depends, status, Request
from fastapi.security import HTTPAuthorizationCredentials
from typing import Optional, Dict, Any
from datetime import datetime
import random
import json
import logging

from ..core.security import get_current_user, security, verify_internal_key
from ..services.models import *
from ..services.helpers import calculate_distance, calculate_stamina_cost, calculate_player_capacity, calculate_crafting_stamina_cost, get_game_message, get_locale_string
from .. import database as db
from ..items import ItemsManager
from .. import game_logic
from ..core.websockets import manager

logger = logging.getLogger(__name__)

# These will be injected by main.py
LOCATIONS = None
ITEMS_MANAGER = None
WORLD = None
redis_manager = None

def init_router_dependencies(locations, items_manager, world, redis_mgr=None):
    """Initialize router with game data dependencies"""
    global LOCATIONS, ITEMS_MANAGER, WORLD, redis_manager
    LOCATIONS = locations
    ITEMS_MANAGER = items_manager
    WORLD = world
    redis_manager = redis_mgr

router = APIRouter(tags=["equipment"])



# Endpoints

@router.post("/api/game/equip")
async def equip_item(
    equip_req: EquipItemRequest,
    request: Request,
    current_user: dict = Depends(get_current_user)
):
    """Equip an item from inventory"""
    player_id = current_user['id']
    locale = request.headers.get('Accept-Language', 'en')
    
    # Get the inventory item
    inv_item = await db.get_inventory_item_by_id(equip_req.inventory_id)
    if not inv_item or inv_item['character_id'] != player_id:
        raise HTTPException(status_code=404, detail="Item not found in inventory")
    
    # Get item definition
    item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
    if not item_def:
        raise HTTPException(status_code=404, detail="Item definition not found")
    
    # Check if item is equippable
    if not item_def.equippable or not item_def.slot:
        raise HTTPException(status_code=400, detail="This item cannot be equipped")
    
    # Check equipment requirements (level + stat gates)
    if item_def.equip_requirements:
        player = await db.get_player_by_id(player_id) if 'level' not in current_user else current_user
        
        req_level = item_def.equip_requirements.get('level', 0)
        if player.get('level', 1) < req_level:
            raise HTTPException(
                status_code=400,
                detail=get_game_message('equip_level_required', locale, level=req_level)
            )
        
        for stat_name in ['strength', 'agility', 'endurance', 'intellect']:
            req_value = item_def.equip_requirements.get(stat_name, 0)
            if req_value > 0 and player.get(stat_name, 0) < req_value:
                raise HTTPException(
                    status_code=400,
                    detail=get_game_message('equip_stat_required', locale, stat=stat_name.capitalize(), value=req_value)
                )
    
    # Check if slot is valid
    valid_slots = ['head', 'torso', 'legs', 'feet', 'weapon', 'offhand', 'backpack']
    if item_def.slot not in valid_slots:
        raise HTTPException(status_code=400, detail=f"Invalid equipment slot: {item_def.slot}")
    
    # Check if slot is already occupied
    current_equipped = await db.get_equipped_item_in_slot(player_id, item_def.slot)
    unequipped_item_name = None
    
    if current_equipped and current_equipped.get('item_id'):
        # Get the old item's name for the message
        old_inv_item = await db.get_inventory_item_by_id(current_equipped['item_id'])
        if old_inv_item:
            old_item_def = ITEMS_MANAGER.get_item(old_inv_item['item_id'])
            unequipped_item_name = old_item_def.name if old_item_def else "previous item"
        
        # Unequip current item first
        await db.unequip_item(player_id, item_def.slot)
        # Mark as not equipped in inventory
        await db.update_inventory_item(current_equipped['item_id'], is_equipped=False)
    
    # Equip the new item
    await db.equip_item(player_id, item_def.slot, equip_req.inventory_id)
    
    # Mark as equipped in inventory
    await db.update_inventory_item(equip_req.inventory_id, is_equipped=True)
    
    # Initialize unique_item if this is first time equipping an equippable with durability
    if inv_item.get('unique_item_id') is None and item_def.durability:
        # Create a unique_item instance for this equipment
        # Save base stats to unique_stats
        base_stats = {k: int(v) if isinstance(v, (int, float)) else v for k, v in item_def.stats.items()} if item_def.stats else {}
        unique_item_id = await db.create_unique_item(
            item_id=item_def.id,
            durability=item_def.durability,
            max_durability=item_def.durability,
            tier=item_def.tier if hasattr(item_def, 'tier') else 1,
            unique_stats=base_stats
        )
        # Link the inventory item to this unique_item
        await db.update_inventory_item(
            equip_req.inventory_id,
            unique_item_id=unique_item_id
        )
    
    # Build message
    if unequipped_item_name:
        message = get_game_message('unequip_equip', locale, old=unequipped_item_name, new=get_locale_string(item_def.name, locale))
    else:
        message = get_game_message('equipped', locale, item=get_locale_string(item_def.name, locale))
    
    # Invalidate cached derived stats (equipment changed)
    from ..services.stats import invalidate_stats_cache
    await invalidate_stats_cache(player_id, redis_manager)
    
    return {
        "success": True,
        "message": message,
        "slot": item_def.slot,
        "unequipped_item": unequipped_item_name
    }


@router.post("/api/game/unequip")
async def unequip_item(
    unequip_req: UnequipItemRequest,
    request: Request,
    current_user: dict = Depends(get_current_user)
):
    """Unequip an item from equipment slot"""
    player_id = current_user['id']
    locale = request.headers.get('Accept-Language', 'en')
    
    # Check if slot is valid
    valid_slots = ['head', 'torso', 'legs', 'feet', 'weapon', 'offhand', 'backpack']
    if unequip_req.slot not in valid_slots:
        raise HTTPException(status_code=400, detail=f"Invalid equipment slot: {unequip_req.slot}")
    
    # Get currently equipped item
    equipped = await db.get_equipped_item_in_slot(player_id, unequip_req.slot)
    if not equipped:
        raise HTTPException(status_code=400, detail=f"No item equipped in {unequip_req.slot} slot")
    
    # Get inventory item and item definition
    inv_item = await db.get_inventory_item_by_id(equipped['item_id'])
    item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
    
    # Check if inventory has space (volume-wise)
    inventory = await db.get_inventory(player_id)
    total_volume = sum(
        ITEMS_MANAGER.get_item(i['item_id']).volume * i['quantity']
        for i in inventory
        if ITEMS_MANAGER.get_item(i['item_id']) and not i['is_equipped']
    )
    
    # Get max volume (base 10 + backpack bonus)
    max_volume = 10.0
    for inv in inventory:
        if inv['is_equipped']:
            item = ITEMS_MANAGER.get_item(inv['item_id'])
            if item:
                # Use unique_stats if this is a unique item, otherwise fall back to default stats
                if inv.get('unique_item_id'):
                    unique_item = await db.get_unique_item(inv['unique_item_id'])
                    if unique_item and unique_item.get('unique_stats'):
                        max_volume += unique_item['unique_stats'].get('volume_capacity', 0)
                elif item.stats:
                    max_volume += item.stats.get('volume_capacity', 0)
    
    # If unequipping backpack, check if items will fit
    if unequip_req.slot == 'backpack':
        # Get the backpack's volume capacity from unique_stats if available
        backpack_volume = 0
        if inv_item.get('unique_item_id'):
            unique_item = await db.get_unique_item(inv_item['unique_item_id'])
            if unique_item and unique_item.get('unique_stats'):
                backpack_volume = unique_item['unique_stats'].get('volume_capacity', 0)
        elif item_def.stats:
            backpack_volume = item_def.stats.get('volume_capacity', 0)
        
        if backpack_volume > 0 and total_volume > (max_volume - backpack_volume):
            raise HTTPException(
                status_code=400,
                detail="Cannot unequip backpack: inventory would exceed volume capacity"
            )
    
    # Check if adding this item would exceed volume
    if total_volume + item_def.volume > max_volume:
        # Drop to ground instead
        await db.unequip_item(player_id, unequip_req.slot)
        await db.update_inventory_item(equipped['item_id'], is_equipped=False)
        await db.drop_item(player_id, inv_item['item_id'], 1, current_user['location_id'])
        await db.remove_from_inventory(player_id, inv_item['item_id'], 1)
        
        # Invalidate cached derived stats
        from ..services.stats import invalidate_stats_cache
        await invalidate_stats_cache(player_id, redis_manager)
        
        return {
            "success": True,
            "message": get_game_message('unequip_dropped', locale, item=get_locale_string(item_def.name, locale)),
            "dropped": True
        }
    
    # Unequip the item
    await db.unequip_item(player_id, unequip_req.slot)
    await db.update_inventory_item(equipped['item_id'], is_equipped=False)
    
    # Invalidate cached derived stats
    from ..services.stats import invalidate_stats_cache
    await invalidate_stats_cache(player_id, redis_manager)
    
    return {
        "success": True,
        "message": get_game_message('unequipped', locale, item=get_locale_string(item_def.name, locale)),
        "dropped": False
    }


@router.get("/api/game/equipment")
async def get_equipment(current_user: dict = Depends(get_current_user)):
    """Get all equipped items"""
    player_id = current_user['id']
    
    equipment = await db.get_all_equipment(player_id)
    
    # Enrich with item data
    enriched = {}
    for slot, item_data in equipment.items():
        if item_data:
            inv_item = await db.get_inventory_item_by_id(item_data['item_id'])
            item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
            if item_def:
                enriched[slot] = {
                    "inventory_id": item_data['item_id'],
                    "item_id": item_def.id,
                    "name": item_def.name,
                    "description": item_def.description,
                    "emoji": item_def.emoji,
                    "image_path": item_def.image_path,
                    "durability": inv_item.get('durability'),
                    "max_durability": inv_item.get('max_durability'),
                    "tier": inv_item.get('tier', 1),
                    "stats": item_def.stats,
                    "encumbrance": item_def.encumbrance
                }
        else:
            enriched[slot] = None
    
    return {"equipment": enriched}


@router.post("/api/game/repair_item")
async def repair_item(
    repair_req: RepairItemRequest,
    request: Request,
    current_user: dict = Depends(get_current_user)
):
    """Repair an item using materials at a workbench location"""
    player_id = current_user['id']
    locale = request.headers.get('Accept-Language', 'en')
    
    # Get player's location
    player = await db.get_player_by_id(player_id)
    location = LOCATIONS.get(player['location_id'])
    
    if not location:
        raise HTTPException(status_code=404, detail="Location not found")
    
    # Check if location has workbench
    location_tags = getattr(location, 'tags', [])
    if 'workbench' not in location_tags and 'repair_station' not in location_tags:
        raise HTTPException(
            status_code=400,
            detail="You need to be at a location with a workbench to repair items. Try the Gas Station!"
        )
    
    # Get inventory item
    inv_item = await db.get_inventory_item(repair_req.inventory_id)
    if not inv_item or inv_item['character_id'] != player_id:
        raise HTTPException(status_code=404, detail="Item not found in inventory")
    
    # Get item definition
    item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
    if not item_def:
        raise HTTPException(status_code=404, detail="Item definition not found")
    
    # Check if item is repairable
    if not getattr(item_def, 'repairable', False):
        raise HTTPException(status_code=400, detail=f"{item_def.name} cannot be repaired")
    
    # Check if item has durability (unique item)
    if not inv_item.get('unique_item_id'):
        raise HTTPException(status_code=400, detail="This item doesn't have durability tracking")
    
    # Get unique item data
    unique_item = await db.get_unique_item(inv_item['unique_item_id'])
    if not unique_item:
        raise HTTPException(status_code=500, detail="Unique item data not found")
    
    current_durability = unique_item.get('durability', 0)
    max_durability = unique_item.get('max_durability', 100)
    
    # Check if item needs repair
    if current_durability >= max_durability:
        raise HTTPException(status_code=400, detail=f"{item_def.name} is already at full durability")
    
    # Get repair materials
    repair_materials = getattr(item_def, 'repair_materials', [])
    if not repair_materials:
        raise HTTPException(status_code=500, detail="Item repair configuration missing")
    
    # Get repair tools
    repair_tools = getattr(item_def, 'repair_tools', [])
    
    # Check if player has all required materials and tools
    player_inventory = await db.get_inventory(player_id)
    inventory_dict = {item['item_id']: item['quantity'] for item in player_inventory}
    
    missing_materials = []
    for material in repair_materials:
        required_qty = material.get('quantity', 1)
        available_qty = inventory_dict.get(material['item_id'], 0)
        if available_qty < required_qty:
            material_def = ITEMS_MANAGER.get_item(material['item_id'])
            material_name = material_def.name if material_def else material['item_id']
            missing_materials.append(f"{material_name} ({available_qty}/{required_qty})")
    
    if missing_materials:
        raise HTTPException(
            status_code=400,
            detail=f"Missing materials: {', '.join(missing_materials)}"
        )
    
    # Check and consume tools if required
    tools_consumed = []
    if repair_tools:
        success, error_msg, tools_consumed = await consume_tool_durability(player_id, repair_tools, player_inventory)
        if not success:
            raise HTTPException(status_code=400, detail=error_msg)
    
    # Calculate stamina cost
    stamina_cost = calculate_crafting_stamina_cost(unique_item.get('tier', 1), 'repair')
    
    # Check stamina
    if player['stamina'] < stamina_cost:
        raise HTTPException(status_code=400, detail=f"Not enough stamina. Need {stamina_cost}, have {player['stamina']}")
    
    # Deduct stamina
    new_stamina = max(0, player['stamina'] - stamina_cost)
    await db.update_player_stamina(player_id, new_stamina)
    
    # Consume materials
    for material in repair_materials:
        await db.remove_item_from_inventory(player_id, material['item_id'], material['quantity'])
    
    # Calculate repair amount
    repair_percentage = getattr(item_def, 'repair_percentage', 25)
    repair_amount = int((max_durability * repair_percentage) / 100)
    new_durability = min(current_durability + repair_amount, max_durability)
    
    # Update unique item durability
    await db.update_unique_item(inv_item['unique_item_id'], durability=new_durability)
    
    # Build materials consumed message
    materials_used = []
    for material in repair_materials:
        material_def = ITEMS_MANAGER.get_item(material['item_id'])
        emoji = material_def.emoji if material_def and hasattr(material_def, 'emoji') else '📦'
        name = material_def.name if material_def else material['item_id']
        materials_used.append(f"{emoji} {name} x{material['quantity']}")
    
    return {
        "success": True,
        "message": get_game_message('repaired_success', locale, item=get_locale_string(item_def.name, locale), amount=repair_amount),
        "item_name": item_def.name,
        "old_durability": current_durability,
        "new_durability": new_durability,
        "max_durability": max_durability,
        "materials_consumed": materials_used,
        "tools_consumed": tools_consumed,
        "repair_amount": repair_amount,
        "stamina_cost": stamina_cost,
        "new_stamina": new_stamina
    }




async def reduce_armor_durability(player_id: int, damage_taken: int) -> tuple:
    """
    Reduce durability of equipped armor pieces when taking damage.
    Formula: durability_loss = max(1, (damage_taken / armor_value) * base_reduction_rate)
    Base reduction rate: 0.5 (so 10 damage with 5 armor = 1 durability loss)
    Returns: (armor_damage_absorbed, broken_armor_pieces)
    """
    equipment = await db.get_all_equipment(player_id)
    armor_pieces = ['head', 'torso', 'legs', 'feet']
    
    total_armor = 0
    equipped_armor = []
    
    # Collect all equipped armor
    for slot in armor_pieces:
        if equipment.get(slot) and equipment[slot]:
            armor_slot = equipment[slot]
            inv_item = await db.get_inventory_item_by_id(armor_slot['item_id'])
            if inv_item and inv_item.get('unique_item_id'):
                item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
                if item_def and item_def.stats and 'armor' in item_def.stats:
                    armor_value = item_def.stats['armor']
                    total_armor += armor_value
                    equipped_armor.append({
                        'slot': slot,
                        'inv_item_id': armor_slot['item_id'],
                        'unique_item_id': inv_item['unique_item_id'],
                        'item_id': inv_item['item_id'],
                        'item_def': item_def,
                        'armor_value': armor_value
                    })
    
    if not equipped_armor:
        return 0, []
    
    # Calculate damage absorbed by armor (total armor reduces damage)
    armor_absorbed = min(damage_taken // 2, total_armor)  # Armor absorbs up to half the damage
    
    # Calculate durability loss for each armor piece
    # Balanced formula: armor should last many combats (10-20+ hits for low tier)
    base_reduction_rate = 0.1  # Reduced from 0.5 to make armor more durable
    broken_armor = []
    
    for armor in equipped_armor:
        # Each piece takes durability loss proportional to its armor value
        proportion = armor['armor_value'] / total_armor if total_armor > 0 else 0
        # Formula: durability_loss = (damage_taken * proportion / armor_value) * base_rate
        # This means higher armor value = less durability loss per hit
        # With base_rate = 0.1, a 5 armor piece taking 10 damage loses ~0.2 durability per hit
        durability_loss = max(1, int((damage_taken * proportion / max(armor['armor_value'], 1)) * base_reduction_rate * 10))
        
        # Get current durability
        unique_item = await db.get_unique_item(armor['unique_item_id'])
        if unique_item:
            current_durability = unique_item.get('durability', 0)
            new_durability = max(0, current_durability - durability_loss)
            
            await db.update_unique_item(armor['unique_item_id'], durability=new_durability)
            
            # If armor broke, unequip and remove from inventory
            if new_durability <= 0:
                await db.unequip_item(player_id, armor['slot'])
                await db.remove_inventory_row(armor['inv_item_id'])
                broken_armor.append({
                    'name': armor['item_def'].name,
                    'emoji': armor['item_def'].emoji,
                    'slot': armor['slot']
                })
    
    return armor_absorbed, broken_armor


async def consume_tool_durability(user_id: int, tools: list, inventory: list) -> tuple:
    """
    Consume durability from required tools.
    Returns: (success, error_message, consumed_tools_info)
    """
    consumed_tools = []
    tools_map = {}
    
    # Build map of available tools with durability
    for inv_item in inventory:
        if inv_item.get('unique_item_id'):
            unique_item = await db.get_unique_item(inv_item['unique_item_id'])
            if unique_item:
                item_id = inv_item['item_id']
                durability = unique_item.get('durability', 0)
                if item_id not in tools_map:
                    tools_map[item_id] = []
                tools_map[item_id].append({
                    'inventory_id': inv_item['id'],
                    'unique_item_id': inv_item['unique_item_id'],
                    'durability': durability,
                    'max_durability': unique_item.get('max_durability', 100)
                })
    
    # Check and consume tools
    for tool_req in tools:
        tool_id = tool_req['item_id']
        durability_cost = tool_req['durability_cost']
        
        if tool_id not in tools_map or not tools_map[tool_id]:
            tool_def = ITEMS_MANAGER.items.get(tool_id)
            tool_name = tool_def.name if tool_def else tool_id
            return False, f"Missing required tool: {tool_name}", []
        
        # Find tool with enough durability
        tool_found = None
        for tool in tools_map[tool_id]:
            if tool['durability'] >= durability_cost:
                tool_found = tool
                break
        
        if not tool_found:
            tool_def = ITEMS_MANAGER.items.get(tool_id)
            tool_name = tool_def.name if tool_def else tool_id
            return False, f"Tool {tool_name} doesn't have enough durability (need {durability_cost})", []
        
        # Consume durability
        new_durability = tool_found['durability'] - durability_cost
        await db.update_unique_item(tool_found['unique_item_id'], durability=new_durability)
        
        # If tool breaks, remove from inventory
        if new_durability <= 0:
            await db.remove_inventory_row(tool_found['inventory_id'])
        
        tool_def = ITEMS_MANAGER.items.get(tool_id)
        consumed_tools.append({
            'item_id': tool_id,
            'name': tool_def.name if tool_def else tool_id,
            'durability_cost': durability_cost,
            'broke': new_durability <= 0
        })
    
    return True, "", consumed_tools


@router.get("/api/game/repairable")
async def get_repairable_items(current_user: dict = Depends(get_current_user)):
    """Get all repairable items from inventory and equipped slots"""
    try:
        player = current_user  # current_user is already the character dict
        if not player:
            raise HTTPException(status_code=404, detail="Player not found")
        
        location_id = player['location_id']
        location = LOCATIONS.get(location_id)
        
        # Check if player is at a repair station
        if not location or 'repair_station' not in getattr(location, 'tags', []):
            raise HTTPException(status_code=400, detail="You must be at a repair station to repair items")
        
        repairable_items = []
        
        # Check inventory items
        inventory = await db.get_inventory(current_user['id'])
        inventory_counts = {}
        for inv_item in inventory:
            item_id = inv_item['item_id']
            quantity = inv_item.get('quantity', 1)
            inventory_counts[item_id] = inventory_counts.get(item_id, 0) + quantity
        
        for inv_item in inventory:
            if inv_item.get('unique_item_id'):
                unique_item = await db.get_unique_item(inv_item['unique_item_id'])
                if not unique_item:
                    continue
                
                item_def = ITEMS_MANAGER.items.get(inv_item['item_id'])
                if not item_def or not getattr(item_def, 'repairable', False):
                    continue
                
                current_durability = unique_item.get('durability', 0)
                max_durability = unique_item.get('max_durability', 100)
                needs_repair = current_durability < max_durability
                
                # Check materials availability
                repair_materials = getattr(item_def, 'repair_materials', [])
                materials_info = []
                has_materials = True
                for material in repair_materials:
                    mat_item_def = ITEMS_MANAGER.items.get(material['item_id'])
                    available = inventory_counts.get(material['item_id'], 0)
                    required = material['quantity']
                    materials_info.append({
                        'item_id': material['item_id'],
                        'name': mat_item_def.name if mat_item_def else material['item_id'],
                        'emoji': mat_item_def.emoji if mat_item_def else '📦',
                        'quantity': required,
                        'available': available,
                        'has_enough': available >= required
                    })
                    if available < required:
                        has_materials = False
                
                # Check tools availability
                repair_tools = getattr(item_def, 'repair_tools', [])
                tools_info = []
                has_tools = True
                for tool_req in repair_tools:
                    tool_id = tool_req['item_id']
                    durability_cost = tool_req['durability_cost']
                    tool_def = ITEMS_MANAGER.items.get(tool_id)
                    
                    # Check if player has this tool (find one with highest durability)
                    tool_found = False
                    tool_durability = 0
                    tool_max_durability = 0
                    best_tool_unique = None
                    
                    for check_item in inventory:
                        if check_item['item_id'] == tool_id and check_item.get('unique_item_id'):
                            unique = await db.get_unique_item(check_item['unique_item_id'])
                            if unique and unique.get('durability', 0) >= durability_cost:
                                if best_tool_unique is None or unique.get('durability', 0) > best_tool_unique.get('durability', 0):
                                    best_tool_unique = unique
                                    tool_found = True
                                    tool_durability = unique.get('durability', 0)
                                    tool_max_durability = unique.get('max_durability', 100)
                    
                    
                    tools_info.append({
                        'item_id': tool_id,
                        'name': tool_def.name if tool_def else tool_id,
                        'emoji': tool_def.emoji if tool_def else '🔧',
                        'durability_cost': durability_cost,
                        'has_tool': tool_found,
                        'tool_durability': tool_durability,
                        'tool_max_durability': tool_max_durability
                    })
                    if not tool_found:
                        has_tools = False
                
                can_repair = needs_repair and has_materials and has_tools
                
                repairable_items.append({
                    'inventory_id': inv_item['id'],
                    'unique_item_id': inv_item['unique_item_id'],
                    'item_id': inv_item['item_id'],
                    'name': item_def.name,
                    'emoji': item_def.emoji,
                    'unique_item_data': {k: int(v) if isinstance(v, (int, float)) and k != 'durability_percent' else v for k, v in unique_item.items()},
                    'tier': unique_item.get('tier', 1),
                    'current_durability': current_durability,
                    'max_durability': max_durability,
                    'durability_percent': int((current_durability / max_durability) * 100),
                    'repair_percentage': getattr(item_def, 'repair_percentage', 25),
                    'needs_repair': needs_repair,
                    'materials': materials_info,
                    'tools': tools_info,
                    'can_repair': can_repair,
                    'location': 'equipped' if inv_item.get('is_equipped') else 'inventory',
                    'stamina_cost': calculate_crafting_stamina_cost(unique_item.get('tier', 1), 'repair'),
                    'type': getattr(item_def, 'type', 'misc')
                })
        
        # Sort: repairable items first (can_repair=True), then by durability percent (lowest first), then by name
        repairable_items.sort(key=lambda x: (not x['can_repair'], -x['durability_percent'], str(x['name'])))
        
        return {'repairable_items': repairable_items}
    
    except Exception as e:
        print(f"Error getting repairable items: {e}")
        import traceback
        traceback.print_exc()
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/api/game/salvageable")
async def get_salvageable_items(current_user: dict = Depends(get_current_user)):
    """Get list of salvageable (uncraftable) items from inventory with their unique stats"""
    try:
        player = current_user  # current_user is already the character dict
        if not player:
            raise HTTPException(status_code=404, detail="Player not found")
        
        location_id = player['location_id']
        location = LOCATIONS.get(location_id)
        
        # Check if player is at a workbench
        if not location or 'workbench' not in getattr(location, 'tags', []):
            return {'salvageable_items': [], 'at_workbench': False}
        
        # Get inventory
        inventory = await db.get_inventory(current_user['id'])
        
        salvageable_items = []
        for inv_item in inventory:
            item_id = inv_item['item_id']
            item_def = ITEMS_MANAGER.items.get(item_id)
            
            if not item_def or not getattr(item_def, 'uncraftable', False):
                continue
            
            # Get unique item details if it exists
            unique_item_data = None
            if inv_item.get('unique_item_id'):
                unique_item = await db.get_unique_item(inv_item['unique_item_id'])
                if unique_item:
                    current_durability = unique_item.get('durability', 0)
                    max_durability = unique_item.get('max_durability', 1)
                    durability_percent = int((current_durability / max_durability) * 100) if max_durability > 0 else 0
                    
                    # Get item stats from definition merged with unique stats
                    item_stats = {}
                    if item_def.stats:
                        item_stats = dict(item_def.stats)
                    if unique_item.get('unique_stats'):
                        item_stats.update(unique_item.get('unique_stats'))
                    
                    unique_item_data = {
                        'current_durability': current_durability,
                        'max_durability': max_durability,
                        'durability_percent': durability_percent,
                        'tier': unique_item.get('tier', 1),
                        'unique_stats': item_stats  # Includes both base stats and unique overrides
                    }
            
            # Get uncraft yield
            uncraft_yield = getattr(item_def, 'uncraft_yield', [])
            yield_info = []
            for material in uncraft_yield:
                mat_def = ITEMS_MANAGER.items.get(material['item_id'])
                yield_info.append({
                    'item_id': material['item_id'],
                    'name': mat_def.name if mat_def else material['item_id'],
                    'emoji': mat_def.emoji if mat_def else '📦',
                    'quantity': material['quantity']
                })
            
            # Check tools availability for uncrafting
            uncraft_tools = getattr(item_def, 'uncraft_tools', [])
            tools_info = []
            has_tools = True
            for tool_req in uncraft_tools:
                tool_id = tool_req['item_id']
                durability_cost = tool_req['durability_cost']
                tool_def = ITEMS_MANAGER.items.get(tool_id)
                
                # Check if player has this tool (find one with highest durability)
                tool_found = False
                tool_durability = 0
                best_tool_unique = None
                
                for check_item in inventory:
                    if check_item['item_id'] == tool_id and check_item.get('unique_item_id'):
                        unique = await db.get_unique_item(check_item['unique_item_id'])
                        if unique and unique.get('durability', 0) >= durability_cost:
                            if best_tool_unique is None or unique.get('durability', 0) > best_tool_unique.get('durability', 0):
                                best_tool_unique = unique
                                tool_found = True
                                tool_durability = unique.get('durability', 0)
                
                tools_info.append({
                    'item_id': tool_id,
                    'name': tool_def.name if tool_def else tool_id,
                    'emoji': tool_def.emoji if tool_def else '🔧',
                    'durability_cost': durability_cost,
                    'has_tool': tool_found,
                    'tool_durability': tool_durability
                })
                
                if not tool_found:
                    has_tools = False
            
            can_uncraft = has_tools
            
            # Build item entry
            item_entry = {
                'inventory_id': inv_item['id'],
                'unique_item_id': inv_item.get('unique_item_id'),
                'item_id': item_id,
                'name': item_def.name,
                'emoji': item_def.emoji,
                'image_path': getattr(item_def, 'image_path', None),
                'tier': getattr(item_def, 'tier', 1),
                'quantity': inv_item['quantity'],
                'base_yield': yield_info,
                'loss_chance': getattr(item_def, 'uncraft_loss_chance', 0.3),
                'stamina_cost': calculate_crafting_stamina_cost(getattr(item_def, 'tier', 1), 'uncraft'),
                'can_uncraft': can_uncraft,
                'uncraft_tools': tools_info,
                'location': 'equipped' if inv_item.get('is_equipped') else 'inventory',
                'type': getattr(item_def, 'type', 'misc')
            }
            
            # Add unique item data if available
            if unique_item_data:
                item_entry['unique_item_data'] = unique_item_data
                item_entry['unique_stats'] = unique_item_data.get('unique_stats', {})
                item_entry['current_durability'] = unique_item_data.get('current_durability')
                item_entry['max_durability'] = unique_item_data.get('max_durability')
                item_entry['durability_percent'] = unique_item_data.get('durability_percent')
            
            salvageable_items.append(item_entry)
        
        return {
            'salvageable_items': salvageable_items,
            'at_workbench': True
        }
    
    except Exception as e:
        print(f"Error getting salvageable items: {e}")
        import traceback
        traceback.print_exc()
        raise HTTPException(status_code=500, detail=str(e))


class LootCorpseRequest(BaseModel):
    corpse_id: str
    item_index: Optional[int] = None  # Index of specific item to loot (None = all)