import EventKit
import Foundation

// Accept CLI args: --days-back N --days-ahead N
var daysBack = 1
var daysAhead = 14
var args = CommandLine.arguments
for i in 0..<args.count {
    if args[i] == "--days-back", i + 1 < args.count, let n = Int(args[i + 1]) { daysBack = n }
    if args[i] == "--days-ahead", i + 1 < args.count, let n = Int(args[i + 1]) { daysAhead = n }
}

let store = EKEventStore()
let status = EKEventStore.authorizationStatus(for: .event)

switch status {
case .fullAccess, .authorized:
    break
case .notDetermined:
    let sem = DispatchSemaphore(value: 0)
    store.requestFullAccessToEvents(completion: { granted, error in
        if !granted {
            fputs("{\"error\":\"access_denied\",\"message\":\"Calendar access was denied. Grant access in System Settings > Privacy & Security > Calendars.\"}\n", stderr)
            exit(1)
        }
        sem.signal()
    })
    sem.wait()
default:
    fputs("{\"error\":\"access_denied\",\"message\":\"Calendar access denied (status=\(status.rawValue)). Grant access to your terminal in System Settings > Privacy & Security > Calendars.\"}\n", stderr)
    exit(1)
}

let cal = Calendar.current
let start = cal.date(byAdding: .day, value: -daysBack, to: Date())!
let end = cal.date(byAdding: .day, value: daysAhead, to: Date())!
let pred = store.predicateForEvents(withStart: start, end: end, calendars: nil)
let events = store.events(matching: pred)

let fmt = ISO8601DateFormatter()
var arr: [[String: Any]] = []

for e in events {
    var d: [String: Any] = [
        "title": e.title ?? "(no title)",
        "start": fmt.string(from: e.startDate),
        "end": fmt.string(from: e.endDate),
        "allDay": e.isAllDay,
        "calendar": e.calendar.title,
        "uid": e.calendarItemIdentifier,
        "location": e.location ?? ""
    ]
    if let notes = e.notes, !notes.isEmpty {
        d["notes"] = String(notes.prefix(500))
    }
    if let attendees = e.attendees, !attendees.isEmpty {
        d["attendees"] = attendees.compactMap { att -> [String: Any]? in
            let name = att.name ?? ""
            let email = att.url.absoluteString.replacingOccurrences(of: "mailto:", with: "")
            let status: String
            switch att.participantStatus {
            case .accepted: status = "accepted"
            case .declined: status = "declined"
            case .tentative: status = "tentative"
            case .pending: status = "pending"
            default: status = "unknown"
            }
            let isOrganizer = att.isCurrentUser ? false : (att.participantRole == .chair)
            return ["name": name, "email": email, "status": status, "organizer": isOrganizer]
        }
    }
    if let org = e.organizer {
        d["organizer"] = org.name ?? org.url.absoluteString.replacingOccurrences(of: "mailto:", with: "")
    }
    arr.append(d)
}

if let data = try? JSONSerialization.data(withJSONObject: arr, options: []),
   let str = String(data: data, encoding: .utf8) {
    print(str)
}
