"""Python library to connect deCONZ and Home Assistant to work together."""

from typing import Final, Literal, NotRequired, TypedDict

from . import ResourceGroup
from .deconz_device import DeconzDevice
from .light.light import LightColorMode, LightEffect
from .scene import TypedScene

COLOR_STATE_ATTRIBUTES: Final = {
    "bri",
    "ct",
    "hue",
    "sat",
    "xy",
    "colormode",
    "effect",
}


class TypedGroupAction(TypedDict):
    """Group action type definition."""

    bri: int
    colormode: NotRequired[Literal["ct", "hs", "xy"]]
    ct: int
    effect: NotRequired[Literal["colorloop", "none"]]
    hue: int
    on: bool
    sat: int
    xy: tuple[float, float]


class TypedGroupState(TypedDict):
    """Group state type definition."""

    all_on: bool
    any_on: bool


class TypedGroup(TypedDict):
    """Group type definition."""

    action: TypedGroupAction
    devicemembership: list[str]
    hidden: bool
    id: str
    lights: list[str]
    lightsequence: list[str]
    multideviceids: list[str]
    name: str
    scenes: list[TypedScene]
    state: TypedGroupState
    type: str


class Group(DeconzDevice):
    """deCONZ light group representation.

    Dresden Elektroniks documentation of light groups in deCONZ
    http://dresden-elektronik.github.io/deconz-rest-doc/groups/
    """

    raw: TypedGroup
    resource_group = ResourceGroup.GROUP

    @property
    def state(self) -> bool | None:
        """Is any light in light group on."""
        return self.any_on

    @property
    def brightness(self) -> int | None:
        """Brightness of the light.

        Depending on the light type 0 might not mean visible "off"
        but minimum brightness.
        """
        return self.raw["action"].get("bri")

    @property
    def color_temp(self) -> int | None:
        """Mired color temperature of the light. (2000K - 6500K)."""
        return self.raw["action"].get("ct")

    @property
    def hue(self) -> int | None:
        """Color hue of the light.

        The hue parameter in the HSV color model is between 0°-360°
        and is mapped to 0..65535 to get 16-bit resolution.
        """
        return self.raw["action"].get("hue")

    @property
    def saturation(self) -> int | None:
        """Color saturation of the light.

        There 0 means no color at all and 255 is the greatest saturation
        of the color.
        """
        return self.raw["action"].get("sat")

    @property
    def xy(self) -> tuple[float, float] | None:
        """CIE xy color space coordinates as array [x, y] of real values (0..1)."""
        x, y = self.raw["action"].get("xy", (None, None))

        if x is None or y is None:
            return None

        if x > 1:
            x = x / 65555

        if y > 1:
            y = y / 65555

        return (x, y)

    @property
    def color_mode(self) -> LightColorMode | None:
        """Color mode of group."""
        if "colormode" in self.raw["action"]:
            return LightColorMode(self.raw["action"]["colormode"])
        return None

    @property
    def effect(self) -> LightEffect | None:
        """Effect of the group."""
        if "effect" in self.raw["action"]:
            return LightEffect(self.raw["action"]["effect"])
        return None

    @property
    def reachable(self) -> bool:
        """Is group reachable."""
        return True

    @property
    def all_on(self) -> bool:
        """Is all lights in light group on."""
        return self.raw["state"].get("all_on") is True

    @property
    def any_on(self) -> bool:
        """Is any lights in light group on."""
        return self.raw["state"].get("any_on") is True

    @property
    def device_membership(self) -> list[str] | None:
        """List of device ids (sensors) when group was created by a device."""
        return self.raw.get("devicemembership")

    @property
    def hidden(self) -> bool | None:
        """Indicate the hidden status of the group.

        Has no effect at the gateway but apps can uses this to hide groups.
        """
        return self.raw.get("hidden")

    @property
    def id(self) -> str | None:
        """Group ID."""
        return self.raw.get("id")

    @property
    def lights(self) -> list[str]:
        """List of all light IDs in group.

        Sequence is defined by the gateway.
        """
        return self.raw.get("lights", [])

    @property
    def light_sequence(self) -> list[str] | None:
        """List of light IDs in group that can be sorted by the user.

        Need not to contain all light ids of this group.
        """
        return self.raw.get("lightsequence")

    @property
    def multi_device_ids(self) -> list[str] | None:
        """List of light IDs in group.

        Subsequent ids from multidevices with multiple endpoints.
        """
        return self.raw.get("multideviceids")
