from typing import Annotated

from fastapi import Depends, Header, HTTPException, status
from sqlalchemy.orm import Session

from app.database import get_db
from app.models import User, UserRole
from app.schemas import RoleEnum
from app.security import decode_token


def _credentials_exception() -> HTTPException:
    return HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )


def get_token(authorization: Annotated[str | None, Header(alias="Authorization")] = None) -> str:
    """
    Accepts either:
    - Raw JWT: Authorization: eyJhbGciOiJ...
    - Standard Bearer: Authorization: Bearer eyJhbGciOiJ...
    """
    if not authorization or not (raw := authorization.strip()):
        raise _credentials_exception()
    if raw.lower().startswith("bearer "):
        return raw[7:].strip()
    return raw


def require_admin_token(
    db: Annotated[Session, Depends(get_db)],
    token: Annotated[str, Depends(get_token)],
) -> User:
    payload = decode_token(token)
    if payload is None or payload.role != RoleEnum.admin:
        raise _credentials_exception()
    user = db.get(User, payload.sub)
    if user is None or not user.is_active or user.role != UserRole.admin:
        raise _credentials_exception()
    return user


def require_user_token(
    db: Annotated[Session, Depends(get_db)],
    token: Annotated[str, Depends(get_token)],
) -> User:
    payload = decode_token(token)
    if payload is None or payload.role != RoleEnum.user:
        raise _credentials_exception()
    user = db.get(User, payload.sub)
    if user is None or not user.is_active or user.role != UserRole.user:
        raise _credentials_exception()
    from app.services.member_inactive_followup_service import touch_user_last_active

    touch_user_last_active(db, user, commit=True)
    return user
