"""Control plane sub-client — tenants, rate plans, and validators."""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from typing import Any, Mapping

from sbn._http import HttpTransport

PREFIX = "/control-plane"


# ---------------------------------------------------------------------------
# Data models
# ---------------------------------------------------------------------------


@dataclass(slots=True)
class RatePlan:
    id: str
    name: str
    sla_tier: str
    daily_quota: int
    burst_limit_per_minute: int
    description: str | None = None
    created_at: str | None = None

    @classmethod
    def from_dict(cls, data: Mapping[str, Any]) -> RatePlan:
        return cls(
            id=str(data["id"]),
            name=str(data["name"]),
            sla_tier=str(data.get("sla_tier", "")),
            daily_quota=int(data.get("daily_quota", 0)),
            burst_limit_per_minute=int(data.get("burst_limit_per_minute", 0)),
            description=data.get("description"),
            created_at=data.get("created_at"),
        )


@dataclass(slots=True)
class TenantSummary:
    id: str
    name: str
    status: str
    rate_plan_id: str
    sla_tier: str
    aggregator_endpoint: str
    validator_count: int = 0

    @classmethod
    def from_dict(cls, data: Mapping[str, Any]) -> TenantSummary:
        return cls(
            id=str(data["id"]),
            name=str(data["name"]),
            status=str(data.get("status", "provisioning")),
            rate_plan_id=str(data.get("rate_plan_id", "")),
            sla_tier=str(data.get("sla_tier", "")),
            aggregator_endpoint=str(data.get("aggregator_endpoint", "")),
            validator_count=int(data.get("validator_count", 0)),
        )


@dataclass(slots=True)
class Validator:
    validator_id: str
    endpoint: str
    status: str
    region: str | None = None
    registered_at: str | None = None
    last_seen_at: str | None = None

    @classmethod
    def from_dict(cls, data: Mapping[str, Any]) -> Validator:
        return cls(
            validator_id=str(data["validator_id"]),
            endpoint=str(data["endpoint"]),
            status=str(data.get("status", "registered")),
            region=data.get("region"),
            registered_at=data.get("registered_at"),
            last_seen_at=data.get("last_seen_at"),
        )


@dataclass(slots=True)
class TenantDetail:
    tenant: dict[str, Any]
    rate_plan: RatePlan
    validators: list[Validator]
    summary: TenantSummary

    @classmethod
    def from_dict(cls, data: Mapping[str, Any]) -> TenantDetail:
        return cls(
            tenant=dict(data.get("tenant") or {}),
            rate_plan=RatePlan.from_dict(data.get("rate_plan") or {}),
            validators=[
                Validator.from_dict(v)
                for v in (data.get("validators") or [])
            ],
            summary=TenantSummary.from_dict(data.get("summary") or data),
        )


# ---------------------------------------------------------------------------
# Control plane client
# ---------------------------------------------------------------------------


class ControlPlaneClient:
    """Tenant management, rate plans, and validator lifecycle."""

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

    # ── Rate plans ─────────────────────────────────────────────────────

    def list_rate_plans(self) -> list[RatePlan]:
        data = self._t.get(f"{PREFIX}/rate-plans").json()
        return [RatePlan.from_dict(d) for d in data]

    def create_rate_plan(
        self,
        *,
        name: str,
        sla_tier: str,
        daily_quota: int,
        burst_limit_per_minute: int,
        description: str | None = None,
    ) -> RatePlan:
        body: dict[str, Any] = {
            "name": name,
            "sla_tier": sla_tier,
            "daily_quota": daily_quota,
            "burst_limit_per_minute": burst_limit_per_minute,
        }
        if description:
            body["description"] = description
        return RatePlan.from_dict(
            self._t.post(f"{PREFIX}/rate-plans", json=body).json()
        )

    # ── Tenants ────────────────────────────────────────────────────────

    def list_tenants(self) -> list[TenantSummary]:
        data = self._t.get(f"{PREFIX}/tenants").json()
        return [TenantSummary.from_dict(d) for d in data]

    def get_tenant(self, tenant_id: str) -> TenantDetail:
        return TenantDetail.from_dict(
            self._t.get(f"{PREFIX}/tenants/{tenant_id}").json()
        )

    def create_tenant(
        self,
        *,
        name: str,
        contact_email: str,
        aggregator_endpoint: str,
        rate_plan_id: str,
        activate: bool = True,
    ) -> TenantDetail:
        body = {
            "name": name,
            "contact_email": contact_email,
            "aggregator_endpoint": aggregator_endpoint,
            "rate_plan_id": rate_plan_id,
            "activate": activate,
        }
        return TenantDetail.from_dict(
            self._t.post(f"{PREFIX}/tenants", json=body).json()
        )

    def update_tenant_rate_plan(
        self,
        tenant_id: str,
        rate_plan_id: str,
        *,
        activate: bool | None = None,
    ) -> TenantDetail:
        body: dict[str, Any] = {"rate_plan_id": rate_plan_id}
        if activate is not None:
            body["activate"] = activate
        return TenantDetail.from_dict(
            self._t.patch(f"{PREFIX}/tenants/{tenant_id}/rate-plan", json=body).json()
        )

    # ── Validators ─────────────────────────────────────────────────────

    def list_validators(self, tenant_id: str) -> list[Validator]:
        data = self._t.get(f"{PREFIX}/tenants/{tenant_id}/validators").json()
        return [Validator.from_dict(d) for d in data]

    def register_validator(
        self,
        tenant_id: str,
        *,
        validator_id: str,
        endpoint: str,
        region: str | None = None,
    ) -> Validator:
        body: dict[str, Any] = {
            "validator_id": validator_id,
            "endpoint": endpoint,
        }
        if region:
            body["region"] = region
        return Validator.from_dict(
            self._t.post(
                f"{PREFIX}/tenants/{tenant_id}/validators", json=body
            ).json()
        )

    def heartbeat_validator(
        self, tenant_id: str, validator_id: str
    ) -> Validator:
        return Validator.from_dict(
            self._t.post(
                f"{PREFIX}/tenants/{tenant_id}/validators/{validator_id}/heartbeat",
                json={},
            ).json()
        )
