"""Ingress API endpoints."""

from __future__ import annotations

from typing import TYPE_CHECKING
from uuid import UUID

from vikdata.models.common import PaginatedResponse
from vikdata.models.ingress import (
    IngressCore,
    IngressCoreListItem,
    CreateIngressCoreRequest,
    UpdateIngressCoreRequest,
    IngressChannel,
    IngressChannelListItem,
    CreateIngressChannelRequest,
    UpdateIngressChannelRequest,
    IngressDestination,
    IngressDestinationListItem,
    CreateIngressDestinationRequest,
    UpdateIngressDestinationRequest,
    IngressMetric,
    PreviewConfigUpdate,
)
from vikdata.models.api_key import (
    ApiKeyListResponse,
    ApiKeyCreateResponse,
    ApiKeyCreate,
)

if TYPE_CHECKING:
    from vikdata.client import VikdataClient


class IngressCoresAPI:
    """Ingress core management."""

    def __init__(self, client: "VikdataClient") -> None:
        self._client = client

    async def list(
        self,
        *,
        page: int | None = None,
        per_page: int | None = None,
        status: str | None = None,
        series_id: UUID | None = None,
        search: str | None = None,
    ) -> PaginatedResponse[IngressCoreListItem]:
        """List ingress cores for the current tenant.

        Args:
            page: Page number (default: 1)
            per_page: Items per page (default: 20, max: 100)
            status: Filter by status (from lookup)
            series_id: Filter by series
            search: Search by name or slug

        Returns:
            Paginated list of ingress cores
        """
        params = {
            "page": page,
            "per_page": per_page,
            "status": status,
            "series_id": str(series_id) if series_id else None,
            "search": search,
        }
        params = {k: v for k, v in params.items() if v is not None}

        return await self._client.request(
            "GET",
            "/api/v1/ingress/cores",
            params=params,
            response_model=PaginatedResponse[IngressCoreListItem],
        )

    async def get(self, core_id: UUID) -> IngressCore:
        """Get an ingress core by ID.

        Args:
            core_id: Core ID

        Returns:
            Ingress core details
        """
        return await self._client.request(
            "GET",
            f"/api/v1/ingress/cores/{core_id}",
            response_model=IngressCore,
        )

    async def create(self, data: CreateIngressCoreRequest) -> IngressCore:
        """Create a new ingress core.

        Args:
            data: Core creation data

        Returns:
            Created ingress core
        """
        return await self._client.request(
            "POST",
            "/api/v1/ingress/cores",
            json=data,
            response_model=IngressCore,
        )

    async def update(
        self,
        core_id: UUID,
        data: UpdateIngressCoreRequest,
    ) -> IngressCore:
        """Update an ingress core.

        Args:
            core_id: Core ID
            data: Core update data

        Returns:
            Updated ingress core
        """
        return await self._client.request(
            "PATCH",
            f"/api/v1/ingress/cores/{core_id}",
            json=data,
            response_model=IngressCore,
        )

    async def delete(self, core_id: UUID) -> None:
        """Delete an ingress core.

        Args:
            core_id: Core ID
        """
        await self._client.request(
            "DELETE",
            f"/api/v1/ingress/cores/{core_id}",
        )

    async def deploy(self, core_id: UUID) -> IngressCore:
        """Deploy an ingress core to Kubernetes.

        Args:
            core_id: Core ID

        Returns:
            Updated ingress core with deployment status
        """
        return await self._client.request(
            "POST",
            f"/api/v1/ingress/cores/{core_id}/deploy",
            response_model=IngressCore,
        )

    async def stop(self, core_id: UUID) -> IngressCore:
        """Stop a running ingress core.

        Args:
            core_id: Core ID

        Returns:
            Updated ingress core
        """
        return await self._client.request(
            "POST",
            f"/api/v1/ingress/cores/{core_id}/stop",
            response_model=IngressCore,
        )

    async def enable_preview(self, core_id: UUID) -> IngressCore:
        """Enable preview for an ingress core.

        Args:
            core_id: Core ID

        Returns:
            Updated ingress core
        """
        return await self._client.request(
            "POST",
            f"/api/v1/ingress/cores/{core_id}/preview/enable",
            response_model=IngressCore,
        )

    async def disable_preview(self, core_id: UUID) -> IngressCore:
        """Disable preview for an ingress core.

        Args:
            core_id: Core ID

        Returns:
            Updated ingress core
        """
        return await self._client.request(
            "POST",
            f"/api/v1/ingress/cores/{core_id}/preview/disable",
            response_model=IngressCore,
        )

    async def update_preview_config(
        self,
        core_id: UUID,
        config: PreviewConfigUpdate,
    ) -> IngressCore:
        """Update preview configuration for an ingress core.

        Args:
            core_id: Core ID
            config: Preview configuration update

        Returns:
            Updated ingress core
        """
        return await self._client.request(
            "PATCH",
            f"/api/v1/ingress/cores/{core_id}/preview/config",
            json=config,
            response_model=IngressCore,
        )

    async def list_api_keys(
        self,
        core_id: UUID,
        include_revoked: bool = False,
    ) -> ApiKeyListResponse:
        """List API keys scoped to this core.

        Args:
            core_id: Core ID
            include_revoked: Whether to include revoked keys

        Returns:
            List of API keys
        """
        return await self._client.request(
            "GET",
            f"/api/v1/ingress/cores/{core_id}/api-keys",
            params={"include_revoked": include_revoked},
            response_model=ApiKeyListResponse,
        )

    async def create_api_key(
        self,
        core_id: UUID,
        data: ApiKeyCreate,
    ) -> ApiKeyCreateResponse:
        """Create an API key scoped to this core.

        Args:
            core_id: Core ID
            data: API key creation data

        Returns:
            Created API key with secret
        """
        return await self._client.request(
            "POST",
            f"/api/v1/ingress/cores/{core_id}/api-keys",
            json=data,
            response_model=ApiKeyCreateResponse,
        )


class IngressChannelsAPI:
    """Ingress channel management."""

    def __init__(self, client: "VikdataClient") -> None:
        self._client = client

    async def list(
        self,
        *,
        page: int | None = None,
        per_page: int | None = None,
        core_id: UUID | None = None,
        search: str | None = None,
    ) -> PaginatedResponse[IngressChannelListItem]:
        """List ingress channels.

        Args:
            page: Page number (default: 1)
            per_page: Items per page (default: 20, max: 100)
            core_id: Filter by core
            search: Search by name

        Returns:
            Paginated list of ingress channels
        """
        params = {
            "page": page,
            "per_page": per_page,
            "core_id": str(core_id) if core_id else None,
            "search": search,
        }
        params = {k: v for k, v in params.items() if v is not None}

        return await self._client.request(
            "GET",
            "/api/v1/ingress/channels",
            params=params,
            response_model=PaginatedResponse[IngressChannelListItem],
        )

    async def get(self, channel_id: UUID) -> IngressChannel:
        """Get an ingress channel by ID.

        Args:
            channel_id: Channel ID

        Returns:
            Ingress channel details
        """
        return await self._client.request(
            "GET",
            f"/api/v1/ingress/channels/{channel_id}",
            response_model=IngressChannel,
        )

    async def create(self, data: CreateIngressChannelRequest) -> IngressChannel:
        """Create a new ingress channel.

        Args:
            data: Channel creation data

        Returns:
            Created ingress channel
        """
        return await self._client.request(
            "POST",
            "/api/v1/ingress/channels",
            json=data,
            response_model=IngressChannel,
        )

    async def update(
        self,
        channel_id: UUID,
        data: UpdateIngressChannelRequest,
    ) -> IngressChannel:
        """Update an ingress channel.

        Args:
            channel_id: Channel ID
            data: Channel update data

        Returns:
            Updated ingress channel
        """
        return await self._client.request(
            "PATCH",
            f"/api/v1/ingress/channels/{channel_id}",
            json=data,
            response_model=IngressChannel,
        )

    async def delete(self, channel_id: UUID) -> None:
        """Delete an ingress channel.

        Args:
            channel_id: Channel ID
        """
        await self._client.request(
            "DELETE",
            f"/api/v1/ingress/channels/{channel_id}",
        )


class IngressDestinationsAPI:
    """Ingress destination management."""

    def __init__(self, client: "VikdataClient") -> None:
        self._client = client

    async def list(
        self,
        *,
        page: int | None = None,
        per_page: int | None = None,
        type: str | None = None,
        search: str | None = None,
    ) -> PaginatedResponse[IngressDestinationListItem]:
        """List ingress destinations.

        Args:
            page: Page number (default: 1)
            per_page: Items per page (default: 20, max: 100)
            type: Filter by type (from lookup)
            search: Search by name

        Returns:
            Paginated list of ingress destinations
        """
        params = {
            "page": page,
            "per_page": per_page,
            "type": type,
            "search": search,
        }
        params = {k: v for k, v in params.items() if v is not None}

        return await self._client.request(
            "GET",
            "/api/v1/ingress/destinations",
            params=params,
            response_model=PaginatedResponse[IngressDestinationListItem],
        )

    async def get(self, destination_id: UUID) -> IngressDestination:
        """Get an ingress destination by ID.

        Args:
            destination_id: Destination ID

        Returns:
            Ingress destination details
        """
        return await self._client.request(
            "GET",
            f"/api/v1/ingress/destinations/{destination_id}",
            response_model=IngressDestination,
        )

    async def create(
        self,
        data: CreateIngressDestinationRequest,
    ) -> IngressDestination:
        """Create a new ingress destination.

        Args:
            data: Destination creation data

        Returns:
            Created ingress destination
        """
        return await self._client.request(
            "POST",
            "/api/v1/ingress/destinations",
            json=data,
            response_model=IngressDestination,
        )

    async def update(
        self,
        destination_id: UUID,
        data: UpdateIngressDestinationRequest,
    ) -> IngressDestination:
        """Update an ingress destination.

        Args:
            destination_id: Destination ID
            data: Destination update data

        Returns:
            Updated ingress destination
        """
        return await self._client.request(
            "PATCH",
            f"/api/v1/ingress/destinations/{destination_id}",
            json=data,
            response_model=IngressDestination,
        )

    async def delete(self, destination_id: UUID) -> None:
        """Delete an ingress destination.

        Args:
            destination_id: Destination ID
        """
        await self._client.request(
            "DELETE",
            f"/api/v1/ingress/destinations/{destination_id}",
        )


class IngressMetricsAPI:
    """Ingress metrics."""

    def __init__(self, client: "VikdataClient") -> None:
        self._client = client

    async def query(
        self,
        *,
        core_id: UUID | None = None,
        channel_id: UUID | None = None,
        start_time: str | None = None,
        end_time: str | None = None,
    ) -> list[IngressMetric]:
        """Query ingress metrics.

        Args:
            core_id: Filter by core ID
            channel_id: Filter by channel ID
            start_time: Start time (ISO 8601)
            end_time: End time (ISO 8601)

        Returns:
            List of metric data points
        """
        params = {
            "core_id": str(core_id) if core_id else None,
            "channel_id": str(channel_id) if channel_id else None,
            "start_time": start_time,
            "end_time": end_time,
        }
        params = {k: v for k, v in params.items() if v is not None}

        return await self._client.request(
            "GET",
            "/api/v1/ingress/metrics",
            params=params,
            response_model=list[IngressMetric],
        )


class IngressAPI:
    """Ingress API endpoints.

    Handles ingress core, channel, destination, and metrics management.
    """

    def __init__(self, client: "VikdataClient") -> None:
        self._client = client
        self.cores = IngressCoresAPI(client)
        self.channels = IngressChannelsAPI(client)
        self.destinations = IngressDestinationsAPI(client)
        self.metrics = IngressMetricsAPI(client)
