"""
Internal API endpoints for Telegram Bot
These endpoints are protected by an internal key and handle game logic
"""

from fastapi import APIRouter, Header, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional, Dict, Any, List
import os

# Internal API key for bot authentication
INTERNAL_API_KEY = os.getenv("API_INTERNAL_KEY", "internal-bot-access-key-change-me")

router = APIRouter(prefix="/api/internal", tags=["internal"])


def verify_internal_key(x_internal_key: str = Header(...)):
    """Verify internal API key"""
    if x_internal_key != INTERNAL_API_KEY:
        raise HTTPException(status_code=403, detail="Invalid internal API key")
    return True


# ==================== Pydantic Models ====================

class PlayerCreate(BaseModel):
    telegram_id: int
    name: str = "Survivor"

class PlayerUpdate(BaseModel):
    name: Optional[str] = None
    hp: Optional[int] = None
    stamina: Optional[int] = None
    location_id: Optional[str] = None
    level: Optional[int] = None
    xp: Optional[int] = None
    strength: Optional[int] = None
    agility: Optional[int] = None
    endurance: Optional[int] = None
    intellect: Optional[int] = None

class MoveRequest(BaseModel):
    direction: str

class CombatStart(BaseModel):
    telegram_id: int
    npc_id: str

class CombatAction(BaseModel):
    action: str  # "attack", "defend", "flee"

class UseItem(BaseModel):
    item_db_id: int

class EquipItem(BaseModel):
    item_db_id: int


# ==================== Player Endpoints ====================

@router.get("/player/telegram/{telegram_id}")
async def get_player_by_telegram(
    telegram_id: int,
    _: bool = Depends(verify_internal_key)
):
    """Get player by Telegram ID"""
    from bot.database import get_player
    player = await get_player(telegram_id=telegram_id)
    if not player:
        raise HTTPException(status_code=404, detail="Player not found")
    return player


@router.post("/player")
async def create_player_internal(
    player_data: PlayerCreate,
    _: bool = Depends(verify_internal_key)
):
    """Create a new player (Telegram bot)"""
    from bot.database import create_player
    player = await create_player(telegram_id=player_data.telegram_id, name=player_data.name)
    if not player:
        raise HTTPException(status_code=500, detail="Failed to create player")
    return player


@router.patch("/player/telegram/{telegram_id}")
async def update_player_internal(
    telegram_id: int,
    updates: PlayerUpdate,
    _: bool = Depends(verify_internal_key)
):
    """Update player data"""
    from bot.database import update_player
    
    # Convert to dict and remove None values
    update_dict = {k: v for k, v in updates.dict().items() if v is not None}
    
    if not update_dict:
        return {"success": True, "message": "No updates provided"}
    
    await update_player(telegram_id=telegram_id, updates=update_dict)
    return {"success": True, "message": "Player updated"}


# ==================== Location Endpoints ====================

@router.get("/location/{location_id}")
async def get_location_internal(
    location_id: str,
    _: bool = Depends(verify_internal_key)
):
    """Get location details"""
    from api.main import LOCATIONS
    
    location = LOCATIONS.get(location_id)
    if not location:
        raise HTTPException(status_code=404, detail="Location not found")
    
    return {
        "id": location.id,
        "name": location.name,
        "description": location.description,
        "exits": location.exits,
        "interactables": {k: {
            "id": v.id,
            "name": v.name,
            "actions": list(v.actions.keys())
        } for k, v in location.interactables.items()},
        "image_path": location.image_path
    }


@router.post("/player/telegram/{telegram_id}/move")
async def move_player_internal(
    telegram_id: int,
    move_data: MoveRequest,
    _: bool = Depends(verify_internal_key)
):
    """Move player in a direction"""
    from bot.database import get_player, update_player
    from api.main import LOCATIONS
    
    player = await get_player(telegram_id=telegram_id)
    if not player:
        raise HTTPException(status_code=404, detail="Player not found")
    
    current_location = LOCATIONS.get(player['location_id'])
    if not current_location:
        raise HTTPException(status_code=400, detail="Invalid current location")
    
    # Check stamina
    if player['stamina'] < 1:
        raise HTTPException(status_code=400, detail="Not enough stamina to move")
    
    # Find exit
    destination_id = current_location.exits.get(move_data.direction.lower())
    if not destination_id:
        raise HTTPException(status_code=400, detail=f"Cannot move {move_data.direction} from here")
    
    new_location = LOCATIONS.get(destination_id)
    if not new_location:
        raise HTTPException(status_code=400, detail="Invalid destination")
    
    # Update player
    await update_player(telegram_id=telegram_id, updates={
        'location_id': new_location.id,
        'stamina': max(0, player['stamina'] - 1)
    })
    
    return {
        "success": True,
        "location": {
            "id": new_location.id,
            "name": new_location.name,
            "description": new_location.description,
            "exits": new_location.exits
        },
        "stamina": max(0, player['stamina'] - 1)
    }


# ==================== Inventory Endpoints ====================

@router.get("/player/telegram/{telegram_id}/inventory")
async def get_inventory_internal(
    telegram_id: int,
    _: bool = Depends(verify_internal_key)
):
    """Get player's inventory"""
    from bot.database import get_inventory
    
    inventory = await get_inventory(telegram_id)
    return {"items": inventory}


@router.post("/player/telegram/{telegram_id}/use_item")
async def use_item_internal(
    telegram_id: int,
    item_data: UseItem,
    _: bool = Depends(verify_internal_key)
):
    """Use an item from inventory"""
    from bot.logic import use_item_logic
    from bot.database import get_player
    
    player = await get_player(telegram_id=telegram_id)
    if not player:
        raise HTTPException(status_code=404, detail="Player not found")
    
    result = await use_item_logic(player, item_data.item_db_id)
    return result


@router.post("/player/telegram/{telegram_id}/equip")
async def equip_item_internal(
    telegram_id: int,
    item_data: EquipItem,
    _: bool = Depends(verify_internal_key)
):
    """Equip/unequip an item"""
    from bot.logic import toggle_equip
    
    result = await toggle_equip(telegram_id, item_data.item_db_id)
    return {"success": True, "message": result}


# ==================== Combat Endpoints ====================

@router.post("/combat/start")
async def start_combat_internal(
    combat_data: CombatStart,
    _: bool = Depends(verify_internal_key)
):
    """Start combat with an NPC"""
    from bot.combat import start_combat
    from bot.database import get_player
    
    player = await get_player(telegram_id=combat_data.telegram_id)
    if not player:
        raise HTTPException(status_code=404, detail="Player not found")
    
    result = await start_combat(combat_data.telegram_id, combat_data.npc_id, player['location_id'])
    if not result.get("success"):
        raise HTTPException(status_code=400, detail=result.get("message", "Failed to start combat"))
    
    return result


@router.get("/combat/telegram/{telegram_id}")
async def get_combat_internal(
    telegram_id: int,
    _: bool = Depends(verify_internal_key)
):
    """Get active combat state"""
    from bot.combat import get_active_combat
    
    combat = await get_active_combat(telegram_id)
    if not combat:
        raise HTTPException(status_code=404, detail="No active combat")
    
    return combat


@router.post("/combat/telegram/{telegram_id}/action")
async def combat_action_internal(
    telegram_id: int,
    action_data: CombatAction,
    _: bool = Depends(verify_internal_key)
):
    """Perform combat action"""
    from bot.combat import player_attack, player_defend, player_flee
    
    if action_data.action == "attack":
        result = await player_attack(telegram_id)
    elif action_data.action == "defend":
        result = await player_defend(telegram_id)
    elif action_data.action == "flee":
        result = await player_flee(telegram_id)
    else:
        raise HTTPException(status_code=400, detail="Invalid combat action")
    
    return result
