import math
import random


class SpaceObject:
    def __init__(self, x, y, radius, color, mass=1.0):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.mass = mass

    def update(self):
        pass

    def draw(self, screen, pygame):
        pass


class Star(SpaceObject):
    def __init__(self, x, y, radius=34, color=(255, 185, 40), name="Star", mass=1.989e30):
        super().__init__(x, y, radius, color, mass)
        self.name = name
        self.planets = []

    def add_planet(self, planet):
        self.planets.append(planet)

    def set_position(self, x, y):
        self.x = x
        self.y = y

    def update(self):
        for planet in self.planets:
            planet.update()

    def draw(self, screen, pygame, show_orbits=True):
        if show_orbits:
            for planet in self.planets:
                planet.draw_orbit(screen, pygame)

        pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius)
        pygame.draw.circle(screen, (255, 230, 120), (int(self.x), int(self.y)), self.radius // 2)

        for planet in self.planets:
            planet.draw(screen, pygame)


class Planet(SpaceObject):
    def __init__(self, star, orbit_number, orbit_radius, angle, speed, direction, radius=None, color=None, mass=None):
        self.star = star
        self.orbit_number = orbit_number
        self.orbit_radius = orbit_radius
        self.angle = angle
        self.speed = speed
        self.angular_speed = speed
        self.direction = direction
        self.linear_speed = abs(self.angular_speed * self.orbit_radius)

        if radius is None:
            radius = random.randint(8, 13)

        if color is None:
            color = (
                random.randint(40, 220),
                random.randint(70, 230),
                random.randint(90, 255),
            )

        if mass is None:
            mass = random.uniform(3.0e24, 8.0e24)

        x, y = self.calculate_position()
        super().__init__(x, y, radius, color, mass)

    def calculate_position(self):
        x = self.star.x + math.cos(self.angle) * self.orbit_radius
        y = self.star.y + math.sin(self.angle) * self.orbit_radius
        return x, y

    def update(self):
        self.angle += self.angular_speed * self.direction
        self.x, self.y = self.calculate_position()

    def draw_orbit(self, screen, pygame):
        pygame.draw.circle(
            screen,
            (160, 160, 160),
            (int(self.star.x), int(self.star.y)),
            int(self.orbit_radius),
            1,
        )

    def draw(self, screen, pygame):
        pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius)
