from __future__ import annotations

from enum import IntEnum, StrEnum


class AppId(StrEnum):
    """Platform identifier forwarded in every request via the ``x-app-id`` header."""

    WEB = "web_global_seaart"
    APP = "app_global_seaart"
    PHONE = "phone_global_seaart"


class Role(IntEnum):
    """Message role in a conversation history."""

    USER = 1
    ASSISTANT = 2


class ImageSize(StrEnum):
    """Aspect ratio preset for image generation.

    Pre-defined presets cover common portrait, landscape, and square ratios.
    For exact pixel dimensions use :meth:`custom`.
    """

    PORTRAIT_1_2 = "1:2"
    PORTRAIT_2_3 = "2:3"
    PORTRAIT_3_4 = "3:4"
    PORTRAIT_4_5 = "4:5"
    PORTRAIT_9_16 = "9:16"

    LANDSCAPE_2_1 = "2:1"
    LANDSCAPE_3_2 = "3:2"
    LANDSCAPE_4_3 = "4:3"
    LANDSCAPE_5_4 = "5:4"
    LANDSCAPE_16_9 = "16:9"

    SQUARE = "1:1"

    @property
    def width(self) -> int:
        """Width component of the aspect ratio."""
        return int(self.value.split(":")[0])

    @property
    def height(self) -> int:
        """Height component of the aspect ratio."""
        return int(self.value.split(":")[1])

    @property
    def ratio(self) -> str:
        """Aspect ratio string in ``"W:H"`` format."""
        return self.value

    @classmethod
    def _missing_(cls, value: object) -> ImageSize:
        assert isinstance(value, str)
        obj = str.__new__(cls, value)
        obj._value_ = value
        return obj

    @classmethod
    def custom(cls, width: int, height: int) -> ImageSize:
        """Create an ``ImageSize`` from exact pixel dimensions.

        Args:
            width: Output width in pixels (minimum 384).
            height: Output height in pixels (minimum 384).

        Returns:
            An ``ImageSize`` with value ``"width:height"``.

        Raises:
            ValueError: If ``width`` or ``height`` is less than 384.
        """
        if width < 384 or height < 384:
            raise ValueError("Width and height must be at least 384 pixels.")
        return cls(f"{width}:{height}")

    @property
    def is_custom(self) -> bool:
        """``True`` when this instance was created with :meth:`custom` rather than a preset."""
        return self not in ImageSize.__members__.values()
