from __future__ import annotations

from datetime import UTC, datetime

from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.orm import Session

from app.core.database import get_db
from app.core.security import decode_access_token
from app.models.admin import Admin
from app.models.user import User
from app.services.auth_service import AuthService

bearer_scheme = HTTPBearer(auto_error=True)


def get_current_token_payload(credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme)) -> dict:
    payload = decode_access_token(credentials.credentials)
    if AuthService.is_token_revoked(payload):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="登录已退出")
    return payload


def get_current_user(
    payload: dict = Depends(get_current_token_payload),
    db: Session = Depends(get_db),
) -> User:
    if payload.get("type") != "user":
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="当前凭证不是用户登录态")

    user_id = payload.get("sub")
    user = db.get(User, int(user_id)) if user_id else None
    if user is None or user.is_deleted:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在")
    if user.status != 1:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="账号已禁用")
    now = datetime.now(UTC).replace(tzinfo=None)
    if user.effective_at and user.effective_at > now:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="账号尚未生效")
    if user.expired_at and user.expired_at < now:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="账号已过期")
    return user


def get_current_admin(
    payload: dict = Depends(get_current_token_payload),
    db: Session = Depends(get_db),
) -> Admin:
    if payload.get("type") != "admin":
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="当前凭证不是管理员登录态")

    admin_id = payload.get("sub")
    admin = db.get(Admin, int(admin_id)) if admin_id else None
    if admin is None:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="管理员不存在")
    if admin.status != 1:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="管理员已禁用")
    return admin
