# -*- coding: utf-8 -*-
"""
radix_wheel.py - Horoskoprad (Radix-Rad) im Sternenklarheit-Stil.
Zeichnet aus einem radix_engine-Chart ein klassisches Horoskoprad:
Tierkreis-Ring mit Glyphen, 12 Haeuser, Planeten (mit Kollisionsvermeidung),
Aspektlinien im Zentrum, AC/MC-Achsen. Warmer Cream-Hintergrund, Gold-Akzente.
"""
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.patches import Wedge, Circle

# ---------- Farben (Sternenklarheit) ----------
BG = '#FAF8F3'
GOLD = '#B8923D'
DARK = '#3D3D3A'
TEXT2 = '#5F5E5A'
RING_EDGE = '#CFC9BA'

# Element-Farben (dezent) fuer die 12 Zeichen
ELEMENT_FILL = {
    'Feuer': '#F3DFD6', 'Erde': '#E5EBD8', 'Luft': '#F3EBCF', 'Wasser': '#DCE6EA',
}
ZEICHEN = ['Widder','Stier','Zwillinge','Krebs','Löwe','Jungfrau',
           'Waage','Skorpion','Schütze','Steinbock','Wassermann','Fische']
ZEICHEN_GLYPH = ['\u2648','\u2649','\u264A','\u264B','\u264C','\u264D',
                 '\u264E','\u264F','\u2650','\u2651','\u2652','\u2653']
ZEICHEN_ELEMENT = ['Feuer','Erde','Luft','Wasser','Feuer','Erde',
                   'Luft','Wasser','Feuer','Erde','Luft','Wasser']

PLANET_GLYPH = {
    'Sonne':'\u2609','Mond':'\u263D','Merkur':'\u263F','Venus':'\u2640',
    'Mars':'\u2642','Jupiter':'\u2643','Saturn':'\u2644','Uranus':'\u2645',
    'Neptun':'\u2646','Pluto':'\u2647','Chiron':'\u26B7','Mondknoten':'\u260A',
}

# Aspekte: Winkel -> (Orbis, Farbe, Linienstil)
ASPEKTE = [
    (0,   8, '#B8923D', 'solid'),    # Konjunktion - Gold
    (60,  4, '#3B6D8C', 'solid'),    # Sextil - Blau (harmonisch)
    (90,  6, '#A93226', 'solid'),    # Quadrat - Rot (Spannung)
    (120, 6, '#3B6D11', 'solid'),    # Trigon - Gruen (harmonisch)
    (180, 8, '#A93226', 'solid'),    # Opposition - Rot (Spannung)
]


def _ang(lon, ac):
    """ekliptische Laenge -> Plot-Winkel (Grad, math. Sinn). AC links (180 Grad)."""
    return np.radians(180.0 + (lon - ac))


def _xy(lon, ac, r):
    a = _ang(lon, ac)
    return r * np.cos(a), r * np.sin(a)


def render_wheel(chart, outfile, subtitle_extra=None):
    ac = chart['ac']
    mc = chart['mc']
    cusps = [h['laenge'] for h in chart['haeuser']]
    planeten = chart['planeten']

    fig, ax = plt.subplots(figsize=(10, 10.6), dpi=200)
    fig.patch.set_facecolor(BG)
    ax.set_facecolor(BG)
    ax.set_xlim(-1.18, 1.18)
    ax.set_ylim(-1.18, 1.28)
    ax.set_aspect('equal')
    ax.axis('off')

    R_OUT, R_ZOD, R_HOUSE, R_INNER = 1.0, 0.86, 0.70, 0.52

    # ---------- 1. Tierkreis-Ring: 12 Sektoren ----------
    for i in range(12):
        z_start = i * 30.0
        a0 = 180.0 + (z_start - ac)
        wedge = Wedge((0, 0), R_OUT, a0, a0 + 30.0, width=R_OUT - R_ZOD,
                      facecolor=ELEMENT_FILL[ZEICHEN_ELEMENT[i]],
                      edgecolor=RING_EDGE, lw=0.8, zorder=2)
        ax.add_patch(wedge)
        # Glyph in Sektor-Mitte
        gx, gy = _xy(z_start + 15.0, ac, (R_OUT + R_ZOD) / 2)
        ax.text(gx, gy, ZEICHEN_GLYPH[i], ha='center', va='center',
                fontsize=16, color=DARK, zorder=3)

    # 5-Grad-Ticks am Tierkreis-Innenrand
    for deg in range(0, 360, 5):
        r1 = R_ZOD
        r2 = R_ZOD - (0.035 if deg % 30 == 0 else 0.018)
        x1, y1 = _xy(deg, ac, r1); x2, y2 = _xy(deg, ac, r2)
        ax.plot([x1, x2], [y1, y2], color=RING_EDGE,
                lw=1.1 if deg % 30 == 0 else 0.6, zorder=2)

    ax.add_patch(Circle((0, 0), R_OUT, fill=False, edgecolor=GOLD, lw=1.4, zorder=4))
    ax.add_patch(Circle((0, 0), R_ZOD, fill=False, edgecolor=RING_EDGE, lw=1.0, zorder=4))
    ax.add_patch(Circle((0, 0), R_HOUSE, fill=False, edgecolor=RING_EDGE, lw=1.0, zorder=4))
    ax.add_patch(Circle((0, 0), R_INNER, fill=False, edgecolor=RING_EDGE, lw=0.8, zorder=4))

    # ---------- 2. Haeuser ----------
    for i in range(12):
        cusp = cusps[i]
        x1, y1 = _xy(cusp, ac, R_INNER)
        x2, y2 = _xy(cusp, ac, R_HOUSE)
        is_axis = i in (0, 3, 6, 9)  # AC, IC, DC, MC
        ax.plot([x1, x2], [y1, y2], color=(GOLD if is_axis else RING_EDGE),
                lw=(1.8 if is_axis else 0.9), zorder=3)
        # Hausnummer in Sektor-Mitte (zwischen cusp[i] und cusp[i+1])
        nxt = cusps[(i + 1) % 12]
        span = (nxt - cusp) % 360.0
        mid = cusp + span / 2.0
        nx, ny = _xy(mid, ac, (R_HOUSE + R_INNER) / 2)
        ax.text(nx, ny, str(i + 1), ha='center', va='center',
                fontsize=9, color=TEXT2, zorder=5,
                bbox=dict(boxstyle='circle,pad=0.12', facecolor=BG,
                          edgecolor='none', alpha=0.7))

    # ---------- 3. AC / MC Beschriftung ----------
    for lon, label in [(ac, 'AC'), (mc, 'MC'),
                       ((ac + 180) % 360, 'DC'), ((mc + 180) % 360, 'IC')]:
        lx, ly = _xy(lon, ac, R_OUT + 0.07)
        ax.text(lx, ly, label, ha='center', va='center', fontsize=11,
                color=GOLD, fontweight='bold', zorder=6)

    # ---------- 4. Planeten (mit Kollisionsvermeidung im Winkel) ----------
    order = sorted(range(len(planeten)), key=lambda k: planeten[k]['laenge'])
    placed = []  # (plot_winkel_grad)
    MINSEP = 7.0
    for k in order:
        p = planeten[k]
        base = (180.0 + (p['laenge'] - ac)) % 360.0
        disp = base
        # nach hinten verschieben, bis Mindestabstand zu bereits platzierten
        for _ in range(40):
            clash = any(abs(((disp - q + 180) % 360) - 180) < MINSEP for q in placed)
            if not clash:
                break
            disp += 1.0
        placed.append(disp)
        a = np.radians(disp)
        # Marker am wahren Ort (kleiner Punkt am Haus-Ring)
        tx, ty = _xy(p['laenge'], ac, R_HOUSE)
        ax.plot(tx, ty, 'o', color=GOLD, markersize=2.5, zorder=6)
        # Glyph am (ggf. verschobenen) Display-Winkel
        gx, gy = R_INNER + 0.085, 0
        px, py = (R_INNER + 0.10) * np.cos(a), (R_INNER + 0.10) * np.sin(a)
        # Verbindungslinie Marker -> Glyph
        ax.plot([tx, px], [ty, py], color=RING_EDGE, lw=0.5, zorder=5)
        ax.text(px, py, PLANET_GLYPH.get(p['name'], '?'), ha='center', va='center',
                fontsize=13.5, color=DARK, zorder=7)
        # Grad-Angabe knapp innerhalb
        dx, dy = (R_INNER - 0.04) * np.cos(a), (R_INNER - 0.04) * np.sin(a)
        rtxt = f"{p['grad']}\u00b0{'R' if p['retro'] else ''}"
        ax.text(dx, dy, rtxt, ha='center', va='center', fontsize=6.5,
                color=TEXT2, zorder=7)

    # ---------- 5. Aspektlinien im Zentrum ----------
    n = len(planeten)
    for i in range(n):
        for j in range(i + 1, n):
            d = abs(planeten[i]['laenge'] - planeten[j]['laenge']) % 360.0
            if d > 180:
                d = 360 - d
            for ang, orb, col, ls in ASPEKTE:
                if abs(d - ang) <= orb:
                    x1, y1 = _xy(planeten[i]['laenge'], ac, R_INNER)
                    x2, y2 = _xy(planeten[j]['laenge'], ac, R_INNER)
                    ax.plot([x1, x2], [y1, y2], color=col, lw=0.8,
                            linestyle=ls, alpha=0.5, zorder=2)
                    break

    # ---------- 6. Titel ----------
    ax.text(0, 1.20, chart['name'], ha='center', va='center',
            fontsize=21, color=DARK, fontweight='bold', fontfamily='DejaVu Serif')
    ax.plot([-0.32, -0.08], [1.13, 1.13], color=GOLD, lw=1.0)
    ax.plot([0.08, 0.32], [1.13, 1.13], color=GOLD, lw=1.0)
    ax.text(0, 1.13, '\u2726', ha='center', va='center', fontsize=11, color=GOLD)
    if subtitle_extra:
        ax.text(0, -1.13, subtitle_extra, ha='center', va='center',
                fontsize=10.5, color=TEXT2)
    ax.text(1.12, -1.14, 'Grundhoroskop', fontsize=8.5, color=GOLD,
            ha='right', style='italic')

    plt.savefig(outfile, dpi=200, bbox_inches='tight', facecolor=BG, edgecolor='none')
    plt.close(fig)
    return outfile


if __name__ == '__main__':
    import swisseph as swe
    swe.set_ephe_path('/home/claude/ephe')
    from radix_engine import compute_radix
    chart = compute_radix(1976, 3, 31, 15, 0, 53.55, 10.0,
                          tz='Europe/Berlin', hsys=b'K', name='Dirk Zessin')
    out = render_wheel(chart, '/home/claude/wheel_dirk_test.png',
                       subtitle_extra='31.03.1976 \u00b7 15:00 \u00b7 Hamburg \u00b7 Koch')
    print('Rad gerendert:', out)
