// Reminders bridge CORE — read + create reminders via the Mac's Reminders.app over AppleScript.
// Local, no cloud. Same osascript-from-engine pattern as Mail (Automation attributed to DewLink.app).
// Creating a reminder is a local write (not an outbound "send"), so it's allowed directly.

import { execFile } from "node:child_process";
const FS = "", RS = "";

function osa(script: string): Promise<{ ok: boolean; out: string; err?: string }> {
  return new Promise((resolve) => {
    execFile("osascript", ["-e", script], { maxBuffer: 4 * 1024 * 1024, timeout: 25_000 }, (e, stdout, stderr) => {
      if (e) {
        const err = (stderr || String(e)).trim();
        const perm = err.includes("-1743") || /not allowed|not authori[sz]ed/i.test(err);
        resolve({ ok: false, out: "", err: perm
          ? "Reminders automation not authorized yet — accept the prompt (or System Settings → Privacy & Security → Automation → DewLink → Reminders), then retry."
          : err });
      } else resolve({ ok: true, out: stdout });
    });
  });
}
const asStr = (s: string) => '"' + String(s ?? "").replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';

/// Open (incomplete) reminders, optionally from one list. Read-only.
export async function remindersList(a?: { list?: string; limit?: number }) {
  const limit = Math.min(a?.limit ?? 30, 100);
  const scope = a?.list ? `list ${asStr(a.list)}` : "default list";
  const r = await osa(`tell application "Reminders"
    set rs to (reminders of ${scope} whose completed is false)
    set n to count of rs
    if n > ${limit} then set n to ${limit}
    set out to ""
    repeat with i from 1 to n
      set rem to item i of rs
      set dd to ""
      try
        set dd to (due date of rem) as string
      end try
      set out to out & (name of rem) & "${FS}" & dd & "${FS}" & (id of rem) & "${RS}"
    end repeat
    return out
  end tell`);
  if (!r.ok) return { ok: false, error: r.err };
  const reminders = r.out.split(RS).filter((x) => x.trim().length > 0).map((row) => {
    const [title, due, id] = row.split(FS);
    const d = (due || "").trim();
    return { title, due: d && d !== "missing value" ? d : null, id: (id || "").trim() };
  });
  return { ok: true, count: reminders.length, list: a?.list ?? "default", reminders };
}

/// All reminder list names (so the caller can target one).
export async function reminderLists() {
  const r = await osa(`tell application "Reminders"
    set out to ""
    repeat with l in lists
      set out to out & (name of l) & "${RS}"
    end repeat
    return out
  end tell`);
  if (!r.ok) return { ok: false, error: r.err };
  return { ok: true, lists: r.out.split(RS).map((s) => s.trim()).filter(Boolean) };
}

/// Create a reminder (local write). Optional list + notes; due-date parsing kept simple for v1.
export async function reminderCreate(a: { title: string; notes?: string; list?: string }) {
  if (!a.title) return { ok: false, error: "missing 'title'" };
  const target = a.list ? `list ${asStr(a.list)}` : "default list";
  const props = a.notes ? `{name:${asStr(a.title)}, body:${asStr(a.notes)}}` : `{name:${asStr(a.title)}}`;
  const r = await osa(`tell application "Reminders"
    make new reminder at ${target} with properties ${props}
    return "created"
  end tell`);
  if (!r.ok) return { ok: false, error: r.err };
  return { ok: true, status: "created", title: a.title, list: a.list ?? "default" };
}
