from typing import final

from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton
from Movie import Movie
from Payment import Payment
from enum import Enum

class ShopItemType(Enum):
    """
    Enum dictating types of items that can be bought from the cinema.
    """
    Movie = 0
    Popcorn = 1
    FrozenCoke = 2
    LollyBag = 3

@final
class ShopItem:
    """
    Represents an item that can be bought from the cinema.
    """
    def __init__(self, shoptype: ShopItemType, quantity: int, movie: Movie | None = None):
        """
        Creates a new ShopItem.
        Throws:
            ValueError - type is ShopItemType.Movie, but movie is not provided as a paramater
        Example (creates a ShopItem with type popcorn and quantity 3):
            ShopItem(ShopItemType.Popcorn, 3)
        """
        self.type = shoptype
        self.movie = movie
        self.quantity = quantity
        self.cost: float
        match shoptype:
            case ShopItemType.Movie:
                if movie is not None:
                    self.cost = movie.price
                    self.movie = movie
                else:
                    raise ValueError("ShopItem with type ShopItemType.Movie must provide a movie as an argument")
            case ShopItemType.Popcorn:
                self.cost = 8.50
            case ShopItemType.FrozenCoke:
                self.cost = 4.50
            case ShopItemType.LollyBag:
                self.cost = 3.50

    def __repr__(self):
        return f"ShopItem(type={self.type}, movie={self.movie}, quantity={self.quantity}, cost={self.cost})"

    def total(self):
        return self.cost * self.quantity

@final
class Cart:
    """
    Holds all the items that the user wants to buy from the cinema.
    """

    cv: CartView | None = None

    def __init__(self):
        self.contents: list[ShopItem] = []

    def __repr__(self):
        return f"Cart(contents={self.contents})"

    def addItem(self, item: ShopItem):
        self.contents.append(item)
        pass

    def show(self):
        self.cv = CartView()
        self.cv.show()

    def total(self) -> float:
        return sum(item.total() for item in self.contents)

cart = Cart()

class CartView(QWidget):
    """
    View to show the contents of the cart, and allow the user to checkout.
    """

    payment: Payment | None = None

    def __init__(self):
        super().__init__()
        global cart

        self.setWindowTitle("Your Cart")
        layout = QVBoxLayout()

        if len(cart.contents) == 0:
            layout.addWidget(QLabel("Your cart is empty!"))
            layout.addWidget(QLabel("Close this window to pick a movie!"))
        else:
            for item in cart.contents:
                layout.addWidget(QLabel(f"{item.quantity}x {item.type.name} - ${item.total():.2f}"))
            button = QPushButton("Checkout")
            button.clicked.connect(self.showPayment)
            layout.addWidget(button)

        self.setLayout(layout)

    def showPayment(self):
        self.payment = Payment(cart)
        self.payment.show()
        self.close()
