import logging
from asyncio import create_task, sleep
from functools import partial
from typing import Optional, Callable

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

from src.ezgg_lan_manager import ReceiptPrintingService
from src.ezgg_lan_manager.components.StatusChangePopup import StatusChangePopup
from src.ezgg_lan_manager.services.CateringService import CateringService
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 CateringManagementOrderDisplay(Component):
    order: CateringOrder
    seat: Optional[Seat]
    clicked_cb: Callable
    status_change_popup_open: bool = False

    def reprint_order(self) -> None:
        create_task(self.session[ReceiptPrintingService].print_order(self.order.customer, self.order))

    def open_status_change_popup(self) -> None:
        self.status_change_popup_open = True

    def format_order_status(self, status: CateringOrderStatus) -> Text:
        status_text = CateringOrder.translate_order_status(status)

        color = self.session.theme.warning_color
        if status == CateringOrderStatus.DELAYED or status == CateringOrderStatus.CANCELED:
            color = self.session.theme.danger_color
        elif status == CateringOrderStatus.COMPLETED:
            color = self.session.theme.success_color

        return Text(text=status_text, style=TextStyle(fill=color))

    async def change_status(self, new_status: CateringOrderStatus) -> Optional[str]:
        await sleep(1)

        logger.debug(f"Status of order with ID {self.order.order_id} changing from {self.order.status} to {new_status}")
        if self.order.status == CateringOrderStatus.CANCELED:  # Can not un-cancel
            return "Stornierte Bestellungen können nicht angepasst werden"

        if self.order.status != new_status:
            if new_status == CateringOrderStatus.CANCELED:
                success = await self.session[CateringService].cancel_order(self.order)
            else:
                success = await self.session[CateringService].update_order_status(self.order.order_id, new_status)

            if success:
                self.order = CateringOrder(
                    order_id=self.order.order_id,
                    order_date=self.order.order_date,
                    status=new_status,
                    items=self.order.items,
                    customer=self.order.customer,
                    is_delivery=self.order.is_delivery
                )

        self.status_change_popup_open = False


    def build(self) -> Component:
        card = Card(
            content=Column(
                Row(
                    Text(f"ID: {self.order.order_id}", margin_left=0.3, margin_top=0.2, justify="center", style=TextStyle(font_size=1.2)),
                ),
                Row(
                    Text(f"Status: ", margin_left=0.3, margin_top=0.2),
                    self.format_order_status(self.order.status),
                    Spacer(),
                    Text(self.order.order_date.strftime("%d.%m. - %H:%M Uhr"), margin_right=0.3),
                ),
                Row(
                    Text(f"Gast: {self.order.customer.user_name}", margin_left=0.3),
                    Spacer(),
                    Text(f"Sitzplatz: {'-' if not self.seat else self.seat.seat_id}", margin_right=0.3),
                ),
                Row(
                    Text("Diese Bestellung wird:", margin_left=0.3, margin_bottom=0.5),
                    Spacer(),
                    Text("Geliefert" if self.order.is_delivery else "Abgeholt", margin_right=0.3, margin_bottom=0.5),
                ),
                Row(
                    Rectangle(
                        content=Button(
                            content=Text("Beleg drucken", justify="left"),
                            shape="rectangle",
                            on_press=self.reprint_order
                        ),
                        stroke_width=0.1
                    ),
                    Rectangle(
                        content=Button(
                            content=Text("Status ändern", justify="right"),
                            shape="rectangle",
                            on_press=self.open_status_change_popup
                        ),
                        stroke_width=0.1
                    ),
                )
            ),
            color=self.session.theme.hud_color,
            colorize_on_hover=True,
            margin=1
        )

        status_change_popup = StatusChangePopup(card, self.status_change_popup_open, self.change_status)

        return PointerEventListener(
            content=status_change_popup,
            on_press=partial(self.clicked_cb, self.order)
        )