import logging

from crud.auth import crud
from fastapi import HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession

logger = logging.getLogger(__name__)

class AuthService:
    @staticmethod
    async def login(
        db: AsyncSession,
        email: str,
        senha: str,
    ) -> dict:
        """
        Realiza login do usuário e retorna o token do cliente associado.
        
        Args:
            db: Sessão do banco de dados
            email: Email do usuário
            senha: Senha do usuário
            
        Returns:
            dict com access_token e token_type
            
        Raises:
            HTTPException: Se credenciais inválidas ou cliente não encontrado
        """
        logger.info(f"Iniciando login para email: {email}")
        
        try:
            user_dict = await crud.get_user_by_email(db, email)
            
            if not user_dict:
                logger.warning(f"Usuário não encontrado para email: {email}")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Acesso negado"
                )
            
            senha_hash = user_dict.get("Senha")
            
            if not senha_hash or senha != senha_hash:
                logger.warning(f"Senha inválida para email: {email}")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Acesso negado"
                )
            
            id_cliente = user_dict.get("IdCliente")
            
            if not id_cliente:
                logger.warning(f"Usuário não possui cliente associado")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Usuário não possui cliente associado"
                )
            
            cliente_dict = await crud.get_cliente_by_id(db, id_cliente)
            
            if not cliente_dict:
                logger.warning(f"Cliente não encontrado para ID: {id_cliente}")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Cliente não encontrado"
                )
            
            token_cliente = cliente_dict.get("Token")
            
            if not token_cliente:
                logger.warning(f"Cliente {id_cliente} não possui token")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Cliente não possui token"
                )
            
            logger.info(f"Login realizado com sucesso para email: {email}")
            return {
                "access_token": token_cliente,
                "token_type": "bearer"
            }
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"Erro ao realizar login: {e}", exc_info=True)
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Erro interno ao processar login"
            )

    @staticmethod
    async def get_current_cliente(
        db: AsyncSession,
        token: str,
    ) -> dict:
        """
        Busca cliente pelo token fornecido.
        
        Args:
            db: Sessão do banco de dados
            token: Token do cliente
            
        Returns:
            Dicionário com dados do cliente encontrado
            
        Raises:
            HTTPException: Se token inválido ou cliente não encontrado
        """
        logger.debug("Buscando cliente por token")
        
        try:
            cliente_dict = await crud.get_cliente_by_token(db, token)
            
            if not cliente_dict:
                logger.warning("Token inválido ou não encontrado")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Token inválido ou não encontrado"
                )
            
            return cliente_dict
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"Erro ao buscar cliente por token: {e}", exc_info=True)
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Erro interno ao validar token"
            )

