def shopping(product_type, customer_type):
    match product_type:
        case "book":
            match customer_type:
                case "student":
                    print("buy, comment, maybe refund")
                case "teacher":
                    print("buy, comment, maybe refund")
            print("do a lot of things")
        case "ticket":
            match customer_type:
                case "VIP":
                    print("prebook, buy, maybe refund")
                case "non-VIP":
                    print("prebook, buy, maybe refund")
        case _:
            raise Exception("Invalid product type customer type")


class BuyBook:
    def buy(self):
        print("default buy book")

    def comment(self):
        print("default comment book")

    def refund(self):
        print("default refund book")


class StudentBuyBookProcess:
    def query(self):
        print("student buy book query")

    def pay(self):
        print("student buy book pay")


class StudentBuyBook(BuyBook):
    buyProcess = StudentBuyBookProcess

    def buy(self):
        self.buyProcess.query()
        self.buyProcess.pay()
        print("student buy book")


class TeacherBuyBook(BuyBook):
    def comment(self):
        print("teacher comment book")


class BuyTicket:
    def prebook(self):
        print("default prebook ticket")

    def buy(self):
        print("default buy ticket")

    def refund(self):
        print("default refund ticket")


class VIPBuyTicket(BuyTicket):
    def buy(self):
        print("VIP buy ticket")


class NonVIPBuyTicket(BuyTicket):
    def refund(self):
        print("non-VIP refund ticket")


class BetterShopping:
    mapping = {
        "book": {
            "student": StudentBuyBook,
            "teacher": TeacherBuyBook,
        },
        "ticket": {
            "VIP": VIPBuyTicket,
            "non-VIP": NonVIPBuyTicket,
        },
    }

    def dispatch(self, product_type, customer_type):
        handler = self.mapping[product_type][customer_type]()
        match product_type:
            case "book":
                handler.buy()
                handler.comment()
                handler.refund()
            case "ticket":
                handler.prebook()
                handler.buy()
                handler.refund()
