"""Radix slider components."""

from __future__ import annotations

from types import SimpleNamespace
from typing import Any, Dict, List, Literal

from reflex.components.component import Component
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
from reflex.style import Style
from reflex.vars import Var

LiteralSliderOrientation = Literal["horizontal", "vertical"]
LiteralSliderDir = Literal["ltr", "rtl"]


class SliderComponent(RadixPrimitiveComponentWithClassName):
    """Base class for all @radix-ui/react-slider components."""

    library = "@radix-ui/react-slider@^1.1.2"


class SliderRoot(SliderComponent):
    """The Slider component comtaining all slider parts."""

    tag = "Root"
    alias = "RadixSliderRoot"

    default_value: Var[List[int]]

    value: Var[List[int]]

    name: Var[str]

    disabled: Var[bool]

    orientation: Var[LiteralSliderOrientation]

    dir: Var[LiteralSliderDir]

    inverted: Var[bool]

    min: Var[int]

    max: Var[int]

    step: Var[int]

    min_steps_between_thumbs: Var[int]

    def get_event_triggers(self) -> Dict[str, Any]:
        """Event triggers for radix slider primitive.

        Returns:
            The triggers for event supported by radix primitives.
        """
        return {
            **super().get_event_triggers(),
            "on_value_change": lambda e0: [e0],  # trigger for all change of a thumb
            "on_value_commit": lambda e0: [e0],  # trigger when thumb is released
        }

    def _apply_theme(self, theme: Component):
        self.style = Style(
            {
                "position": "relative",
                "display": "flex",
                "align_items": "center",
                "user_select": "none",
                "touch_action": "none",
                "width": "200px",
                "height": "20px",
                "&[data-orientation='vertical']": {
                    "flex_direction": "column",
                    "width": "20px",
                    "height": "100px",
                },
                **self.style,
            }
        )


class SliderTrack(SliderComponent):
    """A Slider Track component."""

    tag = "Track"
    alias = "RadixSliderTrack"

    def _apply_theme(self, theme: Component):
        self.style = Style(
            {
                "position": "relative",
                "flex_grow": "1",
                "background_color": "black",
                "border_radius": "9999px",
                "height": "3px",
                "&[data-orientation='vertical']": {
                    "width": "3px",
                },
                **self.style,
            }
        )


class SliderRange(SliderComponent):
    """A SliderRange component."""

    tag = "Range"
    alias = "RadixSliderRange"

    def _apply_theme(self, theme: Component):
        self.style = Style(
            {
                "position": "absolute",
                "background_color": "white",
                "height": "100%",
                "&[data-orientation='vertical']": {
                    "width": "100%",
                },
                **self.style,
            }
        )


class SliderThumb(SliderComponent):
    """A SliderThumb component."""

    tag = "Thumb"
    alias = "RadixSliderThumb"

    def _apply_theme(self, theme: Component):
        self.style = Style(
            {
                "display": "block",
                "width": "20px",
                "height": "20px",
                "background_color": "black",
                "box_shadow": "0 2px 10px black",
                "border_radius": "10px",
                "&:hover": {
                    "background_color": "gray",
                },
                "&:focus": {
                    "outline": "none",
                    "box_shadow": "0 0 0 4px gray",
                },
                **self.style,
            }
        )


class Slider(SimpleNamespace):
    """High level API for slider."""

    root = staticmethod(SliderRoot.create)
    track = staticmethod(SliderTrack.create)
    range = staticmethod(SliderRange.create)
    thumb = staticmethod(SliderThumb.create)

    @staticmethod
    def __call__(**props) -> Component:
        """High level API for slider.

        Args:
            **props: The props of the slider.

        Returns:
            A slider component.
        """
        track = SliderTrack.create(SliderRange.create())
        # if default_value is not set, the thumbs will not render properly but the slider will still work
        if "default_value" in props:
            children = [
                track,
                *[SliderThumb.create() for _ in props.get("default_value", [])],
            ]
        else:
            children = [
                track,
                #     Foreach.create(props.get("value"), lambda e: SliderThumb.create()),  # foreach doesn't render Thumbs properly
            ]

        return SliderRoot.create(*children, **props)


slider = Slider()
