from functools import partial

from rio import Component, Text, Icon, TextStyle, Rectangle, Spacer, Color, PointerEventListener, Column, Row, PointerEvent, Tooltip
from typing import Optional, Callable, Literal

from src.ezgg_lan_manager.types.Seat import Seat
from src.ezgg_lan_manager.types.UserSession import UserSession


class SeatPixel(Component):
    seat_id: str
    on_press_cb: Callable
    seat: Seat
    seat_orientation: Literal["top", "bottom"]

    def determine_color(self) -> Color:
        try:
            user_id = self.session[UserSession].user_id
        except KeyError:
            user_id = None
        if self.seat.user is not None and self.seat.user.user_id == user_id:
            return Color.from_hex("800080")
        elif self.seat.is_blocked or self.seat.user is not None:
            return self.session.theme.danger_color
        return self.session.theme.success_color

    def build(self) -> Component:
        text = Text(f"{self.seat_id}", style=TextStyle(fill=self.session.theme.primary_color, font_size=0.9), align_x=0.5, selectable=False)
        rec = Rectangle(
            content=Row(text),
            min_width=1,
            min_height=1,
            fill=self.determine_color(),
            stroke_width=0.1,
            hover_stroke_width=0.1,
            stroke_color=Color.from_hex("003300") if self.seat.category == "NORMAL" else Color.from_hex("66ff99"),
            grow_x=True,
            grow_y=True,
            hover_fill=self.session.theme.hud_color,
            transition_time=0.4,
            ripple=True
        )

        if self.seat.user or self.seat.is_blocked:
            return PointerEventListener(
                content=Tooltip(
                    anchor=rec,
                    tip=self.seat.user.user_name if self.seat.user else "Gesperrt",
                    position=self.seat_orientation,
                ),
                on_press=partial(self.on_press_cb, self.seat_id),
            )
        else:
            return PointerEventListener(
                content=rec,
                on_press=partial(self.on_press_cb, self.seat_id),
            )


class TextPixel(Component):
    text: Optional[str] = None
    icon_name: Optional[str] = None
    no_outline: bool = False

    def build(self) -> Component:
        if self.text is not None:
            content = Text(self.text, style=TextStyle(fill=self.session.theme.neutral_color, font_size=1), align_x=0.5, selectable=False)
        elif self.icon_name is not None:
            content = Icon(self.icon_name, fill=self.session.theme.neutral_color)
        else:
            content = None
        return Rectangle(
            content=content,
            min_width=1,
            min_height=1,
            fill=self.session.theme.primary_color,
            stroke_width=0.0 if self.no_outline else 0.1,
            stroke_color=self.session.theme.neutral_color,
            hover_stroke_width=None if self.no_outline else 0.1,
            grow_x=True,
            grow_y=True,
            hover_fill=None,
            ripple=True
        )


class WallPixel(Component):
    def build(self) -> Component:
        return Rectangle(
            min_width=1,
            min_height=1,
            fill=Color.from_hex("434343"),
            grow_x=True,
            grow_y=True,
        )


class DebugPixel(Component):
    def build(self) -> Component:
        return Rectangle(
            content=Spacer(),
            min_width=1,
            min_height=1,
            fill=self.session.theme.success_color,
            hover_stroke_color=self.session.theme.hud_color,
            hover_stroke_width=0.1,
            grow_x=True,
            grow_y=True,
            hover_fill=self.session.theme.secondary_color,
            transition_time=0.1
        )


class InvisiblePixel(Component):
    def build(self) -> Component:
        return Rectangle(
            content=Spacer(),
            min_width=1,
            min_height=1,
            fill=self.session.theme.primary_color,
            hover_stroke_width=0.0,
            grow_x=True,
            grow_y=True
        )
