from dataclasses import dataclass
from uuid import UUID

import logging
from fastapi import Depends, HTTPException, status
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession

from app.auth.keycloak_dependencies import get_current_keycloak_sub
from app.core.config import settings
from app.infra.db.metadb.database import get_metadata_session
from app.infra.repositories.metadata_repository import MetadataRepository

logger = logging.getLogger(__name__)


async def get_metadata_repository(
    session: AsyncSession = Depends(get_metadata_session),
) -> MetadataRepository:
    return MetadataRepository(session)


async def get_current_metadata_user(
    keycloak_sub: UUID = Depends(get_current_keycloak_sub),
    metadata_repo: MetadataRepository = Depends(get_metadata_repository),
):
    try:
        user = await metadata_repo.get_user_by_keycloak_id(keycloak_sub)
    except SQLAlchemyError as exc:
        logger.error(
            "Metadata DB error while resolving current user",
            exc_info=True,
        )
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail=f"Metadata database error: {exc}",
        ) from exc
    if not user or not user.is_active:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="Inactive user"
        )
    return user


async def get_current_metadata_admin(
    user=Depends(get_current_metadata_user),
):
    if user.is_superuser or user.role == "admin":
        return user
    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required"
    )


@dataclass(frozen=True)
class _AuthBypassUser:
    id: UUID = UUID(int=0)
    role: str = "admin"
    is_superuser: bool = True
    is_active: bool = True
