"""
Character management router.
Handles character creation, selection, and deletion.
"""
from fastapi import APIRouter, HTTPException, Depends, status, Request
from fastapi.security import HTTPAuthorizationCredentials

from ..items import items_manager
from ..services.helpers import enrich_character_data, get_game_message

from ..core.security import decode_token, create_access_token, security
from ..services.models import CharacterCreate, CharacterSelect
from .. import database as db

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

@router.get("")
async def list_characters(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """List all characters for the logged-in account"""
    token = credentials.credentials
    payload = decode_token(token)
    account_id = payload.get("account_id")
    
    if not account_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token"
        )
    
    characters = await db.get_characters_by_account_id(account_id)
    
    return {
        "characters": [
            await enrich_character_data(char, items_manager)
            for char in characters
        ]
    }


@router.post("")
async def create_character_endpoint(
    character: CharacterCreate,
    request: Request,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Create a new character"""
    token = credentials.credentials
    locale = request.headers.get('Accept-Language', 'en')
    payload = decode_token(token)
    account_id = payload.get("account_id")
    
    if not account_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token"
        )
    
    # Check if account can create more characters
    can_create, error_msg = await db.can_create_character(account_id)
    if not can_create:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=error_msg
        )
    
    # Validate character name
    if len(character.name) < 3 or len(character.name) > 20:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Character name must be between 3 and 20 characters"
        )
    
    # Check if name is unique
    existing = await db.get_character_by_name(character.name)
    if existing:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Character name already taken"
        )
    
    # Validate stat allocation (must total 20 points)
    total_stats = character.strength + character.agility + character.endurance + character.intellect
    if total_stats != 20:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Must allocate exactly 20 stat points (you allocated {total_stats})"
        )
    
    # Validate each stat is >= 0
    if any(stat < 0 for stat in [character.strength, character.agility, character.endurance, character.intellect]):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Stats cannot be negative"
        )
    
    # Create character
    new_character = await db.create_character(
        account_id=account_id,
        name=character.name,
        strength=character.strength,
        agility=character.agility,
        endurance=character.endurance,
        intellect=character.intellect,
        avatar_data=character.avatar_data
    )
    
    if not new_character:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to create character"
        )
    
    return {
        "message": get_game_message('character_created', locale),
        "character": {
            "id": new_character["id"],
            "name": new_character["name"],
            "level": new_character["level"],
            "strength": new_character["strength"],
            "agility": new_character["agility"],
            "endurance": new_character["endurance"],
            "intellect": new_character["intellect"],
            "hp": new_character["hp"],
            "max_hp": new_character["max_hp"],
            "stamina": new_character["stamina"],
            "max_stamina": new_character["max_stamina"],
            "location_id": new_character["location_id"],
            "avatar_data": new_character.get("avatar_data"),
        }
    }


@router.post("/select")
async def select_character(
    selection: CharacterSelect,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Select a character to play"""
    token = credentials.credentials
    payload = decode_token(token)
    account_id = payload.get("account_id")
    
    if not account_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token"
        )
    
    # Verify character belongs to account
    character = await db.get_character_by_id(selection.character_id)
    if not character:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Character not found"
        )
    
    if character["account_id"] != account_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Character does not belong to this account"
        )
    
    # Update last played timestamp
    await db.update_character_last_played(selection.character_id)
    
    # Create new token with character_id
    access_token = create_access_token({
        "account_id": account_id,
        "character_id": selection.character_id
    })
    
    return {
        "access_token": access_token,
        "token_type": "bearer",
        "character": {
            "id": character["id"],
            "name": character["name"],
            "level": character["level"],
            "xp": character["xp"],
            "hp": character["hp"],
            "max_hp": character["max_hp"],
            "stamina": character["stamina"],
            "max_stamina": character["max_stamina"],
            "strength": character["strength"],
            "agility": character["agility"],
            "endurance": character["endurance"],
            "intellect": character["intellect"],
            "location_id": character["location_id"],
            "avatar_data": character.get("avatar_data"),
        }
    }


@router.delete("/{character_id}")
async def delete_character_endpoint(
    character_id: int,
    request: Request,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Delete a character"""
    token = credentials.credentials
    locale = request.headers.get('Accept-Language', 'en')
    payload = decode_token(token)
    account_id = payload.get("account_id")
    
    if not account_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token"
        )
    
    # Verify character belongs to account
    character = await db.get_character_by_id(character_id)
    if not character:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Character not found"
        )
    
    if character["account_id"] != account_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Character does not belong to this account"
        )
    
    # Delete character
    await db.delete_character(character_id)
    
    return {
        "message": get_game_message('character_deleted', locale, name=character['name'])
    }
