"""
Hydra Admin API client for OAuth 2.0 client management.
"""
import httpx
from typing import Dict, List, Optional
from datetime import datetime
import logging

logger = logging.getLogger(__name__)


class HydraClientError(Exception):
    """Base exception for Hydra client errors"""
    pass


class HydraClient:
    """
    Client for interacting with ORY Hydra Admin API.

    Handles OAuth 2.0 client registration, retrieval, updates,
    and deletion via Hydra's administrative endpoints.
    """

    def __init__(self, admin_url: str, timeout: int = 30):
        """
        Initialize Hydra client.

        Args:
            admin_url: Hydra admin API URL (e.g., http://hydra:4445)
            timeout: Request timeout in seconds
        """
        self.admin_url = admin_url.rstrip('/')
        self.timeout = timeout
        self.client = httpx.AsyncClient(
            timeout=timeout,
            follow_redirects=True
        )

    async def close(self):
        """Close HTTP client"""
        await self.client.aclose()

    async def __aenter__(self):
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.close()

    async def create_client(
        self,
        client_id: str,
        client_secret: Optional[str],
        client_name: str,
        redirect_uris: List[str],
        grant_types: List[str],
        response_types: List[str],
        scope: str,
        token_endpoint_auth_method: str = "client_secret_basic",
        metadata: Optional[Dict] = None
    ) -> Dict:
        """
        Create OAuth 2.0 client in Hydra.

        Args:
            client_id: Unique client identifier
            client_secret: Client secret (None for public clients)
            client_name: Human-readable client name
            redirect_uris: Allowed redirect URIs
            grant_types: Allowed grant types
            response_types: Allowed response types
            scope: Space-separated scopes
            token_endpoint_auth_method: Token endpoint auth method
            metadata: Additional client metadata

        Returns:
            Created client object

        Raises:
            HydraClientError: If creation fails
        """
        payload = {
            "client_id": client_id,
            "client_name": client_name,
            "redirect_uris": redirect_uris,
            "grant_types": grant_types,
            "response_types": response_types,
            "scope": scope,
            "token_endpoint_auth_method": token_endpoint_auth_method,
        }

        if client_secret:
            payload["client_secret"] = client_secret

        if metadata:
            payload["metadata"] = metadata

        try:
            response = await self.client.post(
                f"{self.admin_url}/clients",
