from __future__ import annotations

from abc import ABC, abstractmethod
from analogai.foundation.modules.user.user import User
from analogai.foundation.modules.agent.agent import Agent
from analogai.foundation.common.logging.app_logger import app_logger


class AuthorityPolicy(ABC):
    @abstractmethod
    def resolve_api(self, auth_type: str) -> float:
        raise NotImplementedError

    @abstractmethod
    def resolve_role(self, user: User, agent: Agent) -> float:
        raise NotImplementedError


class DefaultAuthorityPolicy(AuthorityPolicy):
    def __init__(self, api_default: float = 0.4, guest_default: float = 0.3):
        self._api_default = api_default
        self._guest_default = guest_default

    def resolve_api(self, auth_type: str) -> float:
        if auth_type == "guest":
            return self._guest_default
        return self._api_default

    def resolve_role(self, user: User, agent: Agent) -> float:
        app_logger.debug("Extracting authority for user_id=%s, agent_id=%s", user.id, agent.id)

        if agent.roles is None:
            app_logger.debug("agent.roles is None for agent_id=%s", agent.id)
            return 0.0

        if not agent.roles:
            app_logger.debug("agent.roles is empty for agent_id=%s", agent.id)
            return 0.0

        app_logger.debug("agent.roles has %s role(s) for agent_id=%s", len(agent.roles), agent.id)

        for idx, role in enumerate(agent.roles):
            if role.user is None:
                app_logger.debug("role[%s].user is None for agent_id=%s", idx, agent.id)
                continue

            role_user_id = role.user.id
            app_logger.debug("role[%s]: comparing role.user.id=%s with user.id=%s", idx, role_user_id, user.id)

            if role_user_id == user.id:
                authority = role.authority if role.authority is not None else 0.0
                app_logger.debug("Found matching role for user_id=%s, authority=%s", user.id, authority)
                return authority

        app_logger.debug("No matching role found for user_id=%s in agent_id=%s, returning 0.0", user.id, agent.id)
        return 0.0
