"""HTTP client for Pier Cloud API."""

import os
import httpx
from typing import Any, Optional
from datetime import datetime, timedelta


class PierCloudClient:
    """Client for Pier Cloud API with JWT authentication."""

    def __init__(
        self, client_id: Optional[str] = None, client_secret: Optional[str] = None
    ):
        self.base_url = os.getenv("PIERCLOUD_API_URL", "https://api.piercloud.io/lake")
        self.client_id = client_id or os.getenv("PIERCLOUD_CLIENT_ID")
        self.client_secret = client_secret or os.getenv("PIERCLOUD_CLIENT_SECRET")

        self.client = httpx.AsyncClient(base_url=self.base_url, timeout=30.0)
        self.access_token: Optional[str] = None
        self.token_expires_at: Optional[datetime] = None

    async def _authenticate(self):
        """Authenticate and get JWT token."""
        if not self.client_id or not self.client_secret:
            raise ValueError(
                "PIERCLOUD_CLIENT_ID and PIERCLOUD_CLIENT_SECRET are required. "
                "Set them as environment variables."
            )

        response = await self.client.post(
            "https://api.piercloud.io/auth",
            json={"client_id": self.client_id, "client_secret": self.client_secret},
        )
        response.raise_for_status()

        data = response.json()["data"]
        self.access_token = data["access_token"]

        # Set expiration (with 60s buffer)
        expires_in = data["expires_in"] - 60
        self.token_expires_at = datetime.now() + timedelta(seconds=expires_in)

    async def _ensure_authenticated(self):
        """Ensure we have a valid token."""
        if not self.access_token or not self.token_expires_at:
            await self._authenticate()
        elif datetime.now() >= self.token_expires_at:
            await self._authenticate()

    async def get(self, path: str) -> Any:
        """GET request with authentication."""
        await self._ensure_authenticated()
        response = await self.client.get(
            path, headers={"Authorization": f"Bearer {self.access_token}"}
        )
        response.raise_for_status()
        return response.json()

    async def query(self, connector_id: str, sql: str) -> Any:
        """Execute a query on a connector."""
        return await self.post(f"/mcp/connectors/{connector_id}/query", {"query": sql})

    async def post(self, path: str, data: dict) -> Any:
        """POST request with authentication."""
        await self._ensure_authenticated()
        response = await self.client.post(
            path, json=data, headers={"Authorization": f"Bearer {self.access_token}"}
        )
        response.raise_for_status()
        return response.json()

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


# Singleton instance
_client = None


def get_client(
    client_id: Optional[str] = None, client_secret: Optional[str] = None
) -> PierCloudClient:
    """Get or create client instance."""
    # If credentials provided, create new instance (for per-request auth)
    if client_id and client_secret:
        return PierCloudClient(client_id, client_secret)

    # Otherwise use singleton (for env var auth)
    global _client
    if _client is None:
        _client = PierCloudClient()
    return _client
