#!/usr/bin/env python3
"""
Export Proton Calendar events as read-only .ics feeds for IRIS.
Reads all calendars via the proton-cal CLI, writes one combined feed plus
one feed per calendar into OUTDIR.
"""
import json, subprocess, os, sys
from datetime import datetime, timezone

# OUTDIR and PROTON_CAL are relative to the script's location
OUTDIR = "."
PROTON_CAL = "./bin/proton-cal"
CONFIG_DIR = ".config/proton-cal"
DAYS = 60  # look-ahead window

def ics_escape(s):
    return (s or "").replace("\\", "\\\\").replace(";", "\\;").replace(",", "\\,").replace("\n", "\\n")

def to_utc(s):
    """Convert an ISO timestamp (may end in Z or have +HH:MM) to UTC 'YYYYMMDDTHHMMSSZ'."""
    if s.endswith("Z"):
        dt = datetime.fromisoformat(s.replace("Z", "+00:00"))
    else:
        dt = datetime.fromisoformat(s)
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return dt.astimezone(timezone.utc).strftime("%Y%m%dT%H%M%SZ")

def to_date(s):
    """All-day DATE value YYYYMMDD."""
    return s[:10].replace("-", "")

def event_to_vevent(ev):
    lines = ["BEGIN:VEVENT"]
    lines.append(f"UID:{ev.get('uid','')}")
    lines.append(f"DTSTAMP:{datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%SZ')}")

    all_day = bool(ev.get("all_day"))
    start = ev.get("start", "")
    end = ev.get("end", "")

    if all_day:
        lines.append(f"DTSTART;VALUE=DATE:{to_date(start)}")
        lines.append(f"DTEND;VALUE=DATE:{to_date(end)}")
    else:
        lines.append(f"DTSTART:{to_utc(start)}")
        lines.append(f"DTEND:{to_utc(end)}")

    lines.append(f"SUMMARY:{ics_escape(ev.get('summary'))}")

    desc = ev.get("description")
    if desc:
        lines.append(f"DESCRIPTION:{ics_escape(desc)}")
    end_line = "END:VEVENT"
    lines.append(end_line)
    return "\r\n".join(lines)

def build_calendar(cal_name, events):
    header = [
        "BEGIN:VCALENDAR",
        "VERSION:2.0",
        "PRODID:-//freedomain.meme//Proton ICS Export//EN",
        "CALSCALE:GREGORIAN",
        "METHOD:PUBLISH",
        f"X-WR-CALNAME:{cal_name}",
    ]
    body = [event_to_vevent(e) for e in events]
    footer = ["END:VCALENDAR"]
    return "\r\n".join(header + body + footer) + "\r\n"

def main():
    # Set HOME env var for proton-cal CLI
    os.environ["HOME"] = os.path.abspath(os.getcwd())

    out = subprocess.run(
        [PROTON_CAL, "events", "--all-calendars", "--days", str(DAYS), "-o", "json"],
        capture_output=True, text=True
    )
    if out.returncode != 0:
        print("ERROR running proton-cal:", out.stderr, file=sys.stderr)
        sys.exit(1)
    try:
        events = json.loads(out.stdout)
    except json.JSONDecodeError as e:
        print("ERROR parsing events JSON:", e, file=sys.stderr)
        print("stdout head:", out.stdout[:500], file=sys.stderr)
        sys.exit(1)

    os.makedirs(OUTDIR, exist_ok=True)

    combined = build_calendar("Proton Kalender (Kombiniert)", events)
    with open(os.path.join(OUTDIR, "combined.ics"), "w") as f:
        f.write(combined)

    by_cal = {}
    for e in events:
        by_cal.setdefault(e.get("calendar_name", "Unknown"), []).append(e)

    for name, evs in by_cal.items():
        safe = "".join(c if c.isalnum() else "_" for c in name)
        with open(os.path.join(OUTDIR, f"{safe}.ics"), "w") as f:
            f.write(build_calendar(name, evs))

    print(f"Wrote {len(events)} events across {len(by_cal)} calendars to {os.path.join(os.getcwd(), OUTDIR)}")
    for name in by_cal:
        safe = "".join(c if c.isalnum() else "_" for c in name)
        print(f"  - {name}: {len(by_cal[name])} events -> {os.path.join(os.getcwd(), OUTDIR, f'{safe}.ics')}")

if __name__ == "__main__":
    main()
