#!/usr/bin/env python3
import warnings
from datetime import datetime
from astropy.coordinates import SkyCoord, FK5
from astropy.time import Time
import astropy.units as u
from erfa import ErfaWarning

# ERFA-Warnungen bezüglich fehlender Distanz/Parallaxe stummschalten
warnings.simplefilter("ignore", category=ErfaWarning)

# Die 57 Navigationssterne des Nautical Almanac (Stand J2000.0)
# Format: (Nr, Name, Bayer, Mag, RA_J2000, Dec_J2000, Dist_ly, PM_RA_mas, PM_Dec_mas)
STARS = [
    (1, "Alpheratz", "alpha And", 2.06, "00h08m23.3s", "+29d05m26s", 97.0, 135.7, -162.9),
    (2, "Ankaa", "alpha Phe", 2.39, "00h26m17.1s", "-42d18m22s", 85.0, 224.9, -353.8),
    (3, "Schedar", "alpha Cas", 2.24, "00h40m30.4s", "+56d32m15s", 228.0, 50.4, -32.1),
    (4, "Diphda", "beta Cet", 2.04, "00h43m35.4s", "-17d59m12s", 96.0, 232.8, -32.1),
    (5, "Achernar", "alpha Eri", 0.45, "01h37m42.9s", "-57d14m12s", 139.0, 87.0, -38.2),
    (6, "Hamal", "alpha Ari", 2.01, "02h07m10.4s", "+23d27m45s", 65.8, 190.7, -145.8),
    (7, "Acamar", "theta Eri", 2.88, "02h58m15.7s", "-40d18m17s", 161.0, 50.8, 30.6),
    (8, "Menkar", "alpha Cet", 2.54, "03h02m16.8s", "+04d05m23s", 249.0, -10.6, -77.8),
    (9, "Mirfak", "alpha Per", 1.79, "03h24m19.4s", "+49d51m40s", 510.0, 24.1, -25.7),
    (10, "Aldebaran", "alpha Tau", 0.85, "04h35m55.2s", "+16d30m33s", 65.3, 63.5, -189.4),
    (11, "Rigel", "beta Ori", 0.18, "05h14m32.3s", "-08d12m06s", 860.0, 1.9, -0.6),
    (12, "Capella", "alpha Aur", 0.08, "05h16m41.4s", "+45d59m53s", 42.9, 75.5, -427.1),
    (13, "Bellatrix", "gamma Ori", 1.64, "05h25m07.9s", "+06d20m59s", 250.0, -8.8, -13.3),
    (14, "Elnath", "beta Tau", 1.65, "05h26m17.5s", "+28d36m27s", 134.0, 22.4, -173.5),
    (15, "Alnilam", "epsilon Ori", 1.69, "05h36m12.8s", "-01d12m07s", 2000.0, 1.5, -1.0),
    (16, "Betelgeuse", "alpha Ori", 0.50, "05h55m10.3s", "+07d24m26s", 640.0, 27.3, 10.9),
    (17, "Canopus", "alpha Car", -0.74, "06h23m57.1s", "-52d41m45s", 310.0, 19.9, 23.2),
    (18, "Sirius", "alpha CMa", -1.46, "06h45m08.9s", "-16d42m58s", 8.6, -546.0, -1223.1),
    (19, "Adhara", "epsilon CMa", 1.50, "06h58m37.6s", "-28d58m19s", 430.0, 2.8, 2.0),
    (20, "Procyon", "alpha CMi", 0.38, "07h39m18.1s", "+05d13m30s", 11.4, -716.6, -1034.6),
    (21, "Pollux", "beta Gem", 1.14, "07h45m18.9s", "+28d01m34s", 33.7, -625.7, -45.9),
    (22, "Avior", "epsilon Car", 1.86, "08h22m30.8s", "-59d30m35s", 630.0, -18.7, 10.3),
    (23, "Suhail", "lambda Vel", 2.21, "09h07m59.8s", "-43d25m57s", 570.0, -18.9, 9.9),
    (24, "Miaplacidus", "beta Car", 1.67, "09h13m12.0s", "-69d43m02s", 111.0, -157.9, 155.6),
    (25, "Alphard", "alpha Hya", 1.98, "09h27m35.2s", "-08d39m31s", 177.0, -14.4, 33.3),
    (26, "Regulus", "alpha Leo", 1.36, "10h08m22.3s", "+11d58m02s", 79.3, -248.5, 5.6),
    (27, "Dubhe", "alpha UMa", 1.79, "11h03m43.7s", "+61d45m03s", 123.0, -136.5, -35.2),
    (28, "Denebola", "beta Leo", 2.14, "11h49m03.6s", "+14d34m19s", 35.9, -499.0, -113.8),
    (29, "Gienah", "gamma Crv", 2.58, "12h15m48.4s", "-17d32m31s", 154.0, -158.0, 18.0),
    (30, "Acrux", "alpha Cru", 0.77, "12h26m35.9s", "-63d05m57s", 320.0, -35.2, -14.7),
    (31, "Gacrux", "gamma Cru", 1.64, "12h31m10.0s", "-57d06m48s", 88.6, 28.1, -263.8),
    (32, "Alioth", "epsilon UMa", 1.76, "12h54m01.7s", "+55d57m35s", 82.6, 111.7, -8.9),
    (33, "Spica", "alpha Vir", 0.98, "13h25m11.6s", "-11d09m41s", 250.0, -42.5, -31.7),
    (34, "Alkaid", "eta UMa", 1.85, "13h47m32.4s", "+49d18m48s", 101.0, -121.2, -15.6),
    (35, "Hadar", "beta Cen", 0.61, "14h03m49.4s", "-60d22m23s", 390.0, -33.4, -23.2),
    (36, "Menkent", "theta Cen", 2.06, "14h06m41.0s", "-36d22m12s", 58.8, -520.5, -518.2),
    (37, "Arktur", "alpha Boo", -0.05, "14h15m39.7s", "+19d10m57s", 36.71, -1093.9, -1999.4),
    (38, "Rigil Kentaurus", "alpha Cen", -0.01, "14h39m36.5s", "-60d50m02s", 4.37, -3678.2, 481.8),
    (39, "Zubenelgenubi", "alpha Lib", 2.75, "14h50m52.8s", "-16d02m30s", 75.8, -103.5, -68.3),
    (40, "Kochab", "beta UMi", 2.07, "14h50m42.3s", "+74d09m20s", 130.0, -32.3, 11.8),
    (41, "Alphecca", "alpha CrB", 2.22, "15h34m41.3s", "+26d42m53s", 75.0, 120.4, -89.4),
    (42, "Antares", "alpha Sco", 1.06, "16h29m24.4s", "-26d25m55s", 550.0, -12.1, -23.3),
    (43, "Atria", "alpha TrA", 1.91, "16h48m39.9s", "-69d01m40s", 391.0, 38.2, -30.0),
    (44, "Sabik", "eta Oph", 2.43, "17h10m22.7s", "-15d43m30s", 88.0, 26.6, 92.8),
    (45, "Shaula", "lambda Sco", 1.62, "17h33m36.5s", "-37d06m14s", 570.0, -8.9, -25.2),
    (46, "Rasalhague", "alpha Oph", 2.08, "17h34m56.0s", "+12d33m36s", 48.6, 112.2, -222.1),
    (47, "Eltanin", "gamma Dra", 2.24, "17h56m36.4s", "+51d29m20s", 154.0, -8.5, -23.1),
    (48, "Kaus Australis", "epsilon Sgr", 1.79, "18h24m10.3s", "-34d23m05s", 143.0, -39.6, -124.1),
    (49, "Vega", "alpha Lyr", 0.03, "18h36m56.3s", "+38d47m01s", 25.04, 200.9, 286.2),
    (50, "Nunki", "sigma Sgr", 2.05, "18h55m15.9s", "-26d17m48s", 228.0, 15.3, -53.2),
    (51, "Altair", "alpha Aql", 0.77, "19h50m47.0s", "+08d52m06s", 16.73, 536.2, 385.3),
    (52, "Peacock", "alpha Pav", 1.94, "20h25m38.9s", "-56d44m06s", 179.0, 7.3, -86.1),
    (53, "Deneb", "alpha Cyg", 1.25, "20h41m25.9s", "+45d16m49s", 2600.0, 2.0, 2.0),
    (54, "Enif", "epsilon Peg", 2.38, "21h44m11.2s", "+09d52m30s", 690.0, 27.2, 0.8),
    (55, "Alnair", "alpha Gru", 1.73, "22h08m14.0s", "-46d57m40s", 101.0, 127.8, -147.9),
    (56, "Fomalhaut", "alpha PsA", 1.17, "22h57m39.1s", "-29d37m20s", 25.1, 329.2, -164.2),
    (57, "Markab", "alpha Peg", 2.49, "23h04m45.6s", "+15d12m19s", 133.0, 60.4, -41.3)
]

def update_all_files():
    now_utc = Time.now()
    local_time_str = datetime.now().strftime("%d.%m.%Y um %H:%M:%S Uhr")
    results = []

    for nr, name, bayer, mag, ra_str, dec_str, dist_ly, pm_ra, pm_dec in STARS:
        star_j2000 = SkyCoord(
            ra=ra_str,
            dec=dec_str,
            distance=dist_ly * u.lightyear,
            pm_ra_cosdec=pm_ra * u.mas / u.yr,
            pm_dec=pm_dec * u.mas / u.yr,
            frame="icrs",
            obstime=Time("J2000.0")
        )

        star_pm = star_j2000.apply_space_motion(new_obstime=now_utc)
        star_apparent = star_pm.transform_to(FK5(equinox=now_utc))

        ra_j2000 = star_j2000.ra.to_string(unit=u.hour, sep=('h ', 'm ', 's'), precision=1)
        dec_j2000 = star_j2000.dec.to_string(unit=u.degree, sep=('° ', "' ", "''"), precision=0, alwayssign=True)

        ra_app = star_apparent.ra.to_string(unit=u.hour, sep=('h ', 'm ', 's'), precision=2)
        dec_app = star_apparent.dec.to_string(unit=u.degree, sep=('° ', "' ", "''"), precision=1, alwayssign=True)

        results.append({
            'nr': nr, 'name': name, 'bayer': bayer, 'mag': mag,
            'ra_j2000': ra_j2000, 'dec_j2000': dec_j2000,
            'ra_app': ra_app, 'dec_app': dec_app
        })

    # -------------------------------------------------------------------------
    # 1. HTML Generieren (mit UTF-8 Header und &deg; Entität)
    # -------------------------------------------------------------------------
    with open("sterne_datum.html", "w", encoding="utf-8") as f:
        f.write("<!DOCTYPE html>\n<html lang='de'>\n<head>\n")
        f.write("  <meta charset='UTF-8'>\n")
        f.write("  <title>Sternenkoordinaten des Datums</title>\n")
        f.write("  <style>body { font-family: monospace; } table { border-collapse: collapse; } th, td { padding: 4px 8px; }</style>\n")
        f.write("</head>\n<body>\n")
        f.write(f"<!-- Generiert am {local_time_str} -->\n")
        f.write("<table border='1'>\n")
        f.write("  <thead>\n    <tr style='background-color: #e0e0e0;'>\n")
        f.write("      <th>Nr.</th><th>Name</th><th>Bayer</th><th>Mag</th><th>RA (J2000)</th><th>Dec (J2000)</th><th>RA (des Datums)</th><th>Dec (des Datums)</th>\n")
        f.write("    </tr>\n  </thead>\n  <tbody>\n")
        for r in results:
            dec_j2000_html = r['dec_j2000'].replace('°', '&deg;')
            dec_app_html = r['dec_app'].replace('°', '&deg;')
            
            f.write(f"    <tr><td>{r['nr']}</td><td><b>{r['name']}</b></td><td>{r['bayer']}</td><td>{r['mag']:.2f}</td>")
            f.write(f"<td>{r['ra_j2000']}</td><td>{dec_j2000_html}</td><td><b>{r['ra_app']}</b></td><td><b>{dec_app_html}</b></td></tr>\n")
        f.write("  </tbody>\n</table>\n")
        f.write("</body>\n</html>\n")

    # -------------------------------------------------------------------------
    # 2. LaTeX Generieren (als eigenständiges, vollständiges Dokument)
    # -------------------------------------------------------------------------
    with open("sterne_datum.tex", "w", encoding="utf-8") as f:
        f.write(r"\documentclass[a4paper,10pt]{article}" + "\n")
        f.write(r"\usepackage[utf8]{inputenc}" + "\n")
        f.write(r"\usepackage[ngerman]{babel}" + "\n")
        f.write(r"\usepackage[margin=1.5cm]{geometry}" + "\n")
        f.write(r"\usepackage{longtable}" + "\n")
        f.write(r"\usepackage{booktabs}" + "\n")
        f.write(r"\begin{document}" + "\n\n")
        f.write(f"% Generiert am {local_time_str}\n")
        f.write(r"\begin{longtable}{r l l r r r | r r}" + "\n")
        f.write(r"\toprule" + "\n")
        f.write(r"\textbf{Nr.} & \textbf{Name} & \textbf{Bayer} & \textbf{Mag} & \textbf{RA (J2000)} & \textbf{Dec (J2000)} & \textbf{RA (des Datums)} & \textbf{Dec (des Datums)} \\" + "\n")
        f.write(r"\midrule" + "\n")
        f.write(r"\endfirsthead" + "\n")
        
        for r in results:
            bayer_raw = r['bayer'].split()
            greek_letter = bayer_raw[0]
            constellation = bayer_raw[1] if len(bayer_raw) > 1 else ""
            bayer_tex = f"$\\{greek_letter}$ {constellation}"

            dec_j2000_tex = f"${r['dec_j2000'].replace('°', r'^\circ').replace('\'\'', r'^{\prime\prime}').replace('\'', r'^\prime')}$"
            dec_app_tex = f"${r['dec_app'].replace('°', r'^\circ').replace('\'\'', r'^{\prime\prime}').replace('\'', r'^\prime')}$"

            f.write(f"{r['nr']} & {r['name']} & {bayer_tex} & {r['mag']:.2f} & {r['ra_j2000']} & {dec_j2000_tex} & {r['ra_app']} & {dec_app_tex} \\\\\n")
            
        f.write(r"\bottomrule" + "\n")
        f.write(r"\end{longtable}" + "\n")
        f.write(r"\end{document}" + "\n")

    # -------------------------------------------------------------------------
    # 3. Plain Text Generieren
    # -------------------------------------------------------------------------
    with open("sterne_datum.txt", "w", encoding="utf-8") as f:
        f.write(f"STERNENKOORDINATEN (Berechnet am {local_time_str})\n")
        f.write("=" * 90 + "\n")
        f.write(f"{'Nr.':<4} {'Name':<16} {'RA (J2000)':<16} {'Dec (J2000)':<14} | {'RA (des Datums)':<18} {'Dec (des Datums)':<16}\n")
        f.write("-" * 90 + "\n")
        for r in results:
            f.write(f"{r['nr']:<4} {r['name']:<16} {r['ra_j2000']:<16} {r['dec_j2000']:<14} | {r['ra_app']:<18} {r['dec_app']:<16}\n")
        f.write("=" * 90 + "\n")

    print(f"57 Sterne erfolgreich verarbeitet und Dateien aktualisiert ({local_time_str}).")

if __name__ == "__main__":
    update_all_files()
