"""
Combat router.
Auto-generated from main.py migration.
"""
from fastapi import APIRouter, HTTPException, Depends, status
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
from .. import database as db
from ..items import ItemsManager
from .. import game_logic
from ..core.websockets import manager
from .equipment import reduce_armor_durability

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=["combat"])



# Endpoints

@router.get("/api/game/combat")
async def get_combat_status(current_user: dict = Depends(get_current_user)):
    """Get current combat status"""
    combat = await db.get_active_combat(current_user['id'])
    if not combat:
        return {"in_combat": False}
    
    # Load NPC data from npcs.json
    import sys
    sys.path.insert(0, '/app')
    from data.npcs import NPCS
    npc_def = NPCS.get(combat['npc_id'])
    
    # Calculate time remaining for turn (server-side to avoid clock offset)
    import time
    turn_time_remaining = None
    if combat['turn'] == 'player':
        turn_started_at = combat.get('turn_started_at', 0)
        time_elapsed = time.time() - turn_started_at
        turn_time_remaining = max(0, 300 - time_elapsed)  # 5 minutes = 300 seconds
    
    return {
        "in_combat": True,
        "combat": {
            "npc_id": combat['npc_id'],
            "npc_name": npc_def.name if npc_def else combat['npc_id'].replace('_', ' ').title(),
            "npc_hp": combat['npc_hp'],
            "npc_max_hp": combat['npc_max_hp'],
            "npc_image": f"{npc_def.image_path}" if npc_def else None,
            "turn": combat['turn'],
            "round": combat.get('round', 1),
            "turn_time_remaining": turn_time_remaining
        }
    }


@router.post("/api/game/combat/initiate")
async def initiate_combat(
    req: InitiateCombatRequest,
    current_user: dict = Depends(get_current_user)
):
    """Start combat with a wandering enemy"""
    import random
    import sys
    sys.path.insert(0, '/app')
    from data.npcs import NPCS
    
    # Check if already in combat
    existing_combat = await db.get_active_combat(current_user['id'])
    if existing_combat:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Already in combat"
        )
    
    # Get enemy from wandering_enemies table
    async with db.DatabaseSession() as session:
        from sqlalchemy import select
        stmt = select(db.wandering_enemies).where(db.wandering_enemies.c.id == req.enemy_id)
        result = await session.execute(stmt)
        enemy = result.fetchone()
    
    if not enemy:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Enemy not found"
        )
    
    # Get NPC definition
    npc_def = NPCS.get(enemy.npc_id)
    if not npc_def:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="NPC definition not found"
        )
    
    # Randomize HP
    npc_hp = random.randint(npc_def.hp_min, npc_def.hp_max)
    
    # Create combat
    combat = await db.create_combat(
        player_id=current_user['id'],
        npc_id=enemy.npc_id,
        npc_hp=npc_hp,
        npc_max_hp=npc_hp,
        location_id=current_user['location_id'],
        from_wandering=True
    )
    
    # Remove the wandering enemy from the location
    async with db.DatabaseSession() as session:
        from sqlalchemy import delete
        stmt = delete(db.wandering_enemies).where(db.wandering_enemies.c.id == req.enemy_id)
        await session.execute(stmt)
        await session.commit()
    
    # Track combat initiation
    await db.update_player_statistics(current_user['id'], combats_initiated=1, increment=True)
    
    # Get player info for broadcasts
    player = current_user  # current_user is already the character dict
    
    # Send WebSocket update to the player
    await manager.send_personal_message(current_user['id'], {
        "type": "combat_started",
        "data": {
            "message": f"Combat started with {npc_def.name}!",
            "combat": {
                "npc_id": enemy.npc_id,
                "npc_name": npc_def.name,
                "npc_hp": npc_hp,
                "npc_max_hp": npc_hp,
                "npc_image": f"{npc_def.image_path}",
                "turn": "player",
                "round": 1
            }
        },
        "timestamp": datetime.utcnow().isoformat()
    })
    
    # Broadcast to location that player entered combat
    await manager.send_to_location(
        location_id=current_user['location_id'],
        message={
            "type": "location_update",
            "data": {
                "message": f"{player['name']} entered combat with {npc_def.name}",
                "action": "combat_started",
                "player_id": player['id']
            },
            "timestamp": datetime.utcnow().isoformat()
        },
        exclude_player_id=current_user['id']
    )
    
    return {
        "success": True,
        "message": f"Combat started with {npc_def.name}!",
        "combat": {
            "npc_id": enemy.npc_id,
            "npc_name": npc_def.name,
            "npc_hp": npc_hp,
            "npc_max_hp": npc_hp,
            "npc_image": f"{npc_def.image_path}",
            "turn": "player",
            "round": 1
        }
    }


@router.post("/api/game/combat/action")
async def combat_action(
    req: CombatActionRequest,
    current_user: dict = Depends(get_current_user)
):
    """Perform a combat action"""
    import random
    import sys
    sys.path.insert(0, '/app')
    from data.npcs import NPCS
    
    # Get active combat
    combat = await db.get_active_combat(current_user['id'])
    if not combat:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Not in combat"
        )
    
    if combat['turn'] != 'player':
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Not your turn"
        )
    
    # Prevent rapid-fire attacks: Check if enough time has passed since last action
    # This prevents abuse by reloading the page to bypass the 2-second enemy turn delay
    # Skip this check on the first turn (round 1) since player always starts
    import time
    current_round = combat.get('round', 1)
    
    if current_round > 1:  # Only check after first turn
        turn_started_at = combat.get('turn_started_at', 0)
        time_since_turn_start = time.time() - turn_started_at
        
        # If the turn just started (less than 2 seconds ago), it means the enemy just attacked
        # and we should wait for the animation to complete
        if time_since_turn_start < 2.0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Please wait for the enemy's turn to complete"
            )
    
    # Get player and NPC data
    player = current_user  # current_user is already the character dict
    npc_def = NPCS.get(combat['npc_id'])
    
    result_message = ""
    combat_over = False
    player_won = False
    
    if req.action == 'attack':
        # Calculate player damage
        base_damage = 5
        strength_bonus = player['strength'] // 2
        level_bonus = player['level']
        weapon_damage = 0
        weapon_effects = {}
        weapon_inv_id = None
        
        # Check for equipped weapon
        equipment = await db.get_all_equipment(player['id'])
        if equipment.get('weapon') and equipment['weapon']:
            weapon_slot = equipment['weapon']
            inv_item = await db.get_inventory_item_by_id(weapon_slot['item_id'])
            if inv_item:
                weapon_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
                if weapon_def and weapon_def.stats:
                    weapon_damage = random.randint(
                        weapon_def.stats.get('damage_min', 0),
                        weapon_def.stats.get('damage_max', 0)
                    )
                    weapon_effects = weapon_def.weapon_effects if hasattr(weapon_def, 'weapon_effects') else {}
                    weapon_inv_id = weapon_slot['item_id']
        
        # Check encumbrance penalty (higher encumbrance = chance to miss)
        encumbrance = player.get('encumbrance', 0)
        attack_failed = False
        if encumbrance > 0:
            miss_chance = min(0.3, encumbrance * 0.05)  # Max 30% miss chance
            if random.random() < miss_chance:
                attack_failed = True
        
        variance = random.randint(-2, 2)
        damage = max(1, base_damage + strength_bonus + level_bonus + weapon_damage + variance)
        
        if attack_failed:
            result_message = f"Your attack misses due to heavy encumbrance! "
            new_npc_hp = combat['npc_hp']
        else:
            # Apply damage to NPC
            new_npc_hp = max(0, combat['npc_hp'] - damage)
            result_message = f"You attack for {damage} damage! "
            
            # Apply weapon effects
            if weapon_effects and 'bleeding' in weapon_effects:
                bleeding = weapon_effects['bleeding']
                if random.random() < bleeding.get('chance', 0):
                    # Apply bleeding effect (would need combat effects table, for now just bonus damage)
                    bleed_damage = bleeding.get('damage', 0)
                    new_npc_hp = max(0, new_npc_hp - bleed_damage)
                    result_message += f"💉 Bleeding effect! +{bleed_damage} damage! "
            
            # Decrease weapon durability (from unique_item)
            if weapon_inv_id and inv_item.get('unique_item_id'):
                new_durability = await db.decrease_unique_item_durability(inv_item['unique_item_id'], 1)
                if new_durability is None:
                    # Weapon broke (unique_item was deleted, cascades to inventory)
                    result_message += "\n⚠️ Your weapon broke! "
                    await db.unequip_item(player['id'], 'weapon')
        
        if new_npc_hp <= 0:
            # NPC defeated
            result_message += f"{npc_def.name} has been defeated!"
            combat_over = True
            player_won = True
            
            # Award XP
            xp_gained = npc_def.xp_reward
            new_xp = player['xp'] + xp_gained
            result_message += f"\n+{xp_gained} XP"
            
            await db.update_player(player['id'], xp=new_xp)
            
            # Track kill statistics
            await db.update_player_statistics(player['id'], enemies_killed=1, damage_dealt=damage, increment=True)
            
            # Check for level up
            level_up_result = await game_logic.check_and_apply_level_up(player['id'])
            if level_up_result['leveled_up']:
                result_message += f"\n🎉 Level Up! You are now level {level_up_result['new_level']}!"
                result_message += f"\n+{level_up_result['levels_gained']} stat point(s) to spend!"
            
            # Create corpse with loot
            import json
            corpse_loot = npc_def.corpse_loot if hasattr(npc_def, 'corpse_loot') else []
            # Convert CorpseLoot objects to dicts
            corpse_loot_dicts = []
            for loot in corpse_loot:
                if hasattr(loot, '__dict__'):
                    corpse_loot_dicts.append({
                        'item_id': loot.item_id,
                        'quantity_min': loot.quantity_min,
                        'quantity_max': loot.quantity_max,
                        'required_tool': loot.required_tool
                    })
                else:
                    corpse_loot_dicts.append(loot)
            await db.create_npc_corpse(
                npc_id=combat['npc_id'],
                location_id=player['location_id'],
                loot_remaining=json.dumps(corpse_loot_dicts)
            )
            
            await db.end_combat(player['id'])
            
            # Update Redis: Delete combat state cache
            if redis_manager:
                await redis_manager.delete_combat_state(player['id'])
                # Update player session
                await redis_manager.update_player_session_field(player['id'], 'xp', new_xp)
                if level_up_result['leveled_up']:
                    await redis_manager.update_player_session_field(player['id'], 'level', level_up_result['new_level'])
            
            # Broadcast to location that combat ended and corpse appeared
            await manager.send_to_location(
                location_id=player['location_id'],
                message={
                    "type": "location_update",
                    "data": {
                        "message": f"{player['name']} defeated {npc_def.name}",
                        "action": "combat_ended",
                        "player_id": player['id'],
                        "corpse_created": True
                    },
                    "timestamp": datetime.utcnow().isoformat()
                },
                exclude_player_id=player['id']
            )
            
        else:
            # NPC's turn - use shared logic
            npc_attack_message, player_defeated = await game_logic.npc_attack(
                player['id'], 
                {'npc_hp': new_npc_hp, 'npc_max_hp': combat['npc_max_hp']}, 
                npc_def, 
                reduce_armor_durability
            )
            result_message += f"\n{npc_attack_message}"
            
            if player_defeated:
                combat_over = True
            else:
                # Update NPC HP (combat turn already updated by npc_attack)
                await db.update_combat(player['id'], {
                    'npc_hp': new_npc_hp
                })
    
    elif req.action == 'flee':
        # 50% chance to flee
        if random.random() < 0.5:
            result_message = "You successfully fled from combat!"
            combat_over = True
            player_won = False  # Fled, not won
            
            # Track successful flee
            await db.update_player_statistics(player['id'], successful_flees=1, increment=True)
            
            # Respawn the enemy back to the location if it came from wandering
            if combat.get('from_wandering_enemy'):
                # Respawn enemy with current HP at the combat location
                import time
                despawn_time = time.time() + 300  # 5 minutes
                async with db.DatabaseSession() as session:
                    from sqlalchemy import insert
                    stmt = insert(db.wandering_enemies).values(
                        npc_id=combat['npc_id'],
                        location_id=combat['location_id'],
                        spawn_timestamp=time.time(),
                        despawn_timestamp=despawn_time
                    )
                    await session.execute(stmt)
                    await session.commit()
            
            await db.end_combat(player['id'])
            
            # Broadcast to location that player fled from combat
            await manager.send_to_location(
                location_id=combat['location_id'],
                message={
                    "type": "location_update",
                    "data": {
                        "message": f"{player['name']} fled from combat",
                        "action": "combat_fled",
                        "player_id": player['id']
                    },
                    "timestamp": datetime.utcnow().isoformat()
                },
                exclude_player_id=player['id']
            )
        else:
            # Failed to flee, NPC attacks
            npc_damage = random.randint(npc_def.damage_min, npc_def.damage_max)
            new_player_hp = max(0, player['hp'] - npc_damage)
            result_message = f"Failed to flee! {npc_def.name} attacks for {npc_damage} damage!"
            
            if new_player_hp <= 0:
                result_message += "\nYou have been defeated!"
                combat_over = True
                await db.update_player(player['id'], hp=0, is_dead=True)
                await db.update_player_statistics(player['id'], deaths=1, failed_flees=1, damage_taken=npc_damage, increment=True)
                
                # Create corpse with player's inventory
                import json
                import time as time_module
                inventory = await db.get_inventory(player['id'])
                inventory_items = []
                for inv_item in inventory:
                    item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
                    inventory_items.append({
                        'item_id': inv_item['item_id'],
                        'name': item_def.name if item_def else inv_item['item_id'],
                        'emoji': item_def.emoji if (item_def and hasattr(item_def, 'emoji')) else '📦',
                        'quantity': inv_item['quantity'],
                        'durability': inv_item.get('durability'),
                        'max_durability': inv_item.get('max_durability'),
                        'tier': inv_item.get('tier')
                    })
                
                logger.info(f"Creating player corpse (failed flee) for {player['name']} at {combat['location_id']} with {len(inventory_items)} items")
                
                corpse_id = await db.create_player_corpse(
                    player_name=player['name'],
                    location_id=combat['location_id'],
                    items=json.dumps([{'item_id': i['item_id'], 'quantity': i['quantity']} for i in inventory])
                )
                
                logger.info(f"Successfully created player corpse (failed flee): ID={corpse_id}, player={player['name']}, location={combat['location_id']}, items_count={len(inventory_items)}")
                
                # Clear player's inventory (items are now in corpse)
                await db.clear_inventory(player['id'])
                
                # Build corpse data for broadcast
                corpse_data = {
                    "id": f"player_{corpse_id}",
                    "type": "player",
                    "name": f"{player['name']}'s Corpse",
                    "emoji": "⚰️",
                    "player_name": player['name'],
                    "loot_count": len(inventory_items),
                    "items": inventory_items,
                    "timestamp": time_module.time()
                }
                
                # Respawn enemy if from wandering
                if combat.get('from_wandering_enemy'):
                    import time
                    despawn_time = time.time() + 300
                    async with db.DatabaseSession() as session:
                        from sqlalchemy import insert
                        stmt = insert(db.wandering_enemies).values(
                            npc_id=combat['npc_id'],
                            location_id=combat['location_id'],
                            spawn_timestamp=time.time(),
                            despawn_timestamp=despawn_time
                        )
                        await session.execute(stmt)
                        await session.commit()
                
                await db.end_combat(player['id'])
                
                # Broadcast to location that player died and corpse appeared
                logger.info(f"Broadcasting player_died (failed flee) to location {combat['location_id']} for player {player['name']}")
                await manager.send_to_location(
                    location_id=combat['location_id'],
                    message={
                        "type": "location_update",
                        "data": {
                            "message": f"{player['name']} was defeated in combat",
                            "action": "player_died",
                            "player_id": player['id'],
                            "corpse": corpse_data
                        },
                        "timestamp": datetime.utcnow().isoformat()
                    },
                    exclude_player_id=player['id']
                )
            else:
                # Player survived, update HP and turn back to player
                await db.update_player(player['id'], hp=new_player_hp)
                await db.update_player_statistics(player['id'], failed_flees=1, damage_taken=npc_damage, increment=True)
                await db.update_combat(player['id'], {'turn': 'player', 'turn_started_at': time.time()})
    
    # Get updated combat state if not over
    updated_combat = None
    if not combat_over:
        raw_combat = await db.get_active_combat(current_user['id'])
        if raw_combat:
            # Calculate time remaining for turn
            import time
            turn_time_remaining = None
            if raw_combat['turn'] == 'player':
                turn_started_at = raw_combat.get('turn_started_at', 0)
                time_elapsed = time.time() - turn_started_at
                turn_time_remaining = max(0, 300 - time_elapsed)
            
            updated_combat = {
                "npc_id": raw_combat['npc_id'],
                "npc_name": npc_def.name,
                "npc_hp": raw_combat['npc_hp'],
                "npc_max_hp": raw_combat['npc_max_hp'],
                "npc_image": f"{npc_def.image_path}",
                "turn": raw_combat['turn'],
                "round": raw_combat.get('round', 1),
                "turn_time_remaining": turn_time_remaining
            }
    
    # Get fresh player data with updated HP after NPC attack
    updated_player = await db.get_player_by_id(current_user['id'])
    if not updated_player:
        updated_player = current_user  # Fallback to current_user if something went wrong
    
    # Note: PvE combat_update WebSocket removed - frontend uses client-side timer
    # and polling for AFK timeout handling. WebSocket still used for PvP.
    
    return {
        "success": True,
        "message": result_message,
        "combat_over": combat_over,
        "player_won": player_won if combat_over else None,
        "combat": updated_combat if updated_combat else None,
        "player": {
            "hp": updated_player['hp'],
            "max_hp": updated_player.get('max_hp', updated_player.get('max_health')),
            "xp": updated_player['xp'],
            "level": updated_player['level']
        }
    }


@router.post("/api/game/pvp/initiate")
async def initiate_pvp_combat(
    req: PvPCombatInitiateRequest,
    current_user: dict = Depends(get_current_user)
):
    """Initiate PvP combat with another player"""
    # Get attacker (current user)
    attacker = await db.get_player_by_id(current_user['id'])
    if not attacker:
        raise HTTPException(status_code=404, detail="Player not found")
    
    # Check if attacker is already in combat
    existing_combat = await db.get_active_combat(attacker['id'])
    if existing_combat:
        raise HTTPException(status_code=400, detail="You are already in PvE combat")
    
    existing_pvp = await db.get_pvp_combat_by_player(attacker['id'])
    if existing_pvp:
        raise HTTPException(status_code=400, detail="You are already in PvP combat")
    
    # Get defender (target player)
    defender = await db.get_player_by_id(req.target_player_id)
    if not defender:
        raise HTTPException(status_code=404, detail="Target player not found")
    
    # Check if defender is in combat
    defender_pve = await db.get_active_combat(defender['id'])
    if defender_pve:
        raise HTTPException(status_code=400, detail="Target player is in PvE combat")
    
    defender_pvp = await db.get_pvp_combat_by_player(defender['id'])
    if defender_pvp:
        raise HTTPException(status_code=400, detail="Target player is in PvP combat")
    
    # Check same location
    if attacker['location_id'] != defender['location_id']:
        raise HTTPException(status_code=400, detail="Target player is not in your location")
    
    # Check danger level (>= 3 required for PvP)
    location = LOCATIONS.get(attacker['location_id'])
    if not location or location.danger_level < 3:
        raise HTTPException(status_code=400, detail="PvP combat is only allowed in dangerous zones (danger level >= 3)")
    
    # Check level difference (+/- 3 levels)
    level_diff = abs(attacker['level'] - defender['level'])
    if level_diff > 3:
        raise HTTPException(
            status_code=400, 
            detail=f"Level difference too large! You can only fight players within 3 levels (target is level {defender['level']})"
        )
    
    # Create PvP combat
    pvp_combat = await db.create_pvp_combat(
        attacker_id=attacker['id'],
        defender_id=defender['id'],
        location_id=attacker['location_id'],
        turn_timeout=300  # 5 minutes
    )
    
    # Track PvP combat initiation
    await db.update_player_statistics(attacker['id'], pvp_combats_initiated=1, increment=True)
    
    # Send WebSocket notifications to both players
    await manager.send_personal_message(attacker['id'], {
        "type": "combat_started",
        "data": {
            "message": f"You have initiated combat with {defender['name']}! They get the first turn.",
            "pvp_combat": pvp_combat
        },
        "timestamp": datetime.utcnow().isoformat()
    })
    
    await manager.send_personal_message(defender['id'], {
        "type": "combat_started",
        "data": {
            "message": f"{attacker['name']} has challenged you to PvP combat! It's your turn.",
            "pvp_combat": pvp_combat
        },
        "timestamp": datetime.utcnow().isoformat()
    })
    
    return {
        "success": True,
        "message": f"You have initiated combat with {defender['name']}! They get the first turn.",
        "pvp_combat": pvp_combat
    }


@router.get("/api/game/pvp/status")
async def get_pvp_combat_status(current_user: dict = Depends(get_current_user)):
    """Get current PvP combat status"""
    pvp_combat = await db.get_pvp_combat_by_player(current_user['id'])
    if not pvp_combat:
        return {"in_pvp_combat": False, "pvp_combat": None}
    
    # Check if current player has already acknowledged - if so, don't show combat anymore
    is_attacker = pvp_combat['attacker_character_id'] == current_user['id']
    if (is_attacker and pvp_combat.get('attacker_acknowledged', False)) or \
       (not is_attacker and pvp_combat.get('defender_acknowledged', False)):
        return {"in_pvp_combat": False, "pvp_combat": None}
    
    # Get both players' data
    attacker = await db.get_player_by_id(pvp_combat['attacker_character_id'])
    defender = await db.get_player_by_id(pvp_combat['defender_character_id'])
    
    # Determine if current user is attacker or defender
    is_attacker = pvp_combat['attacker_character_id'] == current_user['id']
    your_turn = (is_attacker and pvp_combat['turn'] == 'attacker') or \
                (not is_attacker and pvp_combat['turn'] == 'defender')
    
    # Calculate time remaining for turn
    import time
    time_elapsed = time.time() - pvp_combat['turn_started_at']
    time_remaining = max(0, pvp_combat['turn_timeout_seconds'] - time_elapsed)
    
    # Auto-advance if time expired
    if time_remaining == 0 and your_turn:
        # Skip turn
        new_turn = 'defender' if is_attacker else 'attacker'
        await db.update_pvp_combat(pvp_combat['id'], {
            'turn': new_turn,
            'turn_started_at': time.time()
        })
        pvp_combat = await db.get_pvp_combat_by_id(pvp_combat['id'])
        your_turn = False
        time_remaining = pvp_combat['turn_timeout_seconds']
    
    return {
        "in_pvp_combat": True,
        "pvp_combat": {
            "id": pvp_combat['id'],
            "attacker": {
                "id": attacker['id'],
                "username": attacker['name'],
                "level": attacker['level'],
                "hp": attacker['hp'],  # Use actual player HP
                "max_hp": attacker['max_hp']
            },
            "defender": {
                "id": defender['id'],
                "username": defender['name'],
                "level": defender['level'],
                "hp": defender['hp'],  # Use actual player HP
                "max_hp": defender['max_hp']
            },
            "is_attacker": is_attacker,
            "your_turn": your_turn,
            "current_turn": pvp_combat['turn'],
            "time_remaining": int(time_remaining),
            "location_id": pvp_combat['location_id'],
            "last_action": pvp_combat.get('last_action'),
            "combat_over": pvp_combat.get('attacker_fled', False) or pvp_combat.get('defender_fled', False) or \
                          attacker['hp'] <= 0 or defender['hp'] <= 0,
            "attacker_fled": pvp_combat.get('attacker_fled', False),
            "defender_fled": pvp_combat.get('defender_fled', False)
        }
    }


class PvPAcknowledgeRequest(BaseModel):
    combat_id: int


@router.post("/api/game/pvp/acknowledge")
async def acknowledge_pvp_combat(
    req: PvPAcknowledgeRequest,
    current_user: dict = Depends(get_current_user)
):
    """Acknowledge PvP combat end"""
    await db.acknowledge_pvp_combat(req.combat_id, current_user['id'])
    
    # Broadcast to location that player has returned
    player = current_user  # current_user is already the character dict
    if player:
        await manager.send_to_location(
            location_id=player['location_id'],
            message={
                "type": "player_arrived",
                "data": {
                    "player_id": player['id'],
                    "username": player['name'],
                    "message": f"{player['name']} has returned from PvP combat."
                },
                "timestamp": datetime.utcnow().isoformat()
            },
            exclude_player_id=player['id']
        )
    
    return {"success": True}


class PvPCombatActionRequest(BaseModel):
    action: str  # 'attack', 'flee', 'use_item'
    item_id: Optional[str] = None  # For use_item action


@router.post("/api/game/pvp/action")
async def pvp_combat_action(
    req: PvPCombatActionRequest,
    current_user: dict = Depends(get_current_user)
):
    """Perform a PvP combat action"""
    import random
    import time
    
    # Get PvP combat
    pvp_combat = await db.get_pvp_combat_by_player(current_user['id'])
    if not pvp_combat:
        raise HTTPException(status_code=400, detail="Not in PvP combat")
    
    # Determine roles
    is_attacker = pvp_combat['attacker_character_id'] == current_user['id']
    your_turn = (is_attacker and pvp_combat['turn'] == 'attacker') or \
                (not is_attacker and pvp_combat['turn'] == 'defender')
    
    if not your_turn:
        raise HTTPException(status_code=400, detail="It's not your turn")
    
    # Get both players
    attacker = await db.get_player_by_id(pvp_combat['attacker_character_id'])
    defender = await db.get_player_by_id(pvp_combat['defender_character_id'])
    current_player = attacker if is_attacker else defender
    opponent = defender if is_attacker else attacker
    
    result_message = ""
    combat_over = False
    winner_id = None
    
    if req.action == 'attack':
        # Calculate damage (similar to PvE)
        base_damage = 5
        strength_bonus = current_player['strength'] * 2
        level_bonus = current_player['level']
        
        # Check for equipped weapon
        weapon_damage = 0
        equipment = await db.get_all_equipment(current_player['id'])
        if equipment.get('weapon') and equipment['weapon']:
            weapon_slot = equipment['weapon']
            inv_item = await db.get_inventory_item_by_id(weapon_slot['item_id'])
            if inv_item:
                weapon_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
                if weapon_def and weapon_def.stats:
                    weapon_damage = random.randint(
                        weapon_def.stats.get('damage_min', 0),
                        weapon_def.stats.get('damage_max', 0)
                    )
                    # Decrease weapon durability
                    if inv_item.get('unique_item_id'):
                        new_durability = await db.decrease_unique_item_durability(inv_item['unique_item_id'], 1)
                        if new_durability is None:
                            result_message += "⚠️ Your weapon broke! "
                            await db.unequip_item(current_player['id'], 'weapon')
        
        variance = random.randint(-2, 2)
        damage = max(1, base_damage + strength_bonus + level_bonus + weapon_damage + variance)
        
        # Apply armor reduction and durability loss to opponent
        armor_absorbed, broken_armor = await reduce_armor_durability(opponent['id'], damage)
        actual_damage = max(1, damage - armor_absorbed)
        
        # Update opponent HP (use actual player HP, not pvp_combat fields)
        new_opponent_hp = max(0, opponent['hp'] - actual_damage)
        
        # Update opponent's HP in database
        await db.update_player(opponent['id'], hp=new_opponent_hp)
        
        # Store message with attacker's username so both players can see it correctly
        stored_message = f"{current_player['name']} attacks {opponent['name']} for {damage} damage!"
        if armor_absorbed > 0:
            stored_message += f" (Armor absorbed {armor_absorbed})"
        
        for broken in broken_armor:
            stored_message += f"\n💔 {opponent['name']}'s {broken['emoji']} {broken['name']} broke!"
        
        # Check if opponent defeated
        if new_opponent_hp <= 0:
            stored_message += f"\n🏆 {current_player['name']} has defeated {opponent['name']}!"
            result_message = "Combat victory!"  # Simple message, details in stored_message
            combat_over = True
            winner_id = current_player['id']
            
            # Update opponent to dead state
            await db.update_player(opponent['id'], hp=0, is_dead=True)
            
            # Create corpse with opponent's inventory
            import json
            import time as time_module
            inventory = await db.get_inventory(opponent['id'])
            inventory_items = []
            for inv_item in inventory:
                item_def = ITEMS_MANAGER.get_item(inv_item['item_id'])
                inventory_items.append({
                    'item_id': inv_item['item_id'],
                    'name': item_def.name if item_def else inv_item['item_id'],
                    'emoji': item_def.emoji if (item_def and hasattr(item_def, 'emoji')) else '📦',
                    'quantity': inv_item['quantity'],
                    'durability': inv_item.get('durability'),
                    'max_durability': inv_item.get('max_durability'),
                    'tier': inv_item.get('tier')
                })
            
            logger.info(f"Creating player corpse (PvP death) for {opponent['name']} at {opponent['location_id']} with {len(inventory_items)} items")
            
            corpse_id = await db.create_player_corpse(
                player_name=opponent['name'],
                location_id=opponent['location_id'],
                items=json.dumps([{'item_id': i['item_id'], 'quantity': i['quantity']} for i in inventory])
            )
            
            logger.info(f"Successfully created player corpse (PvP death): ID={corpse_id}, player={opponent['name']}, location={opponent['location_id']}, items_count={len(inventory_items)}")
            
            # Clear opponent's inventory (items are now in corpse)
            await db.clear_inventory(opponent['id'])
            
            # Build corpse data for broadcast
            corpse_data = {
                "id": f"player_{corpse_id}",
                "type": "player",
                "name": f"{opponent['name']}'s Corpse",
                "emoji": "⚰️",
                "player_name": opponent['name'],
                "loot_count": len(inventory_items),
                "items": inventory_items,
                "timestamp": time_module.time()
            }
            
            # Update PvP statistics for both players
            await db.update_player_statistics(opponent['id'], 
                pvp_deaths=1, 
                pvp_combats_lost=1, 
                pvp_damage_taken=actual_damage,
                pvp_attacks_received=1,
                increment=True
            )
            await db.update_player_statistics(current_player['id'], 
                players_killed=1, 
                pvp_combats_won=1, 
                pvp_damage_dealt=damage,
                pvp_attacks_landed=1,
                increment=True
            )
            
            # Broadcast to location that player died and corpse appeared
            logger.info(f"Broadcasting player_died (PvP death) to location {opponent['location_id']} for player {opponent['name']}")
            await manager.send_to_location(
                location_id=opponent['location_id'],
                message={
                    "type": "location_update",
                    "data": {
                        "message": f"{opponent['name']} was defeated by {current_player['name']} in PvP combat",
                        "action": "player_died",
                        "player_id": opponent['id'],
                        "corpse": corpse_data
                    },
                    "timestamp": datetime.utcnow().isoformat()
                }
            )
            
            # End PvP combat
            await db.end_pvp_combat(pvp_combat['id'])
        else:
            # Combat continues - don't return detailed message, it's in stored_message
            result_message = ""  # Empty message, frontend will show stored_message from polling
            
            # Update PvP statistics for attack
            await db.update_player_statistics(current_player['id'], 
                pvp_damage_dealt=damage,
                pvp_attacks_landed=1,
                increment=True
            )
            await db.update_player_statistics(opponent['id'], 
                pvp_damage_taken=actual_damage,
                pvp_attacks_received=1,
                increment=True
            )
            
            # Update combat state and switch turns
            # Add timestamp to make each action unique for duplicate detection
            updates = {
                'turn': 'defender' if is_attacker else 'attacker',
                'turn_started_at': time.time(),
                'last_action': f"{stored_message}|{time.time()}"  # Add timestamp for uniqueness
            }
            # No need to update HP in pvp_combat - we use player HP directly
            
            await db.update_pvp_combat(pvp_combat['id'], updates)
            await db.update_player_statistics(current_player['id'], damage_dealt=damage, increment=True)
    
    elif req.action == 'flee':
        # 50% chance to flee from PvP
        if random.random() < 0.5:
            result_message = f"You successfully fled from {opponent['name']}!"
            combat_over = True
            
            # Mark as fled, store last action with timestamp, and end combat
            flee_field = 'attacker_fled' if is_attacker else 'defender_fled'
            await db.update_pvp_combat(pvp_combat['id'], {
                flee_field: True,
                'last_action': f"{current_player['name']} fled from combat!|{time.time()}"
            })
            await db.end_pvp_combat(pvp_combat['id'])
            await db.update_player_statistics(current_player['id'], 
                pvp_successful_flees=1, 
                increment=True
            )
        else:
            # Failed to flee, skip turn
            result_message = f"Failed to flee from {opponent['name']}!"
            await db.update_pvp_combat(pvp_combat['id'], {
                'turn': 'defender' if is_attacker else 'attacker',
                'turn_started_at': time.time(),
                'last_action': f"{current_player['name']} tried to flee but failed!|{time.time()}"
            })
            await db.update_player_statistics(current_player['id'], 
                pvp_failed_flees=1, 
                increment=True
            )
    
    # Send WebSocket combat updates to both players
    # Get fresh PvP combat data
    updated_pvp = await db.get_pvp_combat_by_id(pvp_combat['id'])
    
    # Get fresh player data for HP updates
    fresh_attacker = await db.get_player_by_id(pvp_combat['attacker_character_id'])
    fresh_defender = await db.get_player_by_id(pvp_combat['defender_character_id'])
    
    # Send to both players with enriched data (like the API endpoint does)
    for player_id in [pvp_combat['attacker_character_id'], pvp_combat['defender_character_id']]:
        is_attacker = player_id == pvp_combat['attacker_character_id']
        your_turn = (is_attacker and updated_pvp['turn'] == 'attacker') or \
                    (not is_attacker and updated_pvp['turn'] == 'defender')
        
        # Calculate time remaining
        import time
        time_elapsed = time.time() - updated_pvp['turn_started_at']
        time_remaining = max(0, updated_pvp['turn_timeout_seconds'] - time_elapsed)
        
        # Build enriched pvp_combat object like the API does
        enriched_pvp = {
            "id": updated_pvp['id'],
            "attacker": {
                "id": fresh_attacker['id'],
                "username": fresh_attacker['name'],
                "level": fresh_attacker['level'],
                "hp": fresh_attacker['hp'],
                "max_hp": fresh_attacker['max_hp']
            },
            "defender": {
                "id": fresh_defender['id'],
                "username": fresh_defender['name'],
                "level": fresh_defender['level'],
                "hp": fresh_defender['hp'],
                "max_hp": fresh_defender['max_hp']
            },
            "is_attacker": is_attacker,
            "your_turn": your_turn,
            "current_turn": updated_pvp['turn'],
            "time_remaining": int(time_remaining),
            "location_id": updated_pvp['location_id'],
            "last_action": updated_pvp.get('last_action'),
            "combat_over": updated_pvp.get('attacker_fled', False) or updated_pvp.get('defender_fled', False) or \
                          fresh_attacker['hp'] <= 0 or fresh_defender['hp'] <= 0,
            "attacker_fled": updated_pvp.get('attacker_fled', False),
            "defender_fled": updated_pvp.get('defender_fled', False)
        }
        
        await manager.send_personal_message(player_id, {
            "type": "combat_update",
            "data": {
                "message": result_message if player_id == current_user['id'] else "",
                "log_entry": result_message if player_id == current_user['id'] else "",  # Append to combat log
                "pvp_combat": enriched_pvp,
                "combat_over": combat_over,
                "winner_id": winner_id,
                "attacker_hp": fresh_attacker['hp'],
                "defender_hp": fresh_defender['hp']
            },
            "timestamp": datetime.utcnow().isoformat()
        })
    
    return {
        "success": True,
        "message": result_message,
        "combat_over": combat_over,
        "winner_id": winner_id
    }