import pygame
import sys
import random
import math

# Initialize pygame
pygame.init()

# Window settings
WIDTH, HEIGHT = 820, 790
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("🎰 Lucky Wheel - Spin to Win!")
clock = pygame.time.Clock()

# Colors (RGB tuples only, no alpha)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (232, 65, 83)
GREEN = (86, 207, 117)
BLUE = (94, 166, 247)
YELLOW = (251, 226, 75)
ORANGE = (246, 172, 68)
PURPLE = (183, 93, 204)
PINK = (249, 157, 174)
CYAN = (86, 224, 239)
GOLD = (227, 189, 72)
SILVER = (187, 213, 229)
DARK_GRAY = (43, 57, 91)
LIGHT_GRAY = (167, 171, 198)
BG_COLOR = (29, 41, 81)

# Prize configuration
prizes = [
    {"name": "Grand Prize", "color": RED, "probability": 0.008, "value": "iPhone 15 Pro"},
    {"name": "First Prize", "color": ORANGE, "probability": 0.017, "value": "AirPods Pro"},
    {"name": "Second Prize", "color": YELLOW, "probability": 0.026, "value": "Bluetooth Speaker"},
    {"name": "Third Prize", "color": GREEN, "probability": 0.035, "value": "Power Bank"},
    {"name": "Fourth Prize", "color": CYAN, "probability": 0.044, "value": "Thermal Mug"},
    {"name": "Try Again", "color": BLUE, "probability": 0.555, "value": "Better Luck Next Time!"},
    {"name": "$10 Coupon", "color": PURPLE, "probability": 0.162, "value": "$10 Discount Coupon"},
    {"name": "$5 Coupon", "color": PINK, "probability": 0.163, "value": "$5 Discount Coupon"},
]

# Normalize probabilities
total_prob = sum(p["probability"] for p in prizes)
for prize in prizes:
    prize["probability"] /= total_prob

NUM_SECTORS = len(prizes)
ANGLE_PER_SECTOR = 360 / NUM_SECTORS

# Fonts
def get_font(size, bold=False):
    try:
        font = pygame.font.Font(None, size)
        if bold:
            font.set_bold(True)
    except:
        font = pygame.font.SysFont("arial", size, bold=bold)
    return font

class Particle:
    def __init__(self, x, y, color, size=3, speed=2, life=60):
        self.x = x
        self.y = y
        self.color = color
        self.size = size
        self.vx = random.uniform(-speed, speed)
        self.vy = random.uniform(-speed, speed)
        self.life = life
        self.max_life = life
    
    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += 0.05
        self.life -= 1
        return self.life > 0
    
    def draw(self, surface):
        alpha = int(255 * (self.life / self.max_life))
        s = pygame.Surface((int(self.size * 2), int(self.size * 2)), pygame.SRCALPHA)
        pygame.draw.circle(s, (*self.color, alpha), 
                          (int(self.size), int(self.size)), int(self.size))
        surface.blit(s, (int(self.x - self.size), int(self.y - self.size)))

class LuckyWheel:
    def __init__(self):
        self.angle = 0
        self.spinning = False
        self.speed = 0
        self.target_angle = 0
        self.selected_prize = None
        self.show_result = False
        self.result_timer = 0
        self.history = []
        self.particles = []
        
        # Spin button
        button_width = 220
        button_height = 60
        self.spin_button = pygame.Rect(
            WIDTH // 2 - button_width // 2,
            HEIGHT - 90,
            button_width,
            button_height
        )
        
        # Decorative circles
        self.decorative_circles = []
        for i in range(12):
            angle = i * 30
            x = WIDTH // 2 + 295 * math.cos(math.radians(angle))
            y = 138 + 278 * math.sin(math.radians(angle))
            self.decorative_circles.append({
                'x': x, 'y': y,
                'size': random.randint(3, 6),
                'brightness': random.uniform(0.5, 1.0)
            })
    
    def spin(self):
        if self.spinning:
            return
        
        # Determine prize
        rand = random.random()
        cumulative = 0
        for i, prize in enumerate(prizes):
            cumulative += prize["probability"]
            if rand <= cumulative:
                self.selected_prize = i
                break
        
        # Calculate target angle
        sector_center = self.selected_prize * ANGLE_PER_SECTOR + ANGLE_PER_SECTOR / 2
        full_rotations = random.randint(5, 10) * 360
        self.target_angle = self.angle + full_rotations + (360 - sector_center)
        
        # Set spin speed
        self.speed = 15
        self.spinning = True
        self.show_result = False
        
        # Create particles
        for _ in range(20):
            self.particles.append(Particle(
                WIDTH // 2, 142,
                GOLD,
                size=random.uniform(2, 4),
                speed=random.uniform(1, 3),
                life=random.randint(20, 40)
            ))
    
    def update(self):
        # Update rotation
        if self.spinning:
            self.angle += self.speed
            self.speed *= 0.982
            
            if self.speed < 0.1:
                self.speed = 0
                self.spinning = False
                self.show_result = True
                self.result_timer = 0
                
                # Celebration effects
                for _ in range(30):
                    self.particles.append(Particle(
                        WIDTH // 2, 143,
                        prizes[self.selected_prize]["color"],
                        size=random.uniform(3, 6),
                        speed=random.uniform(2, 5),
                        life=random.randint(30, 60)
                    ))
                
                # Add to history
                self.history.append(prizes[self.selected_prize]["name"])
                if len(self.history) > 10:
                    self.history.pop(0)
        
        # Update result timer
        if self.show_result:
            self.result_timer += 1
            if self.result_timer > 8888:
                self.show_result = False
        
        # Update particles
        for particle in self.particles[:]:
            if not particle.update():
                self.particles.remove(particle)
    
    def draw_wheel(self, surface):
        center_x, center_y = WIDTH // 2, 149
        wheel_radius = 262
        
        # Draw outer shadow
        pygame.draw.circle(surface, (20, 28, 49), (center_x + 8, center_y + 272), wheel_radius + 20)
        
        # Draw outer ring
        pygame.draw.circle(surface, DARK_GRAY, (center_x, center_y), wheel_radius + 15)
        pygame.draw.circle(surface, GOLD, (center_x, center_y), wheel_radius + 12, 3)
        
        # Draw sectors
        for i in range(NUM_SECTORS):
            start_angle = math.radians(self.angle + i * ANGLE_PER_SECTOR)
            end_angle = math.radians(self.angle + (i + 1) * ANGLE_PER_SECTOR)
            
            # Create sector polygon
            points = [(center_x, center_y)]
            steps = 30
            for step in range(steps + 1):
                angle = start_angle + (end_angle - start_angle) * step / steps
                x = center_x + wheel_radius * math.cos(angle)
                y = center_y + wheel_radius * math.sin(angle)
                points.append((x, y))
            
            # Draw sector
            color = prizes[i]["color"]
            pygame.draw.polygon(surface, color, points)
            pygame.draw.polygon(surface, (255, 254, 243), points, 1)
            
            # Draw sector text
            mid_angle = math.radians(self.angle + (i + 0.5) * ANGLE_PER_SECTOR)
            text_radius = wheel_radius * 0.618
            text_x = center_x + text_radius * math.cos(mid_angle)
            text_y = center_y + text_radius * math.sin(mid_angle)
            
            # Draw prize name
            font = get_font(13, True)
            text = font.render(prizes[i]["name"], True, BLACK)
            rotated_text = pygame.transform.rotate(text, -(self.angle + (i + 0.5) * ANGLE_PER_SECTOR))
            text_rect = rotated_text.get_rect(center=(text_x, text_y))
            surface.blit(rotated_text, text_rect)
            
            # Draw prize value
            font_small = get_font(9)
            value_text = font_small.render(prizes[i]["value"], True, BLACK)
            value_radius = wheel_radius * 0.418
            value_x = center_x + value_radius * math.cos(mid_angle)
            value_y = center_y + value_radius * math.sin(mid_angle)
            rotated_value = pygame.transform.rotate(value_text, -(self.angle + (i + 0.5) * ANGLE_PER_SECTOR))
            value_rect = rotated_value.get_rect(center=(value_x, value_y))
            surface.blit(rotated_value, value_rect)
        
        # Draw inner circle
        inner_radius = 50
        pygame.draw.circle(surface, DARK_GRAY, (center_x, center_y), inner_radius)
        pygame.draw.circle(surface, GOLD, (center_x, center_y), inner_radius, 3)
        
        # Draw center text
        font = get_font(18, True)
        center_text = font.render("SPIN", True, GOLD)
        surface.blit(center_text, (center_x - center_text.get_width() // 2,
                                  center_y - center_text.get_height() // 2))
        
        # Draw decorative dots
        for i in range(36):
            angle = math.radians(i * 10)
            dot_x = center_x + (wheel_radius + 8) * math.cos(angle)
            dot_y = center_y + (wheel_radius + 8) * math.sin(angle)
            dot_color = GOLD if i % 2 == 0 else SILVER
            pygame.draw.circle(surface, dot_color, (int(dot_x), int(dot_y)), 3)
    
    def draw_pointer(self, surface):
        center_x, center_y = WIDTH // 2, 392
        
        # Pointer triangle
        pointer_points = [
            (center_x, center_y + 20),
            (center_x - 18, center_y - 8),
            (center_x + 18, center_y - 8)
        ]
        pygame.draw.polygon(surface, RED, pointer_points)
        pygame.draw.polygon(surface, (188, 8, 8), pointer_points, 2)
        
        # Pointer base
        pygame.draw.circle(surface, RED, (center_x, center_y), 8)
        pygame.draw.circle(surface, (159, 8, 8), (center_x, center_y), 8, 2)
    
    def draw_spin_button(self, surface):
        # Draw button shadow
        shadow_rect = self.spin_button.move(0, 5)
        pygame.draw.rect(surface, (20, 28, 49), shadow_rect, border_radius=15)
        
        # Draw button
        color = (52, 161, 231) if not self.spinning else (107, 111, 115)
        pygame.draw.rect(surface, color, self.spin_button, border_radius=12)
        pygame.draw.rect(surface, GOLD, self.spin_button, 3, border_radius=12)
        
        # Draw button text
        font = get_font(26, True)
        text = "🎰 SPIN NOW!" if not self.spinning else "⏳ SPINNING..."
        text_surface = font.render(text, True, WHITE)
        text_rect = text_surface.get_rect(center=self.spin_button.center)
        surface.blit(text_surface, text_rect)
    
    def draw_result(self, surface):
        if not self.show_result:
            return
        
        # Draw semi-transparent overlay
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 169))
        surface.blit(overlay, (0, 0))
        
        # Draw result box
        box_width = 450
        box_height = 292
        box_x = WIDTH // 2 - box_width // 2
        box_y = HEIGHT // 2 - box_height // 2
        
        # Box shadow
        shadow_rect = pygame.Rect(box_x + 6, box_y + 6, box_width, box_height)
        pygame.draw.rect(surface, (20, 28, 122), shadow_rect, border_radius=20)
        
        # Box background
        box_rect = pygame.Rect(box_x, box_y, box_width, box_height)
        pygame.draw.rect(surface, (237, 248, 239), box_rect, border_radius=18)
        pygame.draw.rect(surface, GOLD, box_rect, 4, border_radius=18)
        
        # Congratulations text
        font = get_font(42, True)
        congrats_text = font.render("🎉 CONGRATULATIONS 🎉", True, RED)
        surface.blit(congrats_text, (box_x + box_width // 2 - congrats_text.get_width() // 2,
                                    box_y + 25))
        
        # Prize name
        prize = prizes[self.selected_prize]
        font = get_font(38, True)
        prize_text = font.render(prize["name"], True, prize["color"])
        surface.blit(prize_text, (box_x + box_width // 2 - prize_text.get_width() // 2,
                                 box_y + 113))
        
        # Prize value
        font = get_font(26)
        value_text = font.render(prize["value"], True, DARK_GRAY)
        surface.blit(value_text, (box_x + box_width // 2 - value_text.get_width() // 2,
                                 box_y + 185))
        
        # Close instruction
        font = get_font(18)
        close_text = font.render("Click anywhere to close", True, LIGHT_GRAY)
        surface.blit(close_text, (box_x + box_width // 2 - close_text.get_width() // 2,
                                 box_y + box_height - 42))
    
    def draw_history(self, surface):
        # Draw history panel
        panel_x = WIDTH - 208
        panel_y = 415
        panel_width = 191
        panel_height = 350
        
        # Panel background
        pygame.draw.rect(surface, (34, 47, 126), 
                        (panel_x, panel_y, panel_width, panel_height), 
                        border_radius=10)
        pygame.draw.rect(surface, GOLD, 
                        (panel_x, panel_y, panel_width, panel_height), 
                        2, border_radius=10)
        
        # Panel title
        font = get_font(16, True)
        title_text = font.render("📜 Spin History", True, GOLD)
        surface.blit(title_text, (panel_x + panel_width // 2 - title_text.get_width() // 2,
                                 panel_y + 10))
        
        # Draw history items
        font = get_font(11)
        y_offset = panel_y + 40
        for i, record in enumerate(reversed(self.history)):
            if "Prize" in record:
                color = GREEN
            elif "Try" in record:
                color = LIGHT_GRAY
            else:
                color = YELLOW
            text = font.render(f"{i + 1}. {record}", True, color)
            surface.blit(text, (panel_x + 15, y_offset))
            y_offset += 30
            
            if y_offset > panel_y + panel_height - 20:
                break
    
    def draw_info(self, surface):
        # Draw title
        font = get_font(38, True)
        title_text = font.render("🎰 LUCKY WHEEL 🎰", True, GOLD)
        surface.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, 685))
        
        # Draw instructions
        font = get_font(14)
        inst_text = font.render("Click the button or press SPACE to spin!", True, LIGHT_GRAY)
        surface.blit(inst_text, (WIDTH // 2 - inst_text.get_width() // 2, 725))
    
    def draw(self, surface):
        # Draw background
        surface.fill(BG_COLOR)
        
        # Draw decorative elements
        for circle in self.decorative_circles:
            alpha = int(255 * circle['brightness'])
            s = pygame.Surface((circle['size'] * 2, circle['size'] * 2), pygame.SRCALPHA)
            pygame.draw.circle(s, (255, 233, 151, alpha), 
                             (circle['size'], circle['size']), circle['size'])
            surface.blit(s, (circle['x'] - circle['size'], circle['y'] - circle['size']))
        
        # Draw wheel
        self.draw_wheel(surface)
        
        # Draw pointer
        self.draw_pointer(surface)
        
        # Draw button
        self.draw_spin_button(surface)
        
        # Draw particles
        for particle in self.particles:
            particle.draw(surface)
        
        # Draw history
        self.draw_history(surface)
        
        # Draw info
        self.draw_info(surface)
        
        # Draw result overlay
        self.draw_result(surface)
    
    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            pos = pygame.mouse.get_pos()
            
            # Check if result overlay is shown
            if self.show_result:
                self.show_result = False
                return
            
            # Check spin button click
            if self.spin_button.collidepoint(pos) and not self.spinning:
                self.spin()
        
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and not self.spinning and not self.show_result:
                self.spin()
            elif event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()

def main():
    wheel = LuckyWheel()
    
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            else:
                wheel.handle_event(event)
        
        wheel.update()
        wheel.draw(screen)
        
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()