from typing import ClassVar, Literal, Self

from . import Color
from .style import Layer


class AnsiColor:
    """
    The 16 extended ANSI colors.

    The ANSI color comprise eight base colors and their eight bright versions.
    Unlike most other colors, the ANSI colors have no intrinsic color values and
    hence are abstract colors. At the same time, they do have semantics.
    """
    Black: ClassVar[AnsiColor] = ...
    Red: ClassVar[AnsiColor] = ...
    Green: ClassVar[AnsiColor] = ...
    Yellow: ClassVar[AnsiColor] = ...
    Blue: ClassVar[AnsiColor] = ...
    Magenta: ClassVar[AnsiColor] = ...
    Cyan: ClassVar[AnsiColor] = ...
    White: ClassVar[AnsiColor] = ...
    BrightBlack: ClassVar[AnsiColor] = ...
    BrightRed: ClassVar[AnsiColor] = ...
    BrightGreen: ClassVar[AnsiColor] = ...
    BrightYellow: ClassVar[AnsiColor] = ...
    BrightBlue: ClassVar[AnsiColor] = ...
    BrightMagenta: ClassVar[AnsiColor] = ...
    BrightCyan: ClassVar[AnsiColor] = ...
    BrightWhite: ClassVar[AnsiColor] = ...

    @staticmethod
    def all() -> AnsiColorIterator: ...
    @staticmethod
    def try_from_8bit(value: int) -> AnsiColor: ...
    def to_8bit(self) -> int: ...
    def is_achromatic(self) -> bool: ...
    def is_bright(self) -> bool: ...
    def to_3bit(self) -> AnsiColor: ...
    def name(self) -> str: ...
    def abbr(self) -> str: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class AnsiColorIterator:
    """An iterator over all ANSI colors."""
    def __len__(self) -> int: ...
    def __iter__(self) -> Self: ...
    def __next__(self) -> AnsiColor: ...


class EmbeddedRgb:
    """The 6x6x6 RGB cube embedded in 8-bit color."""
    def __new__(cls, r: int, g: int, b:int) -> Self: ...
    @staticmethod
    def try_from_8bit(value: int) -> EmbeddedRgb: ...
    def to_8bit(self) -> int: ...
    def to_24bit(self) -> bytes: ...
    def to_color(self) -> Color: ...
    def coordinates(self) -> bytes: ...
    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class GrayGradient:
    """The 24-step gray gradient embedded in 8-bit color."""
    def __new__(cls, value: int) -> Self: ...
    @staticmethod
    def try_from_8bit(value: int) -> GrayGradient: ...
    def to_8bit(self) -> int: ...
    def to_24bit(self) -> bytes: ...
    def to_color(self) -> Color: ...
    def level(self) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class EightBitColor_Ansi(EightBitColor):
    """The ANSI colors."""
    def __new__(cls, color: AnsiColor) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> AnsiColor: ...


class EightBitColor_Embedded(EightBitColor):
    """The embedded RGB colors."""
    def __new__(cls, color: EmbeddedRgb) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> EmbeddedRgb: ...


class EightBitColor_Gray(EightBitColor):
    """The gray gradient colors."""
    def __new__(cls, color: GrayGradient) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> GrayGradient: ...


class EightBitColor:
    """The 8-bit colors."""
    Ansi = EightBitColor_Ansi
    Embedded = EightBitColor_Embedded
    Gray = EightBitColor_Gray

    @staticmethod
    def from_8bit(byte: int) -> EightBitColor: ...

    def to_8bit(self) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class Rgb:
    """24-bit RGB colors."""
    def __new__(cls, r: int, g: int, b: int) -> Rgb: ...
    @staticmethod
    def from_color(color: Color) -> Rgb: ...
    def to_color(self) -> Color: ...
    def coordinates(self) -> bytes: ...
    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> int: ...
    def weighted_euclidian_distance(self, other: Rgb) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...


class Colorant_Default(Colorant):
    """The default color."""
    def __new__(cls) -> Self: ...


class Colorant_Ansi(Colorant):
    """The ANSI colors."""
    def __new__(cls, color: AnsiColor) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> AnsiColor: ...


class Colorant_Embedded(Colorant):
    """The embedded RGB colors."""
    def __new__(cls, color: EmbeddedRgb) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> EmbeddedRgb: ...


class Colorant_Gray(Colorant):
    """The gray gradient colors."""
    def __new__(cls, color: GrayGradient) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> GrayGradient: ...


class Colorant_Rgb(Colorant):
    """The 24bit colors."""
    def __new__(cls, color: Rgb) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> Rgb: ...


class Colorant_HiRes(Colorant):
    """The high-resolution colors."""
    def __new__(cls, color: Color) -> Self: ...
    def __getitem__(self, index: Literal[0]) -> Color: ...


class Colorant:
    """A wrapper for all color representations."""
    Default = Colorant_Default
    Ansi = Colorant_Ansi
    Embedded = Colorant_Embedded
    Gray = Colorant_Gray
    Rgb = Colorant_Rgb
    HiRes = Colorant_HiRes

    @staticmethod
    def of(
        colorant: (
            int | AnsiColor | EmbeddedRgb | GrayGradient | EightBitColor | Rgb
            | Color | Colorant
        )
    ) -> Colorant: ...

    def try_to_8bit(self) -> int: ...
    def try_to_24bit(self) -> tuple[int, int, int]: ...
    def is_default(self) -> bool: ...
    def __neg__(self) -> None | Colorant: ...
    def __getitem__(
        self, index: Literal[0]
    ) -> AnsiColor | EmbeddedRgb | GrayGradient | Rgb | Color: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...
    def display(self, layer: Layer) -> str: ...
