from analogai.foundation.modules.user.user import User
from analogai.foundation.modules.agent.agent import Agent
from analogai.foundation.modules.agent.agent_service import AgentService
from analogai.foundation.extensions.authorization.core.enums.operation import AuthorizationOperation
from analogai.foundation.common.logging.app_logger import app_logger

class AuthorizationService:
    def __init__(self, agent_service: AgentService):
        self.agent_service = agent_service

    def authorize_user_for_agent(
        self,
        user: User,
        agent: Agent,
        operation: AuthorizationOperation = AuthorizationOperation.CHAT,
    ) -> bool:
        if not user:
            app_logger.error("Authorization failed: No user provided")
            return False
        if not agent:
            app_logger.error("Authorization failed: No agent provided")
            return False
        user_has_access = self._check_user_access_to_agent(user, agent, operation)
        if user_has_access:
            app_logger.info(f"Authorized user {user.id} for agent {agent.id}")
            return True
        app_logger.error(
            f"Authorization failed: User {user.id} does not have access to agent {agent.id}"
        )
        return False

    def find_and_authorize_agent(
        self,
        user: User,
        agent_id: str,
        operation: AuthorizationOperation = AuthorizationOperation.CHAT,
    ) -> Agent:
        if not user:
            app_logger.error("Authorization failed: No user provided")
            raise ValueError("User not authenticated")
        agent = self.agent_service.find(agent_id)
        if not agent:
            app_logger.error(
                f"Authorization failed: Agent with id {agent_id} not found"
            )
            raise ValueError(f"Agent with id {agent_id} not found")
        if not self.authorize_user_for_agent(user, agent, operation):
            raise ValueError(
                f"User {user.id} does not have access to agent {agent_id}"
            )
        return agent

    def _check_user_access_to_agent(
        self,
        user: User,
        agent: Agent,
        operation: AuthorizationOperation,
    ) -> bool:
        if operation == AuthorizationOperation.CHAT:
            return True
        if not agent.roles:
            return False
        for role in agent.roles:
            if role.user and role.user.id == user.id:
                return True
        return False
