"""Authentication API Endpoints & Token Validation."""
from __future__ import annotations

from typing import Any, Optional

from fastapi import APIRouter, Depends, Header, HTTPException, status
from pydantic import BaseModel

from backend.app.auth.security import (
    create_access_token,
    decode_access_token,
    verify_password,
)
from backend.app.config.settings import settings
from backend.app.database.session import db_manager

router = APIRouter(prefix="/auth", tags=["Authentication"])


class LoginRequestModel(BaseModel):
    username: str
    password: str


class TokenResponseModel(BaseModel):
    access_token: str
    token_type: str = "bearer"
    role: str


@router.post("/login", response_model=TokenResponseModel)
async def login(credentials: LoginRequestModel) -> TokenResponseModel:
    user = db_manager.execute_read_one(
        "SELECT * FROM users WHERE username = ?", (credentials.username,)
    )
    if not user or not verify_password(credentials.password, user["password_hash"]):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
        )

    token = create_access_token({"sub": user["username"], "role": user["role"]})
    return TokenResponseModel(access_token=token, role=user["role"])


def get_current_user(authorization: Optional[str] = Header(None)) -> dict[str, Any]:
    """Dependency: Extract and validate JWT bearer token."""
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Missing or malformed Authorization header",
        )
    token = authorization.split(" ")[1]
    payload = decode_access_token(token)
    if not payload:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired authentication token",
        )
    return payload


@router.get("/me")
async def get_current_user_profile(user: dict[str, Any] = Depends(get_current_user)) -> dict[str, Any]:
    return {"username": user.get("sub"), "role": user.get("role")}
