"""ACP sub-client — Autonomous Compute Procurement management."""

from __future__ import annotations

from typing import Any, Sequence

from sbn._http import HttpTransport

PREFIX = "/internal/acp"


class AcpClient:
    """Budget, lease, receipt, and invoice management for ACP.

    Usage::

        client = SbnClient(base_url="https://api.smartblocks.network")
        client.authenticate_api_key("sbn_live_abc123")

        # Budget
        budget = client.acp.get_budget("proj-1")
        client.acp.update_budget("proj-1", max_monthly_usd=5000, enabled=True)

        # Leases
        leases = client.acp.list_leases("proj-1", state="running")

        # Invoices
        inv = client.acp.generate_invoice("proj-1", start="2026-02-01T00:00:00Z", end="2026-03-01T00:00:00Z")
        client.acp.finalize_invoice("proj-1", inv["id"])
    """

    def __init__(self, transport: HttpTransport) -> None:
        self._t = transport

    # ── Budget ──────────────────────────────────────────────────────────

    def get_budget(self, project_id: str) -> dict[str, Any]:
        """Get ACP budget configuration for a project."""
        return self._t.get(f"{PREFIX}/projects/{project_id}/budget").json()

    def update_budget(
        self,
        project_id: str,
        *,
        max_hourly_usd: float | None = None,
        max_daily_usd: float | None = None,
        max_monthly_usd: float | None = None,
        max_concurrent_leases: int | None = None,
        max_bid_usd_hr: float | None = None,
        enabled: bool | None = None,
    ) -> dict[str, Any]:
        """Create or update ACP budget for a project.

        Only provided fields are sent; omitted fields retain server defaults
        or existing values.
        """
        body: dict[str, Any] = {}
        if max_hourly_usd is not None:
            body["max_hourly_usd"] = max_hourly_usd
        if max_daily_usd is not None:
            body["max_daily_usd"] = max_daily_usd
        if max_monthly_usd is not None:
            body["max_monthly_usd"] = max_monthly_usd
        if max_concurrent_leases is not None:
            body["max_concurrent_leases"] = max_concurrent_leases
        if max_bid_usd_hr is not None:
            body["max_bid_usd_hr"] = max_bid_usd_hr
        if enabled is not None:
            body["enabled"] = enabled
        return self._t.put(f"{PREFIX}/projects/{project_id}/budget", json=body).json()

    def kill(self, project_id: str, *, reason: str = "manual") -> dict[str, Any]:
        """Activate the kill-switch — blocks all new provisioning."""
        return self._t.post(
            f"{PREFIX}/projects/{project_id}/kill",
            json={"reason": reason},
        ).json()

    def unkill(self, project_id: str) -> dict[str, Any]:
        """Deactivate the kill-switch — resume provisioning."""
        return self._t.post(
            f"{PREFIX}/projects/{project_id}/unkill", json={},
        ).json()

    # ── Leases ──────────────────────────────────────────────────────────

    def list_leases(
        self,
        project_id: str,
        *,
        state: str | None = None,
        limit: int = 50,
    ) -> list[dict[str, Any]]:
        """List ACP leases for a project."""
        params: dict[str, Any] = {"limit": limit}
        if state:
            params["state"] = state
        data = self._t.get(
            f"{PREFIX}/projects/{project_id}/leases", params=params,
        ).json()
        return data.get("leases", [])

    def get_lease(self, project_id: str, lease_id: str) -> dict[str, Any]:
        """Get a specific lease."""
        return self._t.get(
            f"{PREFIX}/projects/{project_id}/leases/{lease_id}",
        ).json()

    # ── Receipts ────────────────────────────────────────────────────────

    def list_receipts(
        self,
        project_id: str,
        *,
        receipt_type: str | None = None,
        since: str | None = None,
        cursor: str | None = None,
        limit: int = 50,
    ) -> dict[str, Any]:
        """List ACP provisioning/release receipts.

        Returns dict with ``receipts`` list and optional ``next_cursor``.
        """
        params: dict[str, Any] = {"limit": limit}
        if receipt_type:
            params["receipt_type"] = receipt_type
        if since:
            params["since"] = since
        if cursor:
            params["cursor"] = cursor
        return self._t.get(
            f"{PREFIX}/projects/{project_id}/receipts", params=params,
        ).json()

    # ── Status ──────────────────────────────────────────────────────────

    def status(self, project_id: str) -> dict[str, Any]:
        """ACP overview: budget, active leases, spend summary."""
        return self._t.get(
            f"{PREFIX}/projects/{project_id}/status",
        ).json()

    # ── Invoices ────────────────────────────────────────────────────────

    def generate_invoice(
        self,
        project_id: str,
        *,
        start: str,
        end: str,
    ) -> dict[str, Any]:
        """Generate an ACP invoice for a billing period.

        Args:
            start: ISO 8601 billing period start (e.g. "2026-02-01T00:00:00Z").
            end:   ISO 8601 billing period end.
        """
        return self._t.post(
            f"{PREFIX}/projects/{project_id}/invoices/generate",
            json={
                "billing_period_start": start,
                "billing_period_end": end,
            },
        ).json()

    def list_invoices(
        self,
        project_id: str,
        *,
        status: str | None = None,
        limit: int = 50,
        offset: int = 0,
    ) -> dict[str, Any]:
        """List ACP invoices for a project.

        Returns dict with ``invoices`` list and ``total`` count.
        """
        params: dict[str, Any] = {"limit": limit, "offset": offset}
        if status:
            params["status"] = status
        return self._t.get(
            f"{PREFIX}/projects/{project_id}/invoices", params=params,
        ).json()

    def get_invoice(self, project_id: str, invoice_id: str) -> dict[str, Any]:
        """Get invoice detail with line items."""
        return self._t.get(
            f"{PREFIX}/projects/{project_id}/invoices/{invoice_id}",
        ).json()

    def finalize_invoice(self, project_id: str, invoice_id: str) -> dict[str, Any]:
        """Finalize a draft invoice and mark as sent."""
        return self._t.post(
            f"{PREFIX}/projects/{project_id}/invoices/{invoice_id}/finalize",
            json={},
        ).json()

    def mark_invoice_paid(self, project_id: str, invoice_id: str) -> dict[str, Any]:
        """Record payment for an invoice."""
        return self._t.post(
            f"{PREFIX}/projects/{project_id}/invoices/{invoice_id}/mark-paid",
            json={},
        ).json()

    def void_invoice(self, project_id: str, invoice_id: str) -> dict[str, Any]:
        """Void an invoice (cannot be undone)."""
        return self._t.post(
            f"{PREFIX}/projects/{project_id}/invoices/{invoice_id}/void",
            json={},
        ).json()
