"""AAL client — main entry point for the SDK."""

from __future__ import annotations

import uuid
from typing import Any, cast
from urllib.parse import urlencode

from .buffer import EventBuffer
from .http import HttpClient
from .session import AALSession
from .types import (
    AALClientConfig,
    EventsQueryParams,
    PaginatedEvents,
    SessionResponse,
    StartSessionConfig,
)


class AALClient:
    """Client for the Agent Action Ledger API."""

    def __init__(self, config: AALClientConfig) -> None:
        self._http = HttpClient(config["api_url"], config["api_key"])
        self._buffer = EventBuffer(
            flush_fn=self._send_batch,
            flush_interval=config.get("flush_interval", 1.0),
            batch_size=config.get("batch_size", 100),
        )
        self._buffer.start()

    def start_session(self, config: StartSessionConfig) -> AALSession:
        """Create a new session and return a session handle."""
        session_id = config.get("session_id") or str(uuid.uuid4())
        return AALSession(session_id, config["agent_id"], self._buffer.push)

    def session(self, session_id: str, agent_id: str = "unknown") -> AALSession:
        """Get a session handle for an existing session (no API call)."""
        return AALSession(session_id, agent_id, self._buffer.push)

    async def get_events(self, params: EventsQueryParams | None = None) -> PaginatedEvents:
        """Query events with optional filters."""
        query_parts: dict[str, str] = {}
        if params:
            for key, value in params.items():
                if value is not None:
                    query_parts[key] = str(value)
        qs = urlencode(query_parts) if query_parts else ""
        path = f"/v1/events?{qs}" if qs else "/v1/events"
        result: Any = await self._http.get(path)
        return cast(PaginatedEvents, result)

    async def get_session(self, session_id: str) -> SessionResponse:
        """Get session details including events."""
        result: Any = await self._http.get(f"/v1/sessions/{session_id}")
        return cast(SessionResponse, result)

    async def shutdown(self) -> None:
        """Drain the buffer and close the HTTP client."""
        await self._buffer.drain()
        await self._http.close()

    async def _send_batch(self, events: list[Any]) -> None:
        """Send a batch of events to the API."""
        await self._http.post("/v1/events/batch", {"events": events})
