"""Image generation resource for CMDOP LLM service."""

from __future__ import annotations

from typing import TYPE_CHECKING, Iterable, Literal, 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 openai.types import ImagesResponse

if TYPE_CHECKING:
    from .._client import AsyncCmdopLLM, CmdopLLM

__all__ = ["Images", "AsyncImages"]


class Images(SyncAPIResource):
    """Image generation resource.

    Provides image generation capabilities with model quality presets.

    Example:
        ```python
        from cmdop_llm import CmdopLLM

        client = CmdopLLM()
        response = client.images.generate(
            prompt="A beautiful sunset",
            model_quality="balanced"
        )
        print(response.data[0].url)
        ```
    """

    _client: CmdopLLM

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

    def generate(
        self,
        *,
        prompt: str,
        model: Optional[str] = None,
        model_quality: Optional[Literal["fast", "balanced", "best"]] = None,
        n: Optional[int] = None,
        quality: Optional[Literal["standard", "hd"]] = None,
        response_format: Optional[Literal["url", "b64_json"]] = None,
        size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] = None,
        style: Optional[Literal["vivid", "natural"]] = None,
        user: 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,
    ) -> ImagesResponse:
        """Generate images from a text prompt.

        Args:
            prompt: A text description of the desired image(s).
            model: The model to use for image generation.
            model_quality: Quality preset for auto-selection ("fast", "balanced", "best").
                          Ignored if explicit model is specified.
            n: The number of images to generate.
            quality: The quality of the image ("standard" or "hd").
            response_format: The format of the generated images ("url" or "b64_json").
            size: The size of the generated images.
            style: The style of the generated images ("vivid" or "natural").
            user: A unique identifier for the end-user.
            extra_headers: Additional headers to send.
            extra_query: Additional query parameters.
            extra_body: Additional body parameters.
            timeout: Request timeout.

        Returns:
            ImagesResponse with generated image data.
        """
        body: dict = {"prompt": prompt}

        if model is not None:
            body["model"] = model
        if model_quality is not None:
            body["model_quality"] = model_quality
        if n is not None:
            body["n"] = n
        if quality is not None:
            body["quality"] = quality
        if response_format is not None:
            body["response_format"] = response_format
        if size is not None:
            body["size"] = size
        if style is not None:
            body["style"] = style
        if user is not None:
            body["user"] = user

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


class AsyncImages(AsyncAPIResource):
    """Async image generation resource."""

    _client: AsyncCmdopLLM

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

    async def generate(
        self,
        *,
        prompt: str,
        model: Optional[str] = None,
        model_quality: Optional[Literal["fast", "balanced", "best"]] = None,
        n: Optional[int] = None,
        quality: Optional[Literal["standard", "hd"]] = None,
        response_format: Optional[Literal["url", "b64_json"]] = None,
        size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] = None,
        style: Optional[Literal["vivid", "natural"]] = None,
        user: 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,
    ) -> ImagesResponse:
        """Generate images from a text prompt (async).

        See Images.generate for full documentation.
        """
        body: dict = {"prompt": prompt}

        if model is not None:
            body["model"] = model
        if model_quality is not None:
            body["model_quality"] = model_quality
        if n is not None:
            body["n"] = n
        if quality is not None:
            body["quality"] = quality
        if response_format is not None:
            body["response_format"] = response_format
        if size is not None:
            body["size"] = size
        if style is not None:
            body["style"] = style
        if user is not None:
            body["user"] = user

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


class ImagesWithRawResponse:
    """Raw response wrapper for Images resource."""

    def __init__(self, images: Images) -> None:
        self._images = images

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


class AsyncImagesWithRawResponse:
    """Raw response wrapper for AsyncImages resource."""

    def __init__(self, images: AsyncImages) -> None:
        self._images = images

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