"""Short Links resource for CMDOP LLM service."""

from __future__ import annotations

from typing import TYPE_CHECKING, Optional, Union

import httpx
from openai._compat import cached_property
from openai._resource import AsyncAPIResource, SyncAPIResource
from openai._types import NOT_GIVEN, Body, Headers, NotGiven, Query

from ..types.short_links import (
    ShortLink,
    ShortLinkCreateResponse,
    ShortLinkDeleteResponse,
    ShortLinkListResponse,
    ShortLinkStatsResponse,
)

if TYPE_CHECKING:
    from .._client import AsyncCmdopLLM, CmdopLLM

__all__ = ["ShortLinks", "AsyncShortLinks"]


class ShortLinks(SyncAPIResource):
    """Short Links management resource.

    Provides URL shortening functionality similar to Bitly.

    Example:
        ```python
        from cmdop_llm import CmdopLLM

        client = CmdopLLM()

        # Create a short link
        link = client.short_links.create(url="https://example.com/long-url")
        print(link.short_url)  # https://llm.cmdop.com/s/abc123

        # List all links
        links = client.short_links.list()
        for link in links.data:
            print(f"{link.code}: {link.hits} hits")

        # Get stats
        stats = client.short_links.stats()
        print(f"Total links: {stats.total_links}")
        ```
    """

    _client: CmdopLLM

    @cached_property
    def with_raw_response(self) -> ShortLinksWithRawResponse:
        """Access raw HTTP response data."""
        return ShortLinksWithRawResponse(self)

    def create(
        self,
        *,
        url: str,
        custom_slug: Optional[str] = None,
        max_hits: Optional[int] = None,
        ttl: Optional[str] = None,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkCreateResponse:
        """Create a short link.

        Args:
            url: Target URL to shorten.
            custom_slug: Custom slug (lowercase alphanumeric and hyphens).
            max_hits: Maximum number of hits before link expires.
            ttl: Time to live (e.g., '7d', '24h', '30m').
            extra_headers: Additional headers to send.
            extra_query: Additional query parameters.
            extra_body: Additional body parameters.
            timeout: Request timeout.

        Returns:
            ShortLinkCreateResponse with the created link details.

        Raises:
            openai.ConflictError: If custom_slug already exists.
            openai.APIError: If the request fails.
        """
        body = {
            "url": url,
            "custom_slug": custom_slug,
            "max_hits": max_hits,
            "ttl": ttl,
        }
        body = {k: v for k, v in body.items() if v is not None}

        return self._post(
            "/s/",
            body=body,
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkCreateResponse,
        )

    def list(
        self,
        *,
        limit: int = 50,
        offset: int = 0,
        active_only: bool = False,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkListResponse:
        """List short links.

        Args:
            limit: Maximum number of links to return (1-100).
            offset: Number of links to skip.
            active_only: Only return active links.
            extra_headers: Additional headers to send.
            extra_query: Additional query parameters.
            extra_body: Additional body parameters.
            timeout: Request timeout.

        Returns:
            ShortLinkListResponse with paginated links.
        """
        params = {
            "limit": limit,
            "offset": offset,
            "active_only": active_only,
        }

        return self._get(
            "/s/",
            options={
                "extra_headers": extra_headers,
                "extra_query": {**(extra_query or {}), **params},
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkListResponse,
        )

    def get(
        self,
        code: str,
        *,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLink:
        """Get short link info.

        Args:
            code: Short link code or custom slug.
            extra_headers: Additional headers to send.
            extra_query: Additional query parameters.
            extra_body: Additional body parameters.
            timeout: Request timeout.

        Returns:
            ShortLink with link details.

        Raises:
            openai.NotFoundError: If link not found.
        """
        return self._get(
            f"/s/{code}/info",
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLink,
        )

    def stats(
        self,
        *,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkStatsResponse:
        """Get short links statistics.

        Args:
            extra_headers: Additional headers to send.
            extra_query: Additional query parameters.
            extra_body: Additional body parameters.
            timeout: Request timeout.

        Returns:
            ShortLinkStatsResponse with statistics.
        """
        return self._get(
            "/s/stats",
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkStatsResponse,
        )

    def delete(
        self,
        code: str,
        *,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkDeleteResponse:
        """Deactivate a short link.

        Args:
            code: Short link code or custom slug.
            extra_headers: Additional headers to send.
            extra_query: Additional query parameters.
            extra_body: Additional body parameters.
            timeout: Request timeout.

        Returns:
            ShortLinkDeleteResponse confirming deactivation.

        Raises:
            openai.NotFoundError: If link not found.
        """
        return self._delete(
            f"/s/{code}",
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkDeleteResponse,
        )


class AsyncShortLinks(AsyncAPIResource):
    """Async Short Links management resource."""

    _client: AsyncCmdopLLM

    @cached_property
    def with_raw_response(self) -> AsyncShortLinksWithRawResponse:
        """Access raw HTTP response data."""
        return AsyncShortLinksWithRawResponse(self)

    async def create(
        self,
        *,
        url: str,
        custom_slug: Optional[str] = None,
        max_hits: Optional[int] = None,
        ttl: Optional[str] = None,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkCreateResponse:
        """Create a short link (async).

        See ShortLinks.create for full documentation.
        """
        body = {
            "url": url,
            "custom_slug": custom_slug,
            "max_hits": max_hits,
            "ttl": ttl,
        }
        body = {k: v for k, v in body.items() if v is not None}

        return await self._post(
            "/s/",
            body=body,
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkCreateResponse,
        )

    async def list(
        self,
        *,
        limit: int = 50,
        offset: int = 0,
        active_only: bool = False,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkListResponse:
        """List short links (async).

        See ShortLinks.list for full documentation.
        """
        params = {
            "limit": limit,
            "offset": offset,
            "active_only": active_only,
        }

        return await self._get(
            "/s/",
            options={
                "extra_headers": extra_headers,
                "extra_query": {**(extra_query or {}), **params},
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkListResponse,
        )

    async def get(
        self,
        code: str,
        *,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLink:
        """Get short link info (async).

        See ShortLinks.get for full documentation.
        """
        return await self._get(
            f"/s/{code}/info",
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLink,
        )

    async def stats(
        self,
        *,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkStatsResponse:
        """Get short links statistics (async).

        See ShortLinks.stats for full documentation.
        """
        return await self._get(
            "/s/stats",
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkStatsResponse,
        )

    async def delete(
        self,
        code: str,
        *,
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: Union[float, httpx.Timeout, None, NotGiven] = NOT_GIVEN,
    ) -> ShortLinkDeleteResponse:
        """Deactivate a short link (async).

        See ShortLinks.delete for full documentation.
        """
        return await self._delete(
            f"/s/{code}",
            options={
                "extra_headers": extra_headers,
                "extra_query": extra_query,
                "extra_body": extra_body,
                "timeout": timeout,
            },
            cast_to=ShortLinkDeleteResponse,
        )


class ShortLinksWithRawResponse:
    """Raw response wrapper for ShortLinks resource."""

    def __init__(self, short_links: ShortLinks) -> None:
        self._short_links = short_links

    def create(self, **kwargs) -> httpx.Response:  # type: ignore
        """Get raw response from create."""
        return self._short_links._client.with_raw_response._post(  # type: ignore
            "/s/",
            body=kwargs,
        )

    def list(self, **kwargs) -> httpx.Response:  # type: ignore
        """Get raw response from list."""
        return self._short_links._client.with_raw_response._get(  # type: ignore
            "/s/",
            options={"extra_query": kwargs},
        )


class AsyncShortLinksWithRawResponse:
    """Raw response wrapper for AsyncShortLinks resource."""

    def __init__(self, short_links: AsyncShortLinks) -> None:
        self._short_links = short_links

    async def create(self, **kwargs) -> httpx.Response:  # type: ignore
        """Get raw response from create."""
        return await self._short_links._client.with_raw_response._post(  # type: ignore
            "/s/",
            body=kwargs,
        )

    async def list(self, **kwargs) -> httpx.Response:  # type: ignore
        """Get raw response from list."""
        return await self._short_links._client.with_raw_response._get(  # type: ignore
            "/s/",
            options={"extra_query": kwargs},
        )
