import os
import pytz
import swisseph as swe
import pandas as pd
from datetime import datetime, timezone
from skyfield.api import load
from .utils import format_degree_to_zodiac

class Horoscope:
    def __init__(self, date: str, time: str, location: tuple[str, float, float]):
        self.date = date
        self.time = time
        self.location = location  # (nazwa, szerokość, długość)
        self.positions = {}
        self.ts = load.timescale()

        data_dir = os.path.join(os.path.dirname(__file__), '..', 'data')
        os.makedirs(data_dir, exist_ok=True)
        bsp_path = os.path.join(data_dir, 'de435.bsp')

        if not os.path.exists(bsp_path):
            from urllib.request import urlretrieve
            url = 'https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de435.bsp'
            print("Pobieranie efemeryd...")
            urlretrieve(url, bsp_path)

        self.ephemeris = load(bsp_path)

        self.planets = [
            ('Sun', swe.SUN),
            ('Moon', swe.MOON),
            ('Mercury', swe.MERCURY),
            ('Venus', swe.VENUS),
            ('Mars', swe.MARS),
            ('Jupiter', swe.JUPITER),
            ('Saturn', swe.SATURN),
            ('Uranus', swe.URANUS),
            ('Neptune', swe.NEPTUNE),
            ('Pluto', swe.PLUTO),
            ('Chiron', swe.CHIRON),
            ('Lilith', swe.MEAN_APOG),   
            ('Node', swe.MEAN_NODE),

            
        ]

    def compute(self):
        name, lat, lon = self.location

        local_tz = pytz.timezone("Europe/Warsaw")
        dt_naive = datetime.strptime(f"{self.date} {self.time}", "%Y-%m-%d %H:%M")
        dt_utc = local_tz.localize(dt_naive).astimezone(timezone.utc)
        jd = swe.julday(dt_utc.year, dt_utc.month, dt_utc.day,
                        dt_utc.hour + dt_utc.minute / 60.0)

        swe.set_ephe_path(os.path.join(os.path.dirname(__file__), '..', 'data', 'se'))  # <== dodaj to

        houses, ascmc = swe.houses(jd, lat, lon, b'P')


        self.houses = houses
        self.asc = ascmc[0]
        self.mc = ascmc[1]

        # Planety i punkty
        for nazwa, pid in self.planets:
            lonlat, _ = swe.calc_ut(jd, pid)
            self.positions[nazwa] = {
                'longitude': lonlat[0],
                'latitude': lonlat[1],
                'formatted': format_degree_to_zodiac(lonlat[0])
            }

        
        fortune = (self.asc + self.positions['Moon']['longitude'] -
                   self.positions['Sun']['longitude']) % 360
        self.positions['Fortune'] = {
            'longitude': fortune,
            'latitude': 0.0,
            'formatted': format_degree_to_zodiac(fortune)
        }

        # Vertex (przybliżenie)
        vertex = (self.asc + 180.0) % 360.0
        self.positions['Vertex'] = {
            'longitude': vertex,
            'latitude': 0.0,
            'formatted': format_degree_to_zodiac(vertex)
        }

        # Formatowane ASC i MC
        self.asc_formatted = format_degree_to_zodiac(self.asc)
        self.mc_formatted = format_degree_to_zodiac(self.mc)


    def get_dataframe(self):
        df = pd.DataFrame.from_dict(self.positions, orient='index')
        df.index.name = 'Obiekt'
        return df
