import pygame
import math
import random

# --- Configuration ---
WIDTH, HEIGHT = 900, 750
WHITE, BLACK, GREEN = (255, 255, 255), (0, 0, 0), (34, 139, 34)
GOLD, RED, BLUE = (255, 215, 0), (220, 20, 60), (30, 144, 255)

MARBLE_RADIUS = 15
FRICTION = 0.98


# ---------------- MARBLE CLASS ----------------
class Marble:
    def __init__(self, x, y, color):
        self.x, self.y = x, y
        self.dx, self.dy = 0, 0
        self.color = color

    def move(self):
        self.x += self.dx
        self.y += self.dy
        self.dx *= FRICTION
        self.dy *= FRICTION
        if abs(self.dx) < 0.1:
            self.dx = 0
        if abs(self.dy) < 0.1:
            self.dy = 0

    def draw(self, screen):
        pygame.draw.circle(
            screen, self.color,
            (int(self.x), int(self.y)),
            MARBLE_RADIUS
        )
        pygame.draw.circle(
            screen, BLACK,
            (int(self.x), int(self.y)),
            MARBLE_RADIUS, 1
        )


# ---------------- COLLISION ----------------
def resolve_collision(m1, m2):
    dx, dy = m2.x - m1.x, m2.y - m1.y
    dist = math.hypot(dx, dy)

    if 0 < dist < MARBLE_RADIUS * 2:
        overlap = MARBLE_RADIUS * 2 - dist
        nx, ny = dx / dist, dy / dist

        m1.x -= overlap * nx * 0.5
        m1.y -= overlap * ny * 0.5

        m1.dx, m2.dx = m2.dx, m1.dx
        m1.dy, m2.dy = m2.dy, m1.dy
        return True

    return False


# ================= MODE 2 GAME =================
def run_mode_2():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Marble Game - Mode 2")
    clock = pygame.time.Clock()
    font = pygame.font.SysFont("Arial", 26, bold=True)

    # ---------- PHASE 1: PLAYER NAMES ----------
    player_names = ["", ""]
    name_idx = 0
    naming = True

    while naming:
        screen.fill(BLACK)
        text = f"Player {name_idx + 1} Name: {player_names[name_idx]}_"
        screen.blit(font.render(text, True, WHITE), (WIDTH // 2 - 200, HEIGHT // 2))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN and player_names[name_idx]:
                    name_idx += 1
                    if name_idx > 1:
                        naming = False
                elif event.key == pygame.K_BACKSPACE:
                    player_names[name_idx] = player_names[name_idx][:-1]
                else:
                    player_names[name_idx] += event.unicode

        pygame.display.flip()
        clock.tick(30)

    # ---------- GAME SETUP ----------
    center_ring = (WIDTH // 2, HEIGHT // 2 - 30)
    ring_radius = 130
    shoot_y = HEIGHT - 120
    shoot_pos = (WIDTH // 2, shoot_y)

    ammo = [4, 4]
    collected = [0, 0]
    current_player = 0

    targets = [
        Marble(
            center_ring[0] + random.randint(-50, 50),
            center_ring[1] + random.randint(-50, 50),
            GOLD
        ) for _ in range(6)
    ]

    shooter = Marble(
        shoot_pos[0],
        shoot_pos[1],
        RED if current_player == 0 else BLUE
    )

    is_charging = False
    moving = False
    hit_this_turn = False
    game_over = False

    # ---------- MAIN GAME LOOP ----------
    while not game_over:
        screen.fill(GREEN)

        pygame.draw.circle(screen, WHITE, center_ring, ring_radius, 3)
        pygame.draw.line(screen, WHITE, (0, shoot_y - 30), (WIDTH, shoot_y - 30), 4)

        # UI
        screen.blit(
            font.render(f"{player_names[0]} | Ammo: {ammo[0]} | Wins: {collected[0]}", True, RED),
            (20, 20)
        )
        screen.blit(
            font.render(f"{player_names[1]} | Ammo: {ammo[1]} | Wins: {collected[1]}", True, BLUE),
            (WIDTH - 380, 20)
        )

        turn_txt = font.render(f"{player_names[current_player]}'s TURN", True, WHITE)
        screen.blit(turn_txt, (WIDTH // 2 - 80, 60))

        # Ammo indicators
        for i in range(ammo[0]):
            pygame.draw.circle(screen, RED, (30, HEIGHT - 30 - i * 25), 10)
        for i in range(ammo[1]):
            pygame.draw.circle(screen, BLUE, (WIDTH - 30, HEIGHT - 30 - i * 25), 10)

        mx, my = pygame.mouse.get_pos()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return

            if not moving and ammo[current_player] > 0:
                dist = math.hypot(mx - shooter.x, my - shooter.y)

                if event.type == pygame.MOUSEBUTTONDOWN and dist < MARBLE_RADIUS * 2:
                    is_charging = True

                if event.type == pygame.MOUSEBUTTONUP and is_charging:
                    shooter.dx = (shooter.x - mx) * 0.16
                    shooter.dy = (shooter.y - my) * 0.16
                    is_charging = False
                    moving = True
                    hit_this_turn = False

        # ---------- PHYSICS ----------
        if moving:
            shooter.move()

            for t in targets[:]:
                t.move()

                if resolve_collision(shooter, t):
                    targets.remove(t)
                    collected[current_player] += 1
                    hit_this_turn = True

                if math.hypot(t.x - center_ring[0], t.y - center_ring[1]) > ring_radius:
                    if t in targets:
                        targets.remove(t)
                        collected[current_player] += 1
                        hit_this_turn = True

            if shooter.dx == 0 and shooter.dy == 0 and all(t.dx == 0 for t in targets):
                if hit_this_turn:
                    collected[current_player] += 1
                else:
                    if math.hypot(shooter.x - center_ring[0], shooter.y - center_ring[1]) < ring_radius:
                        shooter.color = GOLD
                        targets.append(shooter)
                        ammo[current_player] -= 1
                    current_player = 1 - current_player

                shooter = Marble(
                    shoot_pos[0],
                    shoot_pos[1],
                    RED if current_player == 0 else BLUE
                )
                moving = False

        # ---------- DRAW ----------
        if is_charging:
            pygame.draw.line(screen, WHITE, (shooter.x, shooter.y), (mx, my), 2)

        if not moving or shooter.dx != 0:
            shooter.draw(screen)

        for t in targets:
            t.draw(screen)

        if ammo[0] <= 0 or ammo[1] <= 0 or len(targets) == 0:
            game_over = True

        pygame.display.flip()
        clock.tick(60)

    # ---------- WINNER SCREEN ----------
    screen.fill(BLACK)
    winner = 0 if collected[0] > collected[1] else 1
    msg = f"{player_names[winner]} WINS WITH {collected[winner]} MARBLES!"
    screen.blit(font.render(msg, True, GOLD), (WIDTH // 2 - 300, HEIGHT // 2))
    pygame.display.flip()
    pygame.time.wait(4000)

    pygame.quit()
