/* lib-ics — minimal ICS parser, no deps.
 * Exposes window.parseICS(text) → [{ uid, summary, start: 'YYYY-MM-DD', startTime, location, description, allDay }]
 * Handles line-folding, escaped chars, DATE vs DATE-TIME.
 */

window.parseICS = function parseICS(raw) {
  if (!raw || typeof raw !== "string") return [];
  // Unfold lines: ICS folds long lines by prefixing with space/tab
  const unfolded = raw.replace(/\r?\n[ \t]/g, "");
  const lines = unfolded.split(/\r?\n/);

  const events = [];
  let cur = null;
  for (const line of lines) {
    if (line === "BEGIN:VEVENT") { cur = {}; continue; }
    if (line === "END:VEVENT") {
      if (cur) {
        const normalized = normalizeEvent(cur);
        if (normalized) events.push(normalized);
      }
      cur = null;
      continue;
    }
    if (!cur) continue;

    // Split key (with params) from value at first ":"
    const idx = line.indexOf(":");
    if (idx < 0) continue;
    const keyPart = line.slice(0, idx);
    const value = unescapeICS(line.slice(idx + 1));
    const [key, ...paramsArr] = keyPart.split(";");
    const params = {};
    for (const p of paramsArr) {
      const [k, v] = p.split("=");
      if (k) params[k] = v;
    }
    cur[key] = { value, params };
  }
  // Sort ascending by start
  events.sort((a, b) => (a.start + (a.startTime || "")).localeCompare(b.start + (b.startTime || "")));
  return events;
};

function unescapeICS(v) {
  return v
    .replace(/\\,/g, ",")
    .replace(/\\;/g, ";")
    .replace(/\\n/gi, "\n")
    .replace(/\\\\/g, "\\");
}

function parseDate(node) {
  if (!node) return null;
  const v = node.value;
  // DATE form: YYYYMMDD (all-day)
  if (node.params?.VALUE === "DATE" || /^\d{8}$/.test(v)) {
    if (/^\d{8}$/.test(v)) return { date: `${v.slice(0, 4)}-${v.slice(4, 6)}-${v.slice(6, 8)}`, time: null, allDay: true };
  }
  // DATE-TIME: YYYYMMDDTHHMMSS[Z]
  const m = v.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(Z?)$/);
  if (m) {
    const [, y, mo, d, h, mi, _s, z] = m;
    if (z === "Z") {
      // UTC → convert to local
      const utc = new Date(Date.UTC(+y, +mo - 1, +d, +h, +mi));
      return {
        date: utc.toISOString().slice(0, 10),
        time: utc.toISOString().slice(11, 16),
        allDay: false,
      };
    }
    return {
      date: `${y}-${mo}-${d}`,
      time: `${h}:${mi}`,
      allDay: false,
    };
  }
  return null;
}

function normalizeEvent(raw) {
  const start = parseDate(raw.DTSTART);
  if (!start) return null;
  return {
    uid: raw.UID?.value || "",
    summary: raw.SUMMARY?.value || "(sans titre)",
    location: raw.LOCATION?.value || "",
    description: raw.DESCRIPTION?.value || "",
    start: start.date,
    startTime: start.time,
    allDay: start.allDay,
    source: "outlook",
  };
}
