from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.config import settings
from src.core.security import verify_token
from src.db.session import get_db
from src.db.models.app_user import AppUser
from src.db.models.role import UserRoleEnum
from src.repository.user_repository import UserRepository

security = HTTPBearer()


# if settings.DEBUG:

async def get_user_by_token(
        token: str,
        db: AsyncSession,
) -> AppUser:
    payload = verify_token(token)
    if payload is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Недействительный токен",
            headers={"WWW-Authenticate": "Bearer"},
        )

    username: str | None = payload.get("sub")
    if username is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Недействительный токен",
            headers={"WWW-Authenticate": "Bearer"},
        )

    user_repo = UserRepository(db)
    user = await user_repo.get_by_username(username)
    if user is None or not user.is_active:
        user = await user_repo.get_by_email(username)
    if user is None or not user.is_active:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Пользователь не найден",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user

async def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    db: AsyncSession = Depends(get_db),
) -> AppUser:
    return await get_user_by_token(token=credentials.credentials, db=db)

# else:
#     from raisa_fastapi_protected_api import UserInfo, get_user_dependency

#     async def get_current_user(
#         user: UserInfo = Depends(get_user_dependency),
#         db: AsyncSession = Depends(get_db),
#     ) -> AppUser:
#         user_repo = UserRepository(db)
#         db_user = await user_repo.get_by_email(user.email)
#         if db_user is None:
#             raise HTTPException(
#                 status_code=status.HTTP_401_UNAUTHORIZED,
#                 detail="Пользователь не найден",
#                 headers={"WWW-Authenticate": "Bearer"},
#             )
#         return db_user


async def get_current_active_user(current_user: AppUser = Depends(get_current_user)) -> AppUser:
    return current_user


async def get_current_active_user_with_set_db(
        current_user: AppUser = Depends(get_current_user),
        db: AsyncSession = Depends(get_db),
) -> AppUser:
    
    user_repo = UserRepository(db)
    await user_repo.set_app_user_id(current_user.id)
    return current_user


def require_admin(
    current_user: AppUser = Depends(get_current_active_user_with_set_db),
) -> AppUser:
    if current_user.role_id != UserRoleEnum.ADMIN:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Недостаточно прав",
        )
    return current_user


def require_executor(
    current_user: AppUser = Depends(get_current_active_user_with_set_db),
) -> AppUser:
    if current_user.role_id not in [
        UserRoleEnum.ADMIN,
        UserRoleEnum.EXECUTOR_DFIP,
        UserRoleEnum.EXECUTOR_RF,
    ]:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Недостаточно прав",
        )
    return current_user


def require_executor_dfip(
    current_user: AppUser = Depends(get_current_active_user_with_set_db),
) -> AppUser:
    if current_user.role_id not in [UserRoleEnum.ADMIN, UserRoleEnum.EXECUTOR_DFIP]:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Недостаточно прав",
        )
    return current_user
