import pygame
import math
import random
import sys

# Initialize Pygame
pygame.init()

# Window settings
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Spinning Watermelon Dart Throw")
clock = pygame.time.Clock()

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
GREEN = (50, 200, 50)
DARK_GREEN = (30, 150, 30)
BROWN = (139, 69, 19)
YELLOW = (255, 255, 0)
GRAY = (100, 100, 100)

# Fonts
font = pygame.font.Font(None, 48)
small_font = pygame.font.Font(None, 32)


class Watermelon:
    """Watermelon class: rotates in the center, can be hit by darts"""
    def __init__(self):
        self.radius = 60
        self.x = WIDTH // 2
        self.y = HEIGHT // 2
        self.angle = 0
        self.rotation_speed = 1.5  # Rotation angle per frame
        self.alive = True
        
        # Create watermelon surface (with stripes)
        self.surface = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA)
        self.draw_watermelon_surface()
        
    def draw_watermelon_surface(self):
        """Draw a watermelon with stripes"""
        surf = self.surface
        center = (self.radius, self.radius)
        r = self.radius - 5
        
        # Watermelon body (dark green base)
        pygame.draw.circle(surf, DARK_GREEN, center, r)
        
        # Watermelon stripes (light green)
        for i in range(6):
            angle_offset = i * (math.pi / 3)
            for j in range(-2, 3):
                x = center[0] + (r - 5) * math.cos(angle_offset + j * 0.15)
                y = center[1] + (r - 5) * math.sin(angle_offset + j * 0.15)
                pygame.draw.circle(surf, GREEN, (int(x), int(y)), 8)
        
        # Watermelon highlight
        for i in range(3):
            x = center[0] + (r - 20) * math.cos(-math.pi/4 + i * 0.2)
            y = center[1] + (r - 30) * math.sin(-math.pi/4 + i * 0.2)
            pygame.draw.circle(surf, (100, 200, 100, 50), (int(x), int(y)), 6)
    
    def update(self):
        """Update watermelon rotation angle"""
        self.angle += self.rotation_speed
        if self.angle >= 360:
            self.angle -= 360
    
    def get_rotated_image(self):
        """Get the rotated watermelon image"""
        rotated = pygame.transform.rotozoom(self.surface, self.angle, 1.0)
        return rotated
    
    def get_rect(self):
        """Get rotated rectangle (for collision detection)"""
        rotated = self.get_rotated_image()
        rect = rotated.get_rect(center=(self.x, self.y))
        return rect
    
    def check_collision(self, dart_pos):
        """Check if dart hits watermelon (circle collision based on distance)"""
        dx = dart_pos[0] - self.x
        dy = dart_pos[1] - self.y
        distance = math.sqrt(dx*dx + dy*dy)
        return distance < self.radius * 0.85  # Slightly smaller for more realistic feel
    
    def draw(self, screen):
        """Draw the watermelon"""
        if not self.alive:
            return
        rotated = self.get_rotated_image()
        rect = rotated.get_rect(center=(self.x, self.y))
        screen.blit(rotated, rect)


class Dart:
    """Dart class"""
    def __init__(self, start_pos, target_pos):
        self.x, self.y = start_pos
        self.speed = 15  # Flight speed
        self.alive = True
        self.hit = False
        
        # Calculate direction vector toward target
        dx = target_pos[0] - start_pos[0]
        dy = target_pos[1] - start_pos[1]
        length = math.sqrt(dx*dx + dy*dy)
        if length > 0:
            self.vx = (dx / length) * self.speed
            self.vy = (dy / length) * self.speed
            self.angle = math.degrees(math.atan2(-dy, dx))  # Dart pointing angle
        else:
            self.vx, self.vy = 0, -self.speed
            self.angle = 0
        
        # Dart trail points
        self.trail = []
    
    def update(self):
        """Update dart position"""
        if not self.alive:
            return
        
        # Record trail
        self.trail.append((self.x, self.y))
        if len(self.trail) > 15:
            self.trail.pop(0)
        
        # Move
        self.x += self.vx
        self.y += self.vy
        
        # Check if out of bounds
        if (self.x < -20 or self.x > WIDTH + 20 or 
            self.y < -20 or self.y > HEIGHT + 20):
            self.alive = False
    
    def draw(self, screen):
        """Draw the dart"""
        if not self.alive:
            return
        
        # Draw trail (fade effect)
        for i, pos in enumerate(self.trail):
            alpha = int(255 * (i / len(self.trail)) * 0.5)
            color = (255, 255, 0, alpha)
            trail_surf = pygame.Surface((6, 6), pygame.SRCALPHA)
            pygame.draw.circle(trail_surf, (*color[:3], alpha), (3, 3), 2 + i//4)
            screen.blit(trail_surf, (pos[0]-3, pos[1]-3))
        
        # Draw dart
        dart_surf = pygame.Surface((30, 10), pygame.SRCALPHA)
        
        # Dart body (arrowhead)
        points = [
            (28, 5),    # Tip
            (20, 2),
            (20, 8),
            (28, 5),
        ]
        pygame.draw.polygon(dart_surf, GRAY, points)
        
        # Dart shaft
        pygame.draw.rect(dart_surf, (200, 200, 200), (2, 3, 18, 4))
        
        # Dart tail fins
        tail_points = [
            (2, 1),
            (0, 0),
            (2, 3),
            (4, 0),
            (2, 1),
        ]
        pygame.draw.polygon(dart_surf, RED, tail_points)
        tail_points2 = [
            (2, 9),
            (0, 10),
            (2, 7),
            (4, 10),
            (2, 9),
        ]
        pygame.draw.polygon(dart_surf, RED, tail_points2)
        
        # Rotate and draw dart
        rotated_dart = pygame.transform.rotate(dart_surf, self.angle)
        rect = rotated_dart.get_rect(center=(self.x, self.y))
        screen.blit(rotated_dart, rect)


class Game:
    """Main game class"""
    def __init__(self):
        self.watermelon = Watermelon()
        self.darts = []
        self.score = 0
        self.game_over = False
        self.win = False
        self.message = ""
        self.message_timer = 0
        self.dart_count = 5  # Initial dart count
        self.max_darts = 5
        self.darts_remaining = self.max_darts
        
        # Dart starting position (bottom of screen)
        self.dart_start_x = WIDTH // 2
        self.dart_start_y = HEIGHT - 30
    
    def handle_click(self, pos):
        """Handle mouse click - throw a dart"""
        if self.game_over or self.win:
            # Click to restart after game ends
            self.reset_game()
            return
        
        if self.darts_remaining <= 0:
            return
        
        # Throw dart from bottom center toward click position
        start_pos = (self.dart_start_x + random.randint(-30, 30), self.dart_start_y)
        dart = Dart(start_pos, pos)
        self.darts.append(dart)
        self.darts_remaining -= 1
    
    def reset_game(self):
        """Reset the game"""
        self.watermelon = Watermelon()
        self.darts = []
        self.score = 0
        self.game_over = False
        self.win = False
        self.message = ""
        self.message_timer = 0
        self.darts_remaining = self.max_darts
    
    def update(self):
        """Update game state"""
        if self.game_over or self.win:
            return
        
        # Update watermelon
        self.watermelon.update()
        
        # Update all darts
        for dart in self.darts[:]:
            dart.update()
            
            # Check if dart hits watermelon
            if (dart.alive and not dart.hit and 
                self.watermelon.alive and 
                self.watermelon.check_collision((dart.x, dart.y))):
                dart.hit = True
                dart.alive = False
                self.score += 1
                self.message = "🎯 Hit! +1 point"
                self.message_timer = 60  # Show for 1 second
                
                # Check if won (3 hits to win)
                if self.score >= 3:
                    self.win = True
                    self.message = "🎉 You Win! Click to restart"
                    self.message_timer = -1  # Show indefinitely
            
            # Remove darts that are out of bounds
            if not dart.alive and not dart.hit:
                self.darts.remove(dart)
        
        # Check if lost (no darts left and not won)
        if self.darts_remaining <= 0 and not self.win:
            # Check if all darts have stopped
            active_darts = [d for d in self.darts if d.alive]
            if len(active_darts) == 0:
                self.game_over = True
                self.message = "😢 Out of darts! Click to restart"
                self.message_timer = -1
        
        # Update message timer
        if self.message_timer > 0:
            self.message_timer -= 1
            if self.message_timer == 0:
                self.message = ""
    
    def draw(self):
        """Draw everything"""
        screen.fill(WHITE)
        
        # Draw background target (decorative)
        for i in range(3, 0, -1):
            color = (200, 50, 50) if i % 2 == 1 else WHITE
            pygame.draw.circle(screen, color, (WIDTH//2, HEIGHT//2), 80 + i*30, 2)
        
        # Draw watermelon
        self.watermelon.draw(screen)
        
        # Draw all darts
        for dart in self.darts:
            dart.draw(screen)
        
        # Draw UI info
        # Score
        score_text = font.render(f"🎯 Score: {self.score}/3", True, BLACK)
        screen.blit(score_text, (20, 20))
        
        # Remaining darts
        darts_text = font.render(f"📌 Remaining: {self.darts_remaining}", True, BLACK)
        screen.blit(darts_text, (20, 75))
        
        # Throw hint (bottom arrow)
        if not self.game_over and not self.win and self.darts_remaining > 0:
            hint_text = small_font.render("👆 Click to throw a dart", True, GRAY)
            hint_rect = hint_text.get_rect(center=(WIDTH//2, HEIGHT - 10))
            screen.blit(hint_text, hint_rect)
            
            # Draw a small crosshair
            pygame.draw.circle(screen, (200, 200, 200), (WIDTH//2, HEIGHT - 50), 20, 1)
            pygame.draw.line(screen, (200, 200, 200), 
                           (WIDTH//2 - 25, HEIGHT - 50), 
                           (WIDTH//2 + 25, HEIGHT - 50), 1)
            pygame.draw.line(screen, (200, 200, 200), 
                           (WIDTH//2, HEIGHT - 75), 
                           (WIDTH//2, HEIGHT - 25), 1)
        
        # Show message
        if self.message:
            msg_color = BLACK
            if "Win" in self.message:
                msg_color = (200, 50, 50)
            elif "Hit" in self.message:
                msg_color = (50, 200, 50)
            msg_text = font.render(self.message, True, msg_color)
            msg_rect = msg_text.get_rect(center=(WIDTH//2, 150))
            screen.blit(msg_text, msg_rect)
        
        # Show restart hint
        if self.game_over or self.win:
            restart_text = small_font.render("Click to restart", True, GRAY)
            restart_rect = restart_text.get_rect(center=(WIDTH//2, 200))
            screen.blit(restart_text, restart_rect)
        
        pygame.display.flip()
    
    def run(self):
        """Main game loop"""
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:  # Left click
                        self.handle_click(event.pos)
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_r:  # R key to reset
                        self.reset_game()
                    if event.key == pygame.K_ESCAPE:  # ESC to quit
                        running = False
            
            self.update()
            self.draw()
            clock.tick(60)
        
        pygame.quit()
        sys.exit()


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