import pygame
import random
import sys
import math

# ========== INIT ==========
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("🐱 Top-Down Cat Café ☕")
clock = pygame.time.Clock()

# ========== COLOR PALETTE ==========
FLOOR        = (248, 235, 215)
WALL_TOP     = (235, 210, 180)
WALL_BOTTOM  = (200, 175, 150)
TABLE        = (170, 130, 90)
TABLE_DARK   = (130, 95, 60)
COUNTER      = (200, 160, 120)
COUNTER_DARK = (150, 110, 80)
MACHINE      = (160, 160, 160)
MACHINE_DARK = (100, 100, 100)
RED          = (220, 80, 80)
GREEN        = (100, 200, 100)
WHITE        = (255, 255, 255)
BLACK        = (50, 40, 30)
GOLD         = (255, 210, 80)
MINT         = (170, 230, 200)
BROWN        = (130, 90, 60)
SKY_BLUE     = (170, 210, 240)
ROSE         = (255, 180, 180)

# ========== FONTS ==========
font_tiny   = pygame.font.Font(None, 18)
font_small  = pygame.font.Font(None, 22)
font_med    = pygame.font.Font(None, 30)
font_large  = pygame.font.Font(None, 46)

# ========== COFFEE MENU ==========
menu_items = [
    {"name": "Espresso",   "icon": "☕", "price": 3},
    {"name": "Latte",      "icon": "🥛", "price": 5},
    {"name": "Mocha",      "icon": "🍫", "price": 7},
    {"name": "Catpuccino", "icon": "🐾", "price": 10},
]

# ========== DECORATIONS ==========
decorations = [
    {"name": "Rug",          "cost": 30,  "owned": True},
    {"name": "Cat Tree",     "cost": 50,  "owned": False},
    {"name": "Fairy Lights", "cost": 40,  "owned": False},
    {"name": "Plant Corner", "cost": 60,  "owned": False},
]

# ========== CATS DATA ==========
cat_data_list = [
    {"name": "Mocha",   "color": (180, 130, 100), "tip": 1, "owned": True},
    {"name": "Latte",   "color": (220, 200, 160), "tip": 2, "owned": False},
    {"name": "Chai",    "color": (200, 160, 120), "tip": 3, "owned": False},
    {"name": "Cinnamon", "color": (240, 140, 80), "tip": 4, "owned": False},
    {"name": "Marshmallow", "color": (255, 240, 220), "tip": 5, "owned": False},
]

# ========== EFFECTS ==========
class FloatText:
    def __init__(self, x, y, text, color=GOLD):
        self.x = x
        self.y = y
        self.text = text
        self.color = color
        self.life = 40
        self.vy = -1.5

    def update(self):
        self.y += self.vy
        self.life -= 1

    def draw(self, surface):
        alpha = min(255, self.life * 10)
        surf = font_small.render(self.text, True, self.color)
        surf.set_alpha(alpha)
        surface.blit(surf, (self.x - surf.get_width()//2, self.y))

class HeartParticle:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.vx = random.uniform(-1, 1)
        self.vy = random.uniform(-2, -0.5)
        self.life = 30

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.life -= 1

    def draw(self, surface):
        if self.life > 0:
            alpha = min(255, self.life * 15)
            # tiny heart
            pts = [
                (self.x, self.y + 2),
                (self.x - 2, self.y),
                (self.x - 4, self.y + 2),
                (self.x - 2, self.y + 4),
                (self.x, self.y + 6),
                (self.x + 2, self.y + 4),
                (self.x + 4, self.y + 2),
                (self.x + 2, self.y),
            ]
            surf = pygame.Surface((8, 8), pygame.SRCALPHA)
            pygame.draw.polygon(surf, (255, 100, 100, alpha), pts)
            surface.blit(surf, (self.x - 4, self.y - 2))

# ========== CUSTOMER ==========
class Customer:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.order = random.choice(menu_items[:3])
        self.wait = 0
        self.max_wait = random.randint(400, 700)
        self.served = False
        self.leaving = False
        self.order_taken = False
        self.coffee_ready = False

    def update(self):
        self.wait += 1
        if self.wait > self.max_wait and not self.served:
            self.leaving = True

    def draw(self, surface):
        if self.leaving: return
        # Shadow
        pygame.draw.ellipse(surface, (0,0,0,50), (self.x-12, self.y+5, 24, 6))
        # Body
        body_color = (255, 220, 180) if not self.served else (210, 240, 210)
        pygame.draw.circle(surface, body_color, (self.x, self.y), 15)
        pygame.draw.circle(surface, BLACK, (self.x, self.y), 15, 2)
        # Eyes
        pygame.draw.circle(surface, BLACK, (self.x-5, self.y-3), 3)
        pygame.draw.circle(surface, BLACK, (self.x+5, self.y-3), 3)
        # Mouth
        if self.served:
            pygame.draw.arc(surface, BLACK, (self.x-5, self.y+2, 10, 6), 0, math.pi, 2)
        # Order bubble
        if self.order_taken and not self.served:
            bx, by = self.x-16, self.y-42
            pygame.draw.rect(surface, WHITE, (bx, by, 32, 32), border_radius=10)
            pygame.draw.rect(surface, BLACK, (bx, by, 32, 32), 2, border_radius=10)
            icon = font_med.render(self.order["icon"], True, BLACK)
            surface.blit(icon, (bx+4, by+2))
        elif not self.order_taken and not self.served:
            bx, by = self.x-16, self.y-42
            pygame.draw.rect(surface, WHITE, (bx, by, 32, 32), border_radius=10)
            pygame.draw.rect(surface, BLACK, (bx, by, 32, 32), 2, border_radius=10)
            qm = font_med.render("?", True, BLACK)
            surface.blit(qm, (bx+6, by+2))
        # Patience bar
        if not self.served:
            bar_w = 24
            bar_x = self.x - bar_w//2
            bar_y = self.y - 32
            fill = max(0, (self.max_wait - self.wait) / self.max_wait)
            pygame.draw.rect(surface, RED, (bar_x, bar_y, bar_w, 4))
            pygame.draw.rect(surface, GREEN, (bar_x, bar_y, bar_w * fill, 4))

# ========== CAT (TOP-DOWN, DETAILED) ==========
class Cat:
    def __init__(self, x, y, data):
        self.x = x
        self.y = y
        self.data = data
        self.state = "sit"   # sit, walk, sleep, groom
        self.dir = random.choice([-1, 1])
        self.timer = 0
        self.anim_frame = 0

    def update(self):
        self.timer += 1
        if random.random() < 0.01:
            self.state = random.choice(["sit", "walk", "sleep", "groom"])
            if self.state == "walk":
                self.dir = random.choice([-1, 1])

        if self.state == "walk":
            self.x += self.dir * 0.7
            if self.x < 130 or self.x > 670:
                self.dir *= -1
            if random.random() < 0.02:
                self.state = "sit"
        elif self.state == "groom":
            self.anim_frame = (self.anim_frame + 1) % 20
            if random.random() < 0.05:
                self.state = "sit"
        elif self.state == "sleep":
            self.anim_frame = (self.anim_frame + 1) % 30
        else:
            self.anim_frame = 0

    def draw(self, surface):
        color = self.data["color"]
        # Shadow
        shadow_alpha = 40
        if self.state == "sleep":
            pygame.draw.ellipse(surface, (0,0,0,shadow_alpha), (self.x-14, self.y+1, 28, 8))
        else:
            pygame.draw.ellipse(surface, (0,0,0,shadow_alpha), (self.x-10, self.y+8, 20, 6))

        if self.state == "sleep":
            # Sleeping body with breathing animation
            breath = math.sin(self.anim_frame * 0.3) * 2
            body_rect = pygame.Rect(self.x-14, self.y-4 - breath//2, 28, 12 + breath)
            pygame.draw.ellipse(surface, color, body_rect)
            head_pos = (self.x-12, self.y-7)
            pygame.draw.circle(surface, color, head_pos, 8)
            # Closed eyes
            eye_x = head_pos[0] + 2
            eye_y = head_pos[1] - 1
            pygame.draw.line(surface, BLACK, (eye_x-3, eye_y), (eye_x-1, eye_y+2), 2)
            pygame.draw.line(surface, BLACK, (eye_x+1, eye_y), (eye_x+3, eye_y+2), 2)
        elif self.state == "groom":
            # Sitting and licking paw
            pygame.draw.circle(surface, color, (self.x, self.y), 10)
            pygame.draw.circle(surface, color, (self.x, self.y-7), 9)
            # Ears
            ear_color = color
            pygame.draw.polygon(surface, ear_color, [(self.x-7, self.y-14), (self.x-3, self.y-9), (self.x-9, self.y-9)])
            pygame.draw.polygon(surface, ear_color, [(self.x+7, self.y-14), (self.x+3, self.y-9), (self.x+9, self.y-9)])
            # Eyes half closed
            eye_y = self.y - 8
            pygame.draw.circle(surface, WHITE, (self.x-4, eye_y), 3)
            pygame.draw.circle(surface, WHITE, (self.x+4, eye_y), 3)
            pygame.draw.circle(surface, BLACK, (self.x-4, eye_y), 2)
            pygame.draw.circle(surface, BLACK, (self.x+4, eye_y), 2)
            # Paw near mouth
            paw_x = self.x + 6
            paw_y = self.y - 4
            pygame.draw.circle(surface, color, (paw_x, paw_y), 4)
        else:  # sit / walk
            body = pygame.draw.circle(surface, color, (self.x, self.y), 10)
            head = pygame.draw.circle(surface, color, (self.x, self.y-7), 9)
            # Ears
            pygame.draw.polygon(surface, color, [(self.x-7, self.y-14), (self.x-3, self.y-9), (self.x-9, self.y-9)])
            pygame.draw.polygon(surface, color, [(self.x+7, self.y-14), (self.x+3, self.y-9), (self.x+9, self.y-9)])
            # Eyes
            eye_y = self.y - 8
            pygame.draw.circle(surface, WHITE, (self.x-4, eye_y), 3)
            pygame.draw.circle(surface, WHITE, (self.x+4, eye_y), 3)
            pygame.draw.circle(surface, BLACK, (self.x-4, eye_y), 1.5)
            pygame.draw.circle(surface, BLACK, (self.x+4, eye_y), 1.5)
            # Nose
            pygame.draw.circle(surface, (255, 150, 150), (self.x, eye_y+2), 1.5)
            # Tail
            tail_x = self.x + (10 if self.dir > 0 else -10)
            tail_y = self.y + 2
            pygame.draw.line(surface, color, (self.x, self.y+5), (tail_x, tail_y-5), 4)

# ========== MAIN GAME ==========
class CatCafeTopDown:
    def __init__(self):
        self.state = "menu"
        self.gold = 50
        self.day = 1
        self.reputation = 0
        self.customers = []
        self.spawn_timer = 0
        self.max_customers = 3
        self.served_today = 0
        self.target_served = 3

        self.cats = [Cat(random.randint(200,600), random.randint(200,400), cat_data_list[0])]
        self.coffee_queue = []
        self.brew_progress = 0

        self.msg = ""
        self.msg_timer = 0
        self.float_texts = []
        self.hearts = []

        # Buttons
        self.btn_play = pygame.Rect(WIDTH//2-60, 300, 120, 50)
        self.btn_shop = pygame.Rect(20, 70, 80, 40)
        self.btn_back = pygame.Rect(20, 70, 80, 40)
        self.machine_rect = pygame.Rect(60, HEIGHT-90, 100, 60)

    # ---------- SPAWN ----------
    def spawn_customer(self):
        if len(self.customers) < self.max_customers:
            x = random.randint(180, 620)
            y = random.randint(180, 350)
            self.customers.append(Customer(x, y))

    # ---------- CLICK HANDLING ----------
    def handle_click(self, pos):
        if self.state == "menu":
            if self.btn_play.collidepoint(pos):
                self.state = "playing"
                self.next_day()
            return

        if self.state == "shop":
            if self.btn_back.collidepoint(pos):
                self.state = "playing"
                return
            self.buy_item(pos)
            return

        if self.btn_shop.collidepoint(pos):
            self.state = "shop"
            return

        # Coffee machine
        if self.machine_rect.collidepoint(pos) and len(self.coffee_queue) > 0:
            if self.brew_progress <= 0:
                self.brew_progress = 1
            return

        # Customers
        for cust in self.customers:
            if (cust.x - pos[0])**2 + (cust.y - pos[1])**2 < 20**2:
                if not cust.order_taken and not cust.served and not cust.leaving:
                    cust.order_taken = True
                    self.coffee_queue.append(cust)
                    self.msg = f"Order: {cust.order['name']}"
                    self.msg_timer = 50
                    return
                elif cust.order_taken and not cust.served and not cust.leaving and cust.coffee_ready:
                    cust.served = True
                    self.gold += cust.order["price"]
                    self.reputation += 1
                    self.served_today += 1
                    self.msg = f"+{cust.order['price']} gold! ☕"
                    self.msg_timer = 50
                    # Float text
                    self.float_texts.append(FloatText(cust.x, cust.y-20, f"+{cust.order['price']}", GOLD))
                    # Hearts
                    for _ in range(5):
                        self.hearts.append(HeartParticle(cust.x, cust.y-20))
                    if cust in self.coffee_queue:
                        self.coffee_queue.remove(cust)
                    return

        # Cats
        for cat in self.cats:
            if (cat.x - pos[0])**2 + (cat.y - pos[1])**2 < 18**2:
                self.gold += cat.data["tip"]
                self.msg = f"Pet {cat.data['name']}! +{cat.data['tip']}"
                self.msg_timer = 45
                self.float_texts.append(FloatText(cat.x, cat.y-20, f"+{cat.data['tip']}", (255, 200, 100)))
                return

    # ---------- SHOP ----------
    def buy_item(self, pos):
        y = 150
        for dec in decorations:
            rect = pygame.Rect(100, y, 320, 45)
            if rect.collidepoint(pos) and self.gold >= dec["cost"] and not dec["owned"]:
                dec["owned"] = True
                self.gold -= dec["cost"]
                self.msg = f"Bought {dec['name']}!"
                self.msg_timer = 60
            y += 55
        y += 20
        for cd in cat_data_list:
            if not cd["owned"]:
                cost = cd["tip"] * 15
                rect = pygame.Rect(100, y, 320, 45)
                if rect.collidepoint(pos) and self.gold >= cost:
                    cd["owned"] = True
                    self.gold -= cost
                    new_cat = Cat(random.randint(200,600), random.randint(200,400), cd)
                    self.cats.append(new_cat)
                    self.msg = f"Adopted {cd['name']}!"
                    self.msg_timer = 60
                y += 55

    # ---------- DAY ----------
    def next_day(self):
        self.day += 1
        self.customers.clear()
        self.coffee_queue.clear()
        self.brew_progress = 0
        self.served_today = 0
        self.spawn_timer = 0
        self.max_customers = 3 + min(self.reputation//3, 4)
        self.msg = f"☀️ Day {self.day} begins!"
        self.msg_timer = 70
        if self.day % 3 == 0:
            locked = [d for d in cat_data_list if not d["owned"]]
            if locked:
                new_data = random.choice(locked)
                new_data["owned"] = True
                self.cats.append(Cat(random.randint(200,600), random.randint(200,400), new_data))
                self.msg = f"{new_data['name']} joined! 🐱"
                self.msg_timer = 80

    # ---------- UPDATE ----------
    def update(self):
        if self.state != "playing": return

        self.spawn_timer += 1
        if self.spawn_timer > random.randint(120, 300):
            self.spawn_timer = 0
            self.spawn_customer()

        if self.brew_progress > 0:
            self.brew_progress += 2
            if self.brew_progress >= 100:
                if self.coffee_queue:
                    self.coffee_queue[0].coffee_ready = True
                    self.msg = f"{self.coffee_queue[0].order['name']} ready!"
                    self.msg_timer = 50
                self.brew_progress = 0

        for cust in self.customers[:]:
            cust.update()
            if cust.leaving:
                if cust in self.coffee_queue:
                    self.coffee_queue.remove(cust)
                self.customers.remove(cust)
            elif cust.served and cust.wait > cust.max_wait + 50:
                self.customers.remove(cust)

        for cat in self.cats:
            cat.update()

        # Effects
        for ft in self.float_texts[:]:
            ft.update()
            if ft.life <= 0:
                self.float_texts.remove(ft)
        for h in self.hearts[:]:
            h.update()
            if h.life <= 0:
                self.hearts.remove(h)

        if len(self.customers) == 0 and self.served_today >= self.target_served:
            self.next_day()

        if self.msg_timer > 0:
            self.msg_timer -= 1
        else:
            self.msg = ""

    # ---------- DRAWING ----------
    def draw_background(self):
        # Gradient floor
        for y in range(0, HEIGHT):
            ratio = y / HEIGHT
            r = int(248 - 10*ratio)
            g = int(235 - 15*ratio)
            b = int(215 - 20*ratio)
            pygame.draw.line(screen, (r, g, b), (0, y), (WIDTH, y))

        # Walls with shadow
        wall_color = WALL_TOP
        pygame.draw.rect(screen, wall_color, (0, 0, WIDTH, 25))
        pygame.draw.rect(screen, WALL_BOTTOM, (0, 25, WIDTH, 5))
        pygame.draw.rect(screen, wall_color, (0, HEIGHT-25, WIDTH, 25))
        pygame.draw.rect(screen, WALL_BOTTOM, (0, HEIGHT-30, WIDTH, 5))
        pygame.draw.rect(screen, wall_color, (0, 0, 25, HEIGHT))
        pygame.draw.rect(screen, WALL_BOTTOM, (25, 0, 5, HEIGHT))
        pygame.draw.rect(screen, wall_color, (WIDTH-25, 0, 25, HEIGHT))
        pygame.draw.rect(screen, WALL_BOTTOM, (WIDTH-30, 0, 5, HEIGHT))

        # Tables with shadow
        for tx, ty in [(220, 200), (550, 220), (350, 380), (600, 420)]:
            pygame.draw.circle(screen, (0,0,0,30), (tx+2, ty+2), 32)
            pygame.draw.circle(screen, TABLE, (tx, ty), 32)
            pygame.draw.circle(screen, TABLE_DARK, (tx, ty), 32, 3)

        # Counter & machine
        counter_rect = pygame.Rect(40, HEIGHT-100, 120, 70)
        pygame.draw.rect(screen, COUNTER, counter_rect, border_radius=8)
        pygame.draw.rect(screen, COUNTER_DARK, counter_rect, 3, border_radius=8)
        machine_rect = pygame.Rect(70, HEIGHT-85, 40, 35)
        pygame.draw.rect(screen, MACHINE, machine_rect, border_radius=5)
        pygame.draw.rect(screen, MACHINE_DARK, machine_rect, 2, border_radius=5)
        # steam
        if self.brew_progress > 0 and self.brew_progress < 90:
            steam_x = 90
            steam_y = HEIGHT-90
            for i in range(3):
                offset = math.sin(pygame.time.get_ticks()*0.01 + i) * 3
                pygame.draw.circle(screen, (200,200,200, 150), (steam_x + offset, steam_y - i*4), 4)

        # Progress bar
        if self.brew_progress > 0:
            bar_rect = pygame.Rect(55, HEIGHT-105, 90, 8)
            pygame.draw.rect(screen, (200,200,200), bar_rect, border_radius=4)
            fill_w = int(90 * self.brew_progress / 100)
            pygame.draw.rect(screen, GOLD, (55, HEIGHT-105, fill_w, 8), border_radius=4)

        # Decorations
        if decorations[0]["owned"]:
            rug_rect = pygame.Rect(270, 440, 260, 70)
            pygame.draw.ellipse(screen, (220, 240, 210), rug_rect)
            pygame.draw.ellipse(screen, (180, 210, 180), rug_rect, 2)
        if decorations[1]["owned"]:
            pygame.draw.rect(screen, (130, 90, 60), (640, 360, 50, 100), border_radius=6)
            pygame.draw.ellipse(screen, (80, 150, 80), (625, 345, 80, 40))
            pygame.draw.ellipse(screen, (50, 100, 50), (625, 345, 80, 40), 2)
        if decorations[2]["owned"]:
            for i in range(30, WIDTH, 60):
                pygame.draw.circle(screen, (255, 240, 150), (i, 22), 5)
                pygame.draw.line(screen, (255, 240, 150), (i, 22), (i, 32), 2)
        if decorations[3]["owned"]:
            for px, py in [(140, 160), (680, 180)]:
                pygame.draw.circle(screen, (40, 100, 40), (px, py+2), 16)
                pygame.draw.circle(screen, (70, 140, 70), (px, py), 16)
                pygame.draw.circle(screen, (30, 70, 30), (px, py), 12)

    def draw_ui(self):
        panel = pygame.Surface((WIDTH, 60), pygame.SRCALPHA)
        panel.fill((255, 248, 240, 220))
        screen.blit(panel, (0, 25))
        gold_t = font_med.render(f"Gold: {self.gold}", True, BLACK)
        screen.blit(gold_t, (WIDTH-150, 28))
        day_t = font_med.render(f"Day {self.day}", True, BLACK)
        screen.blit(day_t, (WIDTH//2-40, 28))
        rep_t = font_small.render(f"Rep: {self.reputation}", True, BLACK)
        screen.blit(rep_t, (WIDTH-150, 50))

        pygame.draw.rect(screen, MINT, self.btn_shop, border_radius=10)
        pygame.draw.rect(screen, BLACK, self.btn_shop, 2, border_radius=10)
        shop_t = font_small.render("Shop", True, BLACK)
        screen.blit(shop_t, (self.btn_shop.x+12, self.btn_shop.y+8))

        if self.msg:
            msg_surf = font_med.render(self.msg, True, BLACK)
            bg_rect = msg_surf.get_rect(center=(WIDTH//2, HEIGHT-25))
            pygame.draw.rect(screen, (255, 255, 220, 220), bg_rect.inflate(20,8), border_radius=10)
            screen.blit(msg_surf, bg_rect)

    def draw_menu(self):
        screen.fill(FLOOR)
        title = font_large.render("🐱 Cat Café", True, BLACK)
        screen.blit(title, (WIDTH//2 - title.get_width()//2, 150))
        pygame.draw.rect(screen, MINT, self.btn_play, border_radius=15)
        pygame.draw.rect(screen, BLACK, self.btn_play, 2, border_radius=15)
        play_t = font_med.render("Play", True, BLACK)
        screen.blit(play_t, (WIDTH//2-25, 312))
        hint = font_small.render("Click customer → order, click machine → brew, click customer → serve", True, BLACK)
        screen.blit(hint, (WIDTH//2 - hint.get_width()//2, 400))

    def draw_shop(self):
        screen.fill(FLOOR)
        title = font_large.render("Shop", True, BLACK)
        screen.blit(title, (WIDTH//2-40, 30))
        pygame.draw.rect(screen, MINT, self.btn_back, border_radius=10)
        pygame.draw.rect(screen, BLACK, self.btn_back, 2, border_radius=10)
        back_t = font_small.render("Back", True, BLACK)
        screen.blit(back_t, (self.btn_back.x+12, self.btn_back.y+8))

        y = 120
        screen.blit(font_med.render("Decorations", True, BLACK), (50, 90))
        for dec in decorations:
            color = MINT if dec["owned"] else (220,220,220)
            rect = pygame.Rect(100, y, 320, 45)
            pygame.draw.rect(screen, color, rect, border_radius=10)
            pygame.draw.rect(screen, BLACK, rect, 2, border_radius=10)
            txt = f"{dec['name']} ({dec['cost']}g) {'✓' if dec['owned'] else ''}"
            screen.blit(font_small.render(txt, True, BLACK), (110, y+10))
            y += 55

        y += 20
        screen.blit(font_med.render("Adopt Cats", True, BLACK), (50, y))
        y += 40
        for cd in cat_data_list:
            if not cd["owned"]:
                cost = cd["tip"] * 15
                color = MINT if self.gold >= cost else (220,220,220)
                rect = pygame.Rect(100, y, 320, 45)
                pygame.draw.rect(screen, color, rect, border_radius=10)
                pygame.draw.rect(screen, BLACK, rect, 2, border_radius=10)
                txt = f"{cd['name']}  Tip +{cd['tip']}g  Cost {cost}g"
                screen.blit(font_small.render(txt, True, BLACK), (110, y+10))
                y += 55

    def draw(self):
        if self.state == "menu":
            self.draw_menu()
        elif self.state == "playing":
            self.draw_background()
            for cust in self.customers:
                cust.draw(screen)
            for cat in self.cats:
                cat.draw(screen)
            for h in self.hearts:
                h.draw(screen)
            for ft in self.float_texts:
                ft.draw(screen)
            self.draw_ui()
        elif self.state == "shop":
            self.draw_shop()

    def run(self):
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    self.handle_click(event.pos)

            self.update()
            self.draw()
            pygame.display.flip()
            clock.tick(60)

        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    game = CatCafeTopDown()
    game.run()