"""Service registration and management API."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from ..exceptions import ServiceRegistrationError
from ..models import HeartbeatResponse, Service, ServiceHealth, ServiceRegistration

if TYPE_CHECKING:
    from ..client import VikdataClient


class ServicesEndpoint:
    """API endpoint for service registration and management."""

    def __init__(self, client: "VikdataClient") -> None:
        """Initialize services endpoint.

        Args:
            client: VikdataClient instance
        """
        self.client = client

    async def register(
        self,
        name: str,
        service_url: str,
        health_endpoint: str | None = None,
        description: str | None = None,
        permissions: list[str] | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> ServiceRegistration:
        """Register a service with vikdata.

        Args:
            name: Service name (e.g., "fishinfo")
            service_url: Base URL of the service
            health_endpoint: Optional health check endpoint path
            description: Optional service description
            permissions: Optional list of permissions this service provides
            metadata: Optional metadata dictionary

        Returns:
            ServiceRegistration with API key

        Raises:
            ServiceRegistrationError: If registration fails
        """
        try:
            health_url = None
            if health_endpoint:
                health_url = f"{service_url.rstrip('/')}/{health_endpoint.lstrip('/')}"

            response = await self.client.request(
                "POST",
                "/api/v1/services/register",
                json={
                    "name": name,
                    "description": description,
                    "base_url": service_url,
                    "health_url": health_url,
                    "service_key": self.client.service_key,
                    "permissions": permissions or [],
                    "metadata": metadata or {},
                },
            )

            data = response.json()
            return ServiceRegistration(**data)

        except Exception as e:
            raise ServiceRegistrationError(f"Failed to register service: {e}") from e

    async def unregister(self, service_id: str) -> None:
        """Unregister a service from vikdata.

        Args:
            service_id: Service ID to unregister

        Raises:
            ServiceRegistrationError: If unregistration fails
        """
        try:
            await self.client.request(
                "DELETE",
                f"/api/v1/services/{service_id}",
            )
        except Exception as e:
            raise ServiceRegistrationError(f"Failed to unregister service: {e}") from e

    async def heartbeat(self, service_id: str) -> HeartbeatResponse:
        """Send heartbeat signal for a registered service.

        Args:
            service_id: Service ID to send heartbeat for

        Returns:
            HeartbeatResponse with acknowledgment and timing info

        Raises:
            ServiceRegistrationError: If heartbeat fails
        """
        try:
            response = await self.client.request(
                "POST",
                f"/api/v1/services/{service_id}/heartbeat",
            )
            data = response.json()
            return HeartbeatResponse(**data)
        except Exception as e:
            raise ServiceRegistrationError(f"Failed to send heartbeat: {e}") from e

    async def deregister(self, service_id: str) -> None:
        """Deregister a service from vikdata (alias for unregister).

        Args:
            service_id: Service ID to deregister

        Raises:
            ServiceRegistrationError: If deregistration fails
        """
        await self.unregister(service_id)

    async def list(self) -> list[Service]:
        """List all registered services.

        Returns:
            List of registered services

        Raises:
            ServiceRegistrationError: If listing fails
        """
        try:
            response = await self.client.request(
                "GET",
                "/api/v1/services",
            )
            data = response.json()
            return [Service(**item) for item in data.get("data", [])]
        except Exception as e:
            raise ServiceRegistrationError(f"Failed to list services: {e}") from e

    async def get(self, service_id: str) -> Service:
        """Get details of a specific service.

        Args:
            service_id: Service ID

        Returns:
            Service details

        Raises:
            ServiceRegistrationError: If fetching fails
        """
        try:
            response = await self.client.request(
                "GET",
                f"/api/v1/services/{service_id}",
            )
            data = response.json()
            return Service(**data)
        except Exception as e:
            raise ServiceRegistrationError(f"Failed to get service: {e}") from e

    async def health_status(self, service_id: str | None = None) -> ServiceHealth | list[ServiceHealth]:
        """Get health status of service(s).

        Args:
            service_id: Optional service ID. If None, returns all services.

        Returns:
            ServiceHealth or list of ServiceHealth

        Raises:
            ServiceRegistrationError: If fetching health fails
        """
        try:
            if service_id:
                response = await self.client.request(
                    "GET",
                    f"/api/v1/services/{service_id}/health",
                )
                data = response.json()
                return ServiceHealth(**data)
            else:
                response = await self.client.request(
                    "GET",
                    "/api/v1/services/health",
                )
                data = response.json()
                return [ServiceHealth(**item) for item in data.get("data", [])]
        except Exception as e:
            raise ServiceRegistrationError(f"Failed to get health status: {e}") from e

    async def report_health(
        self,
        service_id: str,
        status: str,
        checks: dict[str, Any] | None = None,
        details: dict[str, Any] | None = None,
    ) -> None:
        """Report health status to vikdata.

        Args:
            service_id: Service ID
            status: Health status (healthy, degraded, unhealthy)
            checks: Individual health check results
            details: Additional health details

        Raises:
            ServiceRegistrationError: If reporting fails
        """
        try:
            await self.client.request(
                "POST",
                f"/api/v1/services/{service_id}/health",
                json={
                    "status": status,
                    "checks": checks or {},
                    "details": details or {},
                },
            )
        except Exception as e:
            raise ServiceRegistrationError(f"Failed to report health: {e}") from e
