#!/usr/bin/env python3
"""
Fast parallel GCal wipe (May 1+ events) + recreate Robert, Lisa, Shy A events.
"""
import json
import sys
import time
import urllib.request
import urllib.parse
import urllib.error
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime, timezone

CLIENT_ID     = "499447514870-s99jadtrmrj3n11ct62oth8mv32g10r8.apps.googleusercontent.com"
CLIENT_SECRET = "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"
REFRESH_TOKEN = "1//01ISf7Sht-c6FCgYIARAAGAESNwF-L9IrGz9IkMDdZ1YuKbo9zndt849n_qDJTwHHN_1iEQtaOztye4Wr6sAmXiOVv1BCsIcKfFQ"

CONSULTATIONS = "c_9014c7686c0d658621c857d4bee46f26b13a7918350dd79132a8bc9664d7592b@group.calendar.google.com"
LL_ADULT      = "c_13274385edad5496c1427efba712e3d4b2cf9d25ddef582c02abb92c129c2b54@group.calendar.google.com"
LL_MYO        = "c_bbf48fa738d3dcb7ddca59be37ff59471308d8f734ff2a6979f3550778150fd0@group.calendar.google.com"

WIPE_CALENDARS = [CONSULTATIONS, LL_ADULT, LL_MYO]

# May 1, 2026 00:00:00 UTC
WIPE_FROM_ISO = "2026-05-01T00:00:00Z"

ACCESS_TOKEN = None

# ── auth ────────────────────────────────────────────────────────────────────

def get_access_token():
    global ACCESS_TOKEN
    data = urllib.parse.urlencode({
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "refresh_token": REFRESH_TOKEN,
        "grant_type": "refresh_token",
    }).encode()
    req = urllib.request.Request("https://oauth2.googleapis.com/token", data=data)
    with urllib.request.urlopen(req) as r:
        resp = json.loads(r.read())
    ACCESS_TOKEN = resp["access_token"]
    print(f"[auth] token obtained")
    return ACCESS_TOKEN

def headers():
    return {"Authorization": f"Bearer {ACCESS_TOKEN}", "Content-Type": "application/json"}

# ── gcal helpers ─────────────────────────────────────────────────────────────

def gcal_get(url):
    req = urllib.request.Request(url, headers=headers())
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read())

def gcal_delete(cal_id, event_id):
    url = f"https://www.googleapis.com/calendar/v3/calendars/{urllib.parse.quote(cal_id, safe='')}/events/{urllib.parse.quote(event_id, safe='')}"
    req = urllib.request.Request(url, headers=headers(), method="DELETE")
    try:
        with urllib.request.urlopen(req) as r:
            return True
    except urllib.error.HTTPError as e:
        if e.code == 410:  # Already deleted
            return True
        print(f"  [delete error] {event_id}: HTTP {e.code}", flush=True)
        return False

def gcal_create(cal_id, summary, start_iso, end_iso):
    url = f"https://www.googleapis.com/calendar/v3/calendars/{urllib.parse.quote(cal_id, safe='')}/events"
    body = json.dumps({
        "summary": summary,
        "start": {"dateTime": start_iso},
        "end": {"dateTime": end_iso},
    }).encode()
    req = urllib.request.Request(url, data=body, headers=headers(), method="POST")
    with urllib.request.urlopen(req) as r:
        ev = json.loads(r.read())
        return ev["id"]

# ── list all events from May 1 ────────────────────────────────────────────────

def list_events_from(cal_id, time_min=WIPE_FROM_ISO):
    events = []
    page_token = None
    while True:
        params = {
            "timeMin": time_min,
            "maxResults": 2500,
            "singleEvents": "true",
            "orderBy": "startTime",
        }
        if page_token:
            params["pageToken"] = page_token
        url = (f"https://www.googleapis.com/calendar/v3/calendars/"
               f"{urllib.parse.quote(cal_id, safe='')}/events?"
               f"{urllib.parse.urlencode(params)}")
        data = gcal_get(url)
        items = data.get("items", [])
        events.extend(items)
        page_token = data.get("nextPageToken")
        if not page_token:
            break
    return events

# ── wipe ────────────────────────────────────────────────────────────────────

def wipe_calendar(cal_id, name):
    print(f"\n[wipe] listing events in {name}...", flush=True)
    events = list_events_from(cal_id)
    print(f"[wipe] {name}: {len(events)} events to delete", flush=True)
    if not events:
        return 0

    deleted = 0
    failed = 0
    with ThreadPoolExecutor(max_workers=20) as ex:
        futs = {ex.submit(gcal_delete, cal_id, ev["id"]): ev for ev in events}
        for i, fut in enumerate(as_completed(futs), 1):
            ok = fut.result()
            if ok:
                deleted += 1
            else:
                failed += 1
            if i % 50 == 0 or i == len(events):
                print(f"  {name}: {i}/{len(events)} processed ({deleted} ok, {failed} failed)", flush=True)

    print(f"[wipe] {name}: done — {deleted} deleted, {failed} failed", flush=True)
    return deleted

# ── create events ────────────────────────────────────────────────────────────

ROBERT_EVENTS = [
    ("Robert Brinkman", "2026-05-06T13:15:00-04:00", "2026-05-06T14:00:00-04:00"),
    ("Robert Brinkman", "2026-05-08T12:45:00-04:00", "2026-05-08T13:30:00-04:00"),
    ("Robert Brinkman", "2026-05-13T11:00:00-04:00", "2026-05-13T11:45:00-04:00"),
    ("Robert Brinkman", "2026-05-15T13:15:00-04:00", "2026-05-15T14:00:00-04:00"),
    ("Robert Brinkman", "2026-05-18T15:00:00-04:00", "2026-05-18T15:45:00-04:00"),
    ("Robert Brinkman", "2026-05-20T13:45:00-04:00", "2026-05-20T14:30:00-04:00"),
    ("Robert Brinkman", "2026-05-25T11:00:00-04:00", "2026-05-25T11:45:00-04:00"),
    ("Robert Brinkman", "2026-05-27T11:15:00-04:00", "2026-05-27T12:00:00-04:00"),
    ("Robert Brinkman", "2026-06-01T11:30:00-04:00", "2026-06-01T12:15:00-04:00"),
    ("Robert Brinkman", "2026-06-03T11:30:00-04:00", "2026-06-03T12:15:00-04:00"),
    ("Robert Brinkman", "2026-06-05T12:00:00-04:00", "2026-06-05T12:45:00-04:00"),
    ("Robert Brinkman", "2026-06-08T11:30:00-04:00", "2026-06-08T12:15:00-04:00"),
    ("Robert Brinkman", "2026-06-10T10:00:00-04:00", "2026-06-10T10:45:00-04:00"),
    ("Robert Brinkman", "2026-06-12T12:00:00-04:00", "2026-06-12T12:45:00-04:00"),
    ("Robert Brinkman", "2026-06-15T10:00:00-04:00", "2026-06-15T10:45:00-04:00"),
    ("Robert Brinkman", "2026-06-17T11:30:00-04:00", "2026-06-17T12:15:00-04:00"),
    ("Robert Brinkman", "2026-06-19T12:00:00-04:00", "2026-06-19T12:45:00-04:00"),
    ("Robert Brinkman", "2026-06-22T14:00:00-04:00", "2026-06-22T14:45:00-04:00"),
    ("Robert Brinkman", "2026-06-24T10:00:00-04:00", "2026-06-24T10:45:00-04:00"),
    ("Robert Brinkman", "2026-06-26T12:00:00-04:00", "2026-06-26T12:45:00-04:00"),
]

LISA_EVENTS = [
    ("Lisa Frank", "2026-05-04T10:00:00-04:00", "2026-05-04T10:45:00-04:00"),
    ("Lisa Frank", "2026-05-07T10:00:00-04:00", "2026-05-07T10:45:00-04:00"),
    ("Lisa Frank", "2026-05-11T10:30:00-04:00", "2026-05-11T11:15:00-04:00"),
    ("Lisa Frank", "2026-05-15T14:00:00-04:00", "2026-05-15T14:45:00-04:00"),
    ("Lisa Frank", "2026-05-21T13:15:00-04:00", "2026-05-21T14:00:00-04:00"),
    ("Lisa Frank", "2026-05-28T10:45:00-04:00", "2026-05-28T11:30:00-04:00"),
    ("Lisa Frank", "2026-06-01T13:00:00-04:00", "2026-06-01T13:45:00-04:00"),
    ("Lisa Frank", "2026-06-03T13:00:00-04:00", "2026-06-03T13:45:00-04:00"),
]

SHY_EVENTS = [
    ("Shy A", "2026-05-11T15:30:00-04:00", "2026-05-11T16:00:00-04:00"),
    ("Shy A", "2026-05-18T15:30:00-04:00", "2026-05-18T16:00:00-04:00"),
    ("Shy A", "2026-05-25T15:30:00-04:00", "2026-05-25T16:00:00-04:00"),
    ("Shy A", "2026-06-01T15:30:00-04:00", "2026-06-01T16:00:00-04:00"),
    ("Shy A", "2026-06-08T15:30:00-04:00", "2026-06-08T16:00:00-04:00"),
    ("Shy A", "2026-06-15T15:30:00-04:00", "2026-06-15T16:00:00-04:00"),
    ("Shy A", "2026-06-22T15:30:00-04:00", "2026-06-22T16:00:00-04:00"),
    ("Shy A", "2026-06-29T15:30:00-04:00", "2026-06-29T16:00:00-04:00"),
]

def create_batch(label, events, cal_id):
    print(f"\n[create] adding {len(events)} events for {label}...", flush=True)
    created = 0
    for (summary, start, end) in events:
        ev_id = gcal_create(cal_id, summary, start, end)
        print(f"  ✓ {summary}  {start}  → {ev_id}", flush=True)
        created += 1
        time.sleep(0.05)  # small courtesy delay
    print(f"[create] {label}: {created} events created", flush=True)

# ── main ─────────────────────────────────────────────────────────────────────

def main():
    get_access_token()

    # Step 1: Wipe all three calendars
    cal_names = {
        CONSULTATIONS: "Consultations",
        LL_ADULT: "LL Adult",
        LL_MYO: "LL Myo",
    }
    for cal_id in WIPE_CALENDARS:
        wipe_calendar(cal_id, cal_names[cal_id])

    print("\n" + "="*60, flush=True)
    print("WIPE COMPLETE. Starting event creation...", flush=True)
    print("="*60, flush=True)

    # Step 2: Recreate events — all in Consultations
    create_batch("Robert Brinkman", ROBERT_EVENTS, CONSULTATIONS)
    create_batch("Lisa Frank", LISA_EVENTS, CONSULTATIONS)
    create_batch("Shy A", SHY_EVENTS, CONSULTATIONS)

    print("\n" + "="*60, flush=True)
    print("ALL DONE", flush=True)
    print("="*60, flush=True)

if __name__ == "__main__":
    main()
