import matplotlib.pyplot as plt
import numpy as np
from .utils import ZODIAC_SIGNS, PLANET_SYMBOLS, PLANET_COLORS, format_degree_to_zodiac, ASPECTS, calculate_aspects

def plot_full_chart(horoscope, figsize=(10, 10), save_path=None):
    fig, ax = plt.subplots(figsize=figsize, subplot_kw={'projection': 'polar'})
    ax.set_theta_direction(1)
    ax.set_theta_zero_location("W")

    ax.set_yticklabels([])
    ax.set_xticks([])
    ax.set_frame_on(False)
    ax.grid(False)

    fig.subplots_adjust(left=0.05, right=0.95, top=0.95, bottom=0.05)

    # Trzy koncentryczne pierścienie
    for r in [0.5, 0.6, 0.95]:
        circle = plt.Circle((0, 0), r, transform=ax.transData._b,
                            color='black', fill=False, lw=1)
        ax.add_artist(circle)

    # Podziałka zewnętrzna co 1°, 5°, 30°
    for deg in range(360):
        angle = np.deg2rad((deg - horoscope.asc) % 360)
        if deg % 30 == 0:
            r0, r1, lw = 0.93, 1.05, 2
        elif deg % 5 == 0:
            r0, r1, lw = 0.96, 1.02, 1
        else:
            r0, r1, lw = 0.98, 1.01, 0.4
        ax.plot([angle, angle], [r0, r1], color='gray', lw=lw)

    # Znaki zodiaku
    for i in range(12):
        zodiac_line_deg = (i * 30 - horoscope.asc) % 360
        angle_line = np.deg2rad(zodiac_line_deg)
        ax.plot([angle_line, angle_line], [0.95, 1.05], color='black', lw=2)

        zodiac_text_deg = (i * 30 + 15 - horoscope.asc) % 360
        angle_text = np.deg2rad(zodiac_text_deg)
        ax.text(angle_text, 1.1, ZODIAC_SIGNS[i], fontsize=24,
                ha='center', va='center', fontweight='bold')

    # Linie domów i numery
    for i in range(12):
        cusp_deg = horoscope.houses[i]
        angle_rad = np.deg2rad((cusp_deg - horoscope.asc) % 360)
        ax.plot([angle_rad, angle_rad], [0.5, 0.95], color='gray', lw=1)

        start = horoscope.houses[i]
        end = horoscope.houses[(i + 1) % 12]
        mid = (start + (end - start) % 360 / 2) % 360
        mid_angle = np.deg2rad((mid - horoscope.asc) % 360)
        ax.text(mid_angle, 0.55, str(i + 1), fontsize=13,
                ha='center', va='center', fontweight='bold')

    # Linie ASC/DSC/MC/IC
    asc_angle = np.deg2rad(0)
    dsc_angle = np.deg2rad(180)
    mc_angle = np.deg2rad((horoscope.mc - horoscope.asc) % 360)
    ic_angle = np.deg2rad((horoscope.mc + 180 - horoscope.asc) % 360)

    ax.plot([asc_angle, asc_angle], [0.5, 0.95], color=PLANET_COLORS.get('ASC', 'blue'), lw=2.5)
    ax.plot([dsc_angle, dsc_angle], [0.5, 0.95], color=PLANET_COLORS.get('ASC', 'blue'), lw=2.5)
    ax.plot([mc_angle, mc_angle], [0.5, 0.95], color=PLANET_COLORS.get('MC', 'red'), lw=2.5)
    ax.plot([ic_angle, ic_angle], [0.5, 0.95], color=PLANET_COLORS.get('MC', 'red'), lw=2.5)

    # Etykiety osi
    ax.text(asc_angle, 1.1, 'ASC', fontsize=13, ha='center', va='center', color=PLANET_COLORS.get('ASC', 'blue'))
    ax.text(dsc_angle, 1.1, 'DSC', fontsize=13, ha='center', va='center', color=PLANET_COLORS.get('ASC', 'blue'))
    ax.text(mc_angle, 1.1, 'MC', fontsize=13, ha='center', va='center', color=PLANET_COLORS.get('MC', 'red'))
    ax.text(ic_angle, 1.1, 'IC', fontsize=13, ha='center', va='center', color=PLANET_COLORS.get('MC', 'red'))

    # Symbole planet i kreski na podziałce
    for planet, info in horoscope.positions.items():
        lon = (info['longitude'] - horoscope.asc) % 360
        angle = np.deg2rad(lon)
        color = PLANET_COLORS.get(planet, 'black')
        symbol = PLANET_SYMBOLS.get(planet, planet[0])

        # Obliczenia pozycji w znaku
        abs_lon = info['longitude'] % 360
        zodiac_index = int(abs_lon // 30)
        deg_in_sign = abs_lon % 30
        degrees = int(deg_in_sign)
        minutes = int(round((deg_in_sign - degrees) * 60)) % 60
        sign_str = ZODIAC_SIGNS[zodiac_index]

        # Kreska pozycji planety
        ax.plot([angle, angle], [0.95, 1.01], color=color, lw=1.8, zorder=10)
        ax.plot([angle, angle], [0.51, 0.48], color=color, lw=1.8, zorder=10)

        # Symbol planety (środek pierścienia)
        ax.text(angle, 0.88, symbol, fontsize=16, ha='center',
                va='center', fontweight='bold', color=color)

        # Kierunek: górna część wykresu
        if 90 <= lon <= 270:
            va_main = 'top'
            offset = -0.03
        else:
            va_main = 'bottom'
            offset = +0.03

        # Pozycja w stopniach i znakach
        ax.text(angle, 0.75 + offset, f"{degrees}°", fontsize=9,
                ha='center', va=va_main, color='black')
        ax.text(angle, 0.7 + offset, f"{minutes:02d}′", fontsize=9,
                ha='center', va=va_main, color='black')
        ax.text(angle, 0.65 + offset, sign_str, fontsize=13,
                ha='center', va=va_main, color='black')
        
        # Oblicz aspekty
        aspects = calculate_aspects(horoscope.positions, ASPECTS)

        # Rysuj aspekty
        for p1, p2, name, color in aspects:
            lon1 = (horoscope.positions[p1]['longitude'] - horoscope.asc) % 360
            lon2 = (horoscope.positions[p2]['longitude'] - horoscope.asc) % 360
            angle1 = np.deg2rad(lon1)
            angle2 = np.deg2rad(lon2)
            ax.plot([angle1, angle2], [0.5, 0.5], color=color, lw=1, alpha=0.8, zorder=0)



    if save_path:
        plt.savefig(save_path, bbox_inches='tight', dpi=300)
    else:
        plt.show()
