from typing import Annotated, Final

from fastapi import APIRouter, Depends, Form, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from starlette.status import HTTP_500_INTERNAL_SERVER_ERROR

from app.application.users.passwords import (
    PasswordPolicyError,
    PasswordServiceError,
    change_own_password,
    validate_new_password,
)
from app.auth import get_current_user
from app.models import UserInDB
from app.routes.shell_navigation import build_shell_context


router = APIRouter()
templates = Jinja2Templates(directory="web")
CurrentUser = Annotated[UserInDB, Depends(get_current_user)]
PerfilTemplate: Final[str] = "perfil.html"

@router.get("/perfil", response_class=HTMLResponse)
async def perfil(request: Request, user: CurrentUser):
    return templates.TemplateResponse(request, PerfilTemplate, {
        "request": request,
        "user": user,
        **build_shell_context(request=request, user=user),
    })

@router.post("/perfil/cambiar-password")
async def cambiar_password_usuario(
    request: Request,
    current_password: Annotated[str, Form(...)],
    new_password: Annotated[str, Form(...)],
    confirm_password: Annotated[str, Form(...)],
    user: CurrentUser,
):
    try:
        validate_new_password(new_password, confirm_password)
        await change_own_password(user.username, current_password, new_password)
    except PasswordPolicyError as exc:
        return templates.TemplateResponse(request, PerfilTemplate, {
            "request": request,
            "user": user,
            "error": exc.user_message,
            **build_shell_context(request=request, user=user),
        })
    except PasswordServiceError as exc:
        raise HTTPException(
            status_code=HTTP_500_INTERNAL_SERVER_ERROR,
            detail="No se pudo actualizar la contraseña en este momento.",
        ) from exc

    return templates.TemplateResponse(request, PerfilTemplate, {
        "request": request,
        "user": user,
        "success": "Contraseña actualizada correctamente.",
        **build_shell_context(request=request, user=user),
    })
