"""
Layer 1 Agent: Environment-based primitives wrapper for spicedb
Composes RawAgent and provides access to Layer 1 primitives (structured helpers).
Automatically loads credentials from environment variables for easy integration
with AI Agent frameworks (LangChain, CrewAI, Madison, etc.)
"""
import os
from typing import Any, Dict, List, Literal, Optional, Type, TypeVar, Union
from pydantic import BaseModel
from .raw_agent import RawAgent
from .primitives import SpicedbPrimitives

T = TypeVar('T', bound=BaseModel)

class PrimitivesAgent:
    """
    Agent-ready wrapper for spicedb primitives (Layer 1).

    Composes RawAgent and provides access to structured helper methods.

    Automatically loads credentials from environment variables:
    - SPICEDB_API_KEY: API key/token for authentication
    - SPICEDB_BASE_URL: Base URL for the API (optional, has default)

    Usage:
        agent = PrimitivesAgent()  # Uses env vars
        agent = PrimitivesAgent(api_key="...", base_url="...")  # Explicit

        # Access raw methods via .raw
        await agent.raw.get_markets(...)

        # Access primitive methods directly
        await agent.get_markets_structured(...)
    """

    def __init__(
        self,
        api_key: Optional[str] = None,
        base_url: Optional[str] = None
    ):
        # Load from environment variables with fallbacks
        self.api_key = api_key or os.environ.get("SPICEDB_API_KEY")
        self.base_url = base_url or os.environ.get("SPICEDB_BASE_URL", "https://api.example.com")

        if not self.api_key:
            raise ValueError(
                "API key is required. Set SPICEDB_API_KEY environment variable "
                "or pass api_key parameter."
            )

        # Initialize RawAgent (Layer 0)
        self.raw = RawAgent(api_key=self.api_key, base_url=self.base_url)

        # Initialize Primitives (Layer 1)
        # Primitives need the raw client instances
        self._primitives = SpicedbPrimitives(
            permissions_client=self.raw._permissions
        )

    # ─────────────────────────────────────────────────────────────────────────────
    # Primitive operations (Layer 1)
    # ─────────────────────────────────────────────────────────────────────────────

    async def permissions_service_check_permission_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_check_permission_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_check_permission_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_check_bulk_permissions_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_check_bulk_permissions_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_check_bulk_permissions_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_expand_permission_tree_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_expand_permission_tree_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_expand_permission_tree_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_lookup_resources_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_lookup_resources_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_lookup_resources_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_lookup_subjects_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_lookup_subjects_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_lookup_subjects_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_delete_relationships_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_delete_relationships_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_delete_relationships_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_read_relationships_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_read_relationships_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_read_relationships_structured(
            body=body,
            response_model=response_model
        )

    async def permissions_service_write_relationships_structured(
        self,
        body: Dict[str, Any],
        response_model: Optional[Type[T]] = None
    ) -> T | Dict[str, Any]:
        """
        permissions_service_write_relationships_structured
        Args:
            body: Request body
            response_model: Optional Pydantic model to parse the response into
        Returns:
            Parsed response as the specified Pydantic model, or raw Dict if no model provided
        """
        return await self._primitives.permissions_service_write_relationships_structured(
            body=body,
            response_model=response_model
        )
