"""ARQERA API client."""

from __future__ import annotations

from typing import Any

import httpx

from arqera.models import (
    AraAction,
    EvidenceArtifact,
    GovernanceResult,
)


class _GovernanceAPI:
    """Governance evaluation endpoints."""

    def __init__(self, client: ArqeraClient):
        self._client = client

    def evaluate(
        self,
        action: str,
        *,
        description: str | None = None,
        context: dict[str, Any] | None = None,
    ) -> GovernanceResult:
        """Evaluate an action against the 7 governance laws.

        Args:
            action: Action identifier (e.g., "email.send", "data.delete").
            description: Human-readable description of the action.
            context: Additional context for evaluation (risk_level, etc.).

        Returns:
            GovernanceResult with verdict (PROCEED/ESCALATE/BLOCK) and per-law details.
        """
        body: dict[str, Any] = {"action": action}
        if description is not None:
            body["description"] = description
        if context is not None:
            body["context"] = context

        data = self._client._post("/ara/governance/evaluate", json=body)
        return GovernanceResult.from_dict(data)


class _AraAPI:
    """Ara action execution endpoints."""

    def __init__(self, client: ArqeraClient):
        self._client = client

    def execute(
        self,
        action: str,
        *,
        description: str | None = None,
        context: dict[str, Any] | None = None,
    ) -> AraAction:
        """Execute an action through Ara with governance evaluation.

        Args:
            action: Action identifier.
            description: Human-readable description.
            context: Additional context.

        Returns:
            AraAction with execution result and governance verdict.
        """
        body: dict[str, Any] = {"action": action}
        if description is not None:
            body["description"] = description
        if context is not None:
            body["context"] = context

        data = self._client._post("/ara/execute", json=body)
        return AraAction.from_dict(data)

    def approve(self, action_id: str) -> AraAction:
        """Approve a pending action.

        Args:
            action_id: ID of the action to approve.

        Returns:
            Updated AraAction.
        """
        data = self._client._post(f"/ara/approve/{action_id}")
        return AraAction.from_dict(data)

    def reject(self, action_id: str, *, reason: str | None = None) -> AraAction:
        """Reject a pending action.

        Args:
            action_id: ID of the action to reject.
            reason: Reason for rejection.

        Returns:
            Updated AraAction.
        """
        body: dict[str, Any] = {}
        if reason is not None:
            body["reason"] = reason
        data = self._client._post(f"/ara/reject/{action_id}", json=body or None)
        return AraAction.from_dict(data)

    def pending(self) -> list[AraAction]:
        """List all pending actions awaiting approval.

        Returns:
            List of pending AraAction objects.
        """
        data = self._client._get("/ara/pending")
        items = data if isinstance(data, list) else data.get("items", [])
        return [AraAction.from_dict(item) for item in items]


class _EvidenceAPI:
    """Evidence chain endpoints."""

    def __init__(self, client: ArqeraClient):
        self._client = client

    def list(
        self,
        *,
        artifact_type: str | None = None,
        page: int = 1,
        page_size: int = 50,
    ) -> list[EvidenceArtifact]:
        """List evidence artifacts.

        Args:
            artifact_type: Filter by artifact type.
            page: Page number (1-indexed).
            page_size: Number of results per page.

        Returns:
            List of EvidenceArtifact objects.
        """
        params: dict[str, Any] = {"page": page, "page_size": page_size}
        if artifact_type is not None:
            params["artifact_type"] = artifact_type

        data = self._client._get("/evidence", params=params)
        items = data if isinstance(data, list) else data.get("items", [])
        return [EvidenceArtifact.from_dict(item) for item in items]

    def export(
        self,
        *,
        artifact_types: list[str] | None = None,
        start_date: str | None = None,
        end_date: str | None = None,
        export_format: str = "json",
    ) -> dict[str, Any]:
        """Export evidence artifacts for compliance audits.

        Args:
            artifact_types: Filter by artifact types.
            start_date: ISO date string for start of range.
            end_date: ISO date string for end of range.
            export_format: Export format ("json" or "csv").

        Returns:
            Export result with artifacts data.
        """
        body: dict[str, Any] = {"format": export_format}
        if artifact_types is not None:
            body["artifact_types"] = artifact_types
        if start_date is not None:
            body["start_date"] = start_date
        if end_date is not None:
            body["end_date"] = end_date

        return self._client._post("/evidence-collection/export", json=body)


class ArqeraClient:
    """ARQERA API client.

    Usage:
        client = ArqeraClient(api_key="ak_...")

        # Evaluate governance
        result = client.governance.evaluate("email.send")
        if result.passed:
            print("Action allowed")

        # Execute with governance
        action = client.ara.execute("email.send", description="Send report")

        # List evidence
        artifacts = client.evidence.list(artifact_type="governance_evaluation")
    """

    def __init__(
        self,
        api_key: str,
        *,
        base_url: str = "https://api.arqera.io/api",
        timeout: float = 30.0,
    ):
        """Initialize ARQERA client.

        Args:
            api_key: API key (starts with "ak_").
            base_url: API base URL.
            timeout: Request timeout in seconds.
        """
        self._api_key = api_key
        self._base_url = base_url.rstrip("/")
        self._http = httpx.Client(
            base_url=self._base_url,
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
                "User-Agent": "arqera-python/0.1.0",
            },
            timeout=timeout,
        )

        self.governance = _GovernanceAPI(self)
        self.ara = _AraAPI(self)
        self.evidence = _EvidenceAPI(self)

    def _get(self, path: str, *, params: dict[str, Any] | None = None) -> Any:
        """Make GET request."""
        response = self._http.get(path, params=params)
        response.raise_for_status()
        return response.json()

    def _post(self, path: str, *, json: dict[str, Any] | None = None) -> Any:
        """Make POST request."""
        response = self._http.post(path, json=json)
        response.raise_for_status()
        return response.json()

    def close(self) -> None:
        """Close the HTTP client."""
        self._http.close()

    def __enter__(self) -> ArqeraClient:
        return self

    def __exit__(self, *args: Any) -> None:
        self.close()
