from __future__ import annotations

from abc import ABC, abstractmethod
import uuid
from analogai.foundation.modules.user.user import User
from analogai.foundation.modules.user.user_service import UserService
from analogai.foundation.extensions.authentication.api_token.api_token_payload import ApiTokenPayload


class ApiAuthTypeHandler(ABC):
    auth_type: str

    @abstractmethod
    def authenticate(
        self,
        auth_payload: dict,
        api_payload: ApiTokenPayload,
        user_service: UserService,
    ) -> User:
        raise NotImplementedError

    @staticmethod
    def _get_or_create_user(
        user_service: UserService,
        email: str,
        name: str,
    ) -> User:
        existing = user_service.find_by_email(email)
        if existing:
            return existing
        return user_service.create(str(uuid.uuid4()), name, str(email))

    @staticmethod
    def _resolve_email_name(
        prefix: str,
        agent_id: str,
        name_prefix: str,
    ) -> tuple[str, str]:
        email = f"{prefix}+{agent_id}@analogai.local"
        name = f"{name_prefix} Agent {agent_id}"
        return email, name


class UserApiAuthHandler(ApiAuthTypeHandler):
    auth_type = "user"

    def authenticate(
        self,
        auth_payload: dict,
        api_payload: ApiTokenPayload,
        user_service: UserService,
    ) -> User:
        user_email = auth_payload.get("user_email") or auth_payload.get("email")
        if not user_email:
            raise ValueError("User email required for auth_type=user")
        name = user_email.split("@", 1)[0] if user_email else "API User"
        return self._get_or_create_user(user_service, user_email, name)


class SystemApiAuthHandler(ApiAuthTypeHandler):
    auth_type = "system"

    def authenticate(
        self,
        auth_payload: dict,
        api_payload: ApiTokenPayload,
        user_service: UserService,
    ) -> User:
        email, name = self._resolve_email_name("system", api_payload.agent_id, "System")
        return self._get_or_create_user(user_service, email, name)


class GuestApiAuthHandler(ApiAuthTypeHandler):
    auth_type = "guest"

    def authenticate(
        self,
        auth_payload: dict,
        api_payload: ApiTokenPayload,
        user_service: UserService,
    ) -> User:
        email, name = self._resolve_email_name("guest", api_payload.agent_id, "Guest")
        return self._get_or_create_user(user_service, email, name)
