import math
import random
from solar_objects import Star, Planet


TICKET_CONFIG = {
    "window": {
        "width": 1200,
        "height": 720,
        "min_width": 850,
        "min_height": 560,
    },
    "stars": [
        {
            "name": "Star 1",
            "planet_count": 11,
            "planets_per_orbit": 1,
            "first_orbit": 48,
            "orbit_step": 24,
            "color": (255, 190, 40),
            "mass": 1.989e30,
        },
        {
            "name": "Star 2",
            "planet_count": 12,
            "planets_per_orbit": 2,
            "first_orbit": 58,
            "orbit_step": 38,
            "color": (255, 150, 55),
            "mass": 1.750e30,
        },
    ],
    "rules": {
        "even_orbit_direction": -1,
        "odd_orbit_direction": 1,
        "orbits_must_intersect": True,
    },
}


class SolarSystem:
    def __init__(self, width=1200, height=720):
        self.width = width
        self.height = height
        self.stars = []
        self.show_orbits = True
        self.paused = False
        self.create_system()
        self.resize(width, height)

    def create_system(self):
        self.stars = []

        for star_data in TICKET_CONFIG["stars"]:
            star = Star(
                0,
                0,
                radius=34,
                color=star_data["color"],
                name=star_data["name"],
                mass=star_data["mass"],
            )
            planet_count = star_data["planet_count"]
            planets_per_orbit = star_data["planets_per_orbit"]
            orbit_count = math.ceil(planet_count / planets_per_orbit)
            created = 0

            for orbit_number in range(1, orbit_count + 1):
                orbit_radius = star_data["first_orbit"] + (orbit_number - 1) * star_data["orbit_step"]
                direction = self.get_direction(orbit_number)
                speed = 0.009 + orbit_number * 0.0007
                base_angle = random.uniform(0, math.pi * 2)

                for place in range(planets_per_orbit):
                    if created >= planet_count:
                        break

                    angle = base_angle + place * (2 * math.pi / planets_per_orbit)
                    planet_mass = random.uniform(3.0e24, 8.0e24)
                    planet = Planet(
                        star,
                        orbit_number,
                        orbit_radius,
                        angle,
                        speed,
                        direction,
                        mass=planet_mass,
                    )
                    star.add_planet(planet)
                    created += 1

            self.stars.append(star)

    def get_direction(self, orbit_number):
        if orbit_number % 2 == 0:
            return TICKET_CONFIG["rules"]["even_orbit_direction"]
        return TICKET_CONFIG["rules"]["odd_orbit_direction"]

    def resize(self, width, height):
        self.width = width
        self.height = height
        center_x = width // 2
        center_y = height // 2
        distance = min(370, max(300, width // 3))

        self.stars[0].set_position(center_x - distance // 2, center_y)
        self.stars[1].set_position(center_x + distance // 2, center_y)

        for star in self.stars:
            for planet in star.planets:
                planet.x, planet.y = planet.calculate_position()

    def update(self):
        if self.paused:
            return

        for star in self.stars:
            star.update()

    def draw(self, screen, pygame):
        for star in self.stars:
            star.draw(screen, pygame, self.show_orbits)

    def toggle_pause(self):
        self.paused = not self.paused

    def toggle_orbits(self):
        self.show_orbits = not self.show_orbits

    def get_all_objects(self):
        objects = []
        for star in self.stars:
            objects.append(star)
            objects.extend(star.planets)
        return objects

    def get_total_mass(self):
        return sum(obj.mass for obj in self.get_all_objects())

    def get_planet_count(self):
        return sum(len(star.planets) for star in self.stars)
