from typing import Optional

from rio import Text, Column, TextStyle, Component, event, Button, Popup

from src.ezgg_lan_manager import ConfigurationService, UserService, TicketingService, RefreshService
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
from src.ezgg_lan_manager.components.TicketBuyCard import TicketBuyCard
from src.ezgg_lan_manager.services.AccountingService import InsufficientFundsError
from src.ezgg_lan_manager.services.TicketingService import TicketNotAvailableError, UserAlreadyHasTicketError
from src.ezgg_lan_manager.types.Ticket import Ticket
from src.ezgg_lan_manager.types.User import User
from src.ezgg_lan_manager.types.UserSession import UserSession


class BuyTicketPage(Component):
    user: Optional[User] = None
    user_ticket: Optional[Ticket] = None
    is_popup_open: bool = False
    popup_message: str = ""
    is_popup_success: bool = False
    is_buying_enabled: bool = False
    is_user_logged_in: bool = False

    @event.on_populate
    async def on_populate(self) -> None:
        self.session[RefreshService].subscribe(self.on_populate)
        await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Ticket kaufen")
        try:
            user_id = self.session[UserSession].user_id
        except KeyError:
            self.user = None
        else:
            self.user = await self.session[UserService].get_user(user_id)
        if self.user is None:  # No user logged in
            self.is_buying_enabled = False
            self.is_user_logged_in = False
            self.user_ticket = None
        else:  # User is logged in
            self.is_user_logged_in = True
            possible_ticket = await self.session[TicketingService].get_user_ticket(self.user.user_id)
            self.user_ticket = possible_ticket
            if possible_ticket is not None:  # User already has a ticket
                self.is_buying_enabled = False
            else:
                self.is_buying_enabled = True

    async def on_buy_pressed(self, category: str) -> None:
        if not self.user:
            return
        self.is_buying_enabled = False
        self.force_refresh()

        try:
            t_s = self.session[TicketingService]
            ticket = await t_s.purchase_ticket(self.user.user_id, category)
            self.popup_message = f"Ticket erfolgreich gekauft. Deine Ticket-ID lautet: {ticket.ticket_id}."
            self.is_popup_success = True
        except TicketNotAvailableError:
            self.popup_message = "Das ausgewählte Ticket ist nicht verfügbar."
            self.is_popup_success = False
        except InsufficientFundsError:
            self.popup_message = "Dein Guthaben reicht nicht aus um dieses Ticket zu kaufen."
            self.is_popup_success = False
        except UserAlreadyHasTicketError:
            self.popup_message = (f"Du besitzt bereits ein Ticket. Um dein aktuelles Ticket zu stornieren, kontaktiere bitte den Support unter "
                                  f"{self.session[ConfigurationService].get_lan_info().organizer_mail}.")
            self.is_popup_success = False
        except RuntimeError:
            self.popup_message = "Ein unbekannter Fehler ist aufgetreten."
            self.is_popup_success = False
        self.is_popup_open = True
        await self.on_populate()

    async def on_popup_close_pressed(self) -> None:
        self.is_popup_open = False
        self.popup_message = ""

    def build(self) -> Component:
        ticket_infos = self.session[ConfigurationService].get_ticket_info()
        header = Column(
            Text(
                "Tickets & Preise",
                style=TextStyle(
                    fill=self.session.theme.background_color,
                    font_size=1.2
                ),
                margin_top=2,
                align_x=0.5
            ),
            spacing=0.2
        )

        if not self.is_user_logged_in:
            header.add(Text(
                "Du musst eingeloggt sein\num ein Ticket zu kaufen",
                style=TextStyle(
                    fill=self.session.theme.background_color,
                    font_size=0.6
                ),
                align_x=0.5
            ))

        return Column(
            MainViewContentBox(
                Column(
                    header,
                    Popup(
                        anchor=header,
                        content=Column(
                            Text(
                                self.popup_message,
                                style=TextStyle(font_size=1.1, fill=self.session.theme.success_color if self.is_popup_success else self.session.theme.danger_color),
                                overflow="wrap",
                                grow_y=True,
                                margin=1
                            ),
                            Button("Bestätigen", shape="rounded", grow_y=False, on_press=self.on_popup_close_pressed),
                            min_width=34,
                            min_height=10
                        ),
                        is_open=self.is_popup_open,
                        position="bottom",
                        margin=1,
                        corner_radius=0.2,
                        color=self.session.theme.primary_color
                    ),
                    *[TicketBuyCard(
                        description=t.description,
                        additional_info=t.additional_info,
                        price=t.price,
                        category=t.category,
                        pressed_cb=self.on_buy_pressed,
                        is_enabled=self.is_buying_enabled,
                        total_tickets=t.total_tickets,
                        user_ticket=self.user_ticket
                    ) for t in ticket_infos]
                ),
            ),
            align_y=0
        )
