import logging
from dataclasses import field, dataclass
from datetime import datetime
from typing import Optional, Callable

from rio import Column, Component, event, TextStyle, Text, Spacer, PointerEvent, Button, Popup, Card, Row, Rectangle, Color, PointerEventListener

from src.ezgg_lan_manager import ConfigurationService, CateringService, SeatingService, AccountingService
from src.ezgg_lan_manager.components.CateringManagementOrderDisplay import CateringManagementOrderDisplay
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
from src.ezgg_lan_manager.types.CateringOrder import CateringOrder, CateringOrderStatus
from src.ezgg_lan_manager.types.Seat import Seat

logger = logging.getLogger(__name__.split(".")[-1])


class CateringOrderInfoPopup(Component):
    order: Optional[CateringOrder] = None
    close_cb: Optional[Callable] = None

    def build(self) -> Component:
        if not self.order:
            return Card(
                content=Text(""),
                margin=1,
                color=self.session.theme.hud_color,
                min_width=40,
                min_height=40,
                on_press=self.close_cb
            )
        rows = []
        is_contrast_line = True
        for item, amount in self.order.items.items():
            style = TextStyle(
                fill=self.session.theme.secondary_color if is_contrast_line else self.session.theme.neutral_color)
            is_contrast_line = not is_contrast_line
            rows.append(
                Row(
                    Text(f"{amount}x", style=style),
                    Spacer(),
                    Text(f"{item.name}", style=style)
                )
            )
        return Card(
            content=Column(
                Text(f"Bestellung {self.order.order_id}", style=TextStyle(font_size=1.2), margin_bottom=1),
                *rows,
                Spacer(),
                Row(Text("Gesamtpreis:"), Spacer(),
                    Text(self.session[AccountingService].make_euro_string_from_decimal(self.order.price)))
            ),
            margin=1,
            color=self.session.theme.hud_color,
            min_width=40,
            min_height=40,
            on_press=self.close_cb,
            corner_radius=0.5,
            elevate_on_hover=False,
            colorize_on_hover=False
        )


@dataclass
class CateringOrderWithSeat:
    catering_order: CateringOrder
    seat: Optional[Seat]


class ManageCateringPage(Component):
    all_orders: list[CateringOrderWithSeat] = field(default_factory=list)
    last_updated: Optional[datetime] = None
    order_popup_open: bool = False
    order_popup_order: Optional[CateringOrder] = None

    @event.on_populate
    async def on_populate(self) -> None:
        await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Catering Verwaltung")
        self.all_orders = await self.populate_seating(await self.session[CateringService].get_orders())
        self.last_updated = datetime.now()

    @event.periodic(30)
    async def update_orders(self) -> None:
        polled_orders = await self.session[CateringService].get_orders()
        self.all_orders = await self.populate_seating(polled_orders)
        self.last_updated = datetime.now()

    async def populate_seating(self, orders: list[CateringOrder]) -> list[CateringOrderWithSeat]:
        result = []
        for order in orders:
            seat = await self.session[SeatingService].get_user_seat(order.customer.user_id)
            result.append(CateringOrderWithSeat(catering_order=order, seat=seat))
        return result

    def get_all_pending_orders(self) -> list[CateringOrderWithSeat]:
        filtered_list = list(filter(lambda
                                        o: o.catering_order.status != CateringOrderStatus.COMPLETED and o.catering_order.status != CateringOrderStatus.CANCELED,
                                    self.all_orders))
        sorted_list = sorted(filtered_list, key=lambda o: o.catering_order.order_date)
        return sorted_list

    def get_all_completed_orders(self) -> list[CateringOrderWithSeat]:
        filtered_list = list(filter(lambda
                                        o: o.catering_order.status == CateringOrderStatus.COMPLETED or o.catering_order.status == CateringOrderStatus.CANCELED,
                                    self.all_orders))
        sorted_list = sorted(filtered_list, key=lambda o: o.catering_order.order_date)
        return sorted_list

    async def order_clicked(self, order: CateringOrder, _: PointerEvent) -> None:
        await self.update_orders()
        self.order_popup_order = order
        self.order_popup_open = True

    async def close_cb(self) -> None:
        self.order_popup_open = False

    def build(self) -> Component:
        header_text = Text(
            text="Catering Verwaltung",
            style=TextStyle(
                fill=self.session.theme.background_color,
                font_size=1.2
            ),
            margin_top=2,
            margin_bottom=1,
            align_x=0.5
        )
        popup = Popup(
            anchor=header_text,
            content=CateringOrderInfoPopup(order=self.order_popup_order, close_cb=self.close_cb),
            is_open=self.order_popup_open,
            position="bottom",
            corner_radius=0.5
        )
        return Column(
            MainViewContentBox(
                Column(
                    popup,
                    PointerEventListener(
                        content=Rectangle(
                            content=Text(text="Neue Bestellung anlegen", fill=Color.WHITE, justify="center", margin=0.3),
                            margin_bottom=1,
                            margin_right=5,
                            margin_left=5,
                            fill=self.session.theme.secondary_color,
                            hover_fill=self.session.theme.hud_color,
                            stroke_width=0.2,
                            stroke_color=Color.TRANSPARENT,
                            hover_stroke_width=0.2,
                            hover_stroke_color=self.session.theme.background_color,
                            cursor="pointer",
                            transition_time=0.1
                        ),
                        on_press=lambda _: self.session.navigate_to("new-pos-order")
                    )
                )
            ),
            MainViewContentBox(
                Column(
                    Text(
                        text="Offene Bestellungen",
                        style=TextStyle(
                            fill=self.session.theme.background_color,
                            font_size=1.2
                        ),
                        margin_top=2,
                        margin_bottom=0.2,
                        align_x=0.5
                    ),
                    Text(
                        text=f"Letzte Aktualisierung: {'-' if not self.last_updated else self.last_updated.strftime('%H:%M:%S')}",
                        style=TextStyle(
                            fill=self.session.theme.background_color,
                            font_size=0.7
                        ),
                        margin_top=0.2,
                        margin_bottom=0.2,
                        align_x=0.5
                    ),
                    Button(
                        content=Text("Jetzt aktualisieren", style=TextStyle(font_size=0.7), justify="center"),
                        shape="rectangle",
                        margin_bottom=1,
                        on_press=self.update_orders
                    ),
                    *[CateringManagementOrderDisplay(v.catering_order, v.seat, self.order_clicked) for v in
                      self.get_all_pending_orders()],
                )
            ),
            MainViewContentBox(
                Column(
                    Text(
                        text="Abgeschlossene Bestellungen",
                        style=TextStyle(
                            fill=self.session.theme.background_color,
                            font_size=1.2
                        ),
                        margin_top=2,
                        margin_bottom=0.2,
                        align_x=0.5
                    ),
                    *[CateringManagementOrderDisplay(v.catering_order, v.seat, self.order_clicked) for v in
                      self.get_all_completed_orders()],
                )
            ),
            Spacer()
        )
