(function(){
// ============================================================
// agenda.jsx — Universelle Traktandenliste (wiederkehrende Besprechungspunkte)
// Eigenständige Entität, getrennt von Todos/Habits/Exams.
// Depends on (window): todayISO, localISO, fmtDate, nextInternalRuleDate, DatePicker
// ============================================================

const { useState } = React;

const WEEKDAY_LABELS = [{ dow: 1, l: "Mo" }, { dow: 2, l: "Di" }, { dow: 3, l: "Mi" }, { dow: 4, l: "Do" }, { dow: 5, l: "Fr" }, { dow: 6, l: "Sa" }, { dow: 7, l: "So" }];

function anchorLabel(a){
  if (!a) return "";
  if (a.anchorType === "outlook") return a.anchor?.subject ? `Outlook · ${a.anchor.subject}` : "Outlook";
  if (a.anchorType === "internalRule") {
    const days = (a.anchor?.days || []).map(d => WEEKDAY_LABELS.find(w => w.dow === d)?.l).filter(Boolean).join("/");
    const everyN = a.anchor?.everyNWeeks > 1 ? `alle ${a.anchor.everyNWeeks} Wochen` : "wöchentlich";
    return `${everyN}${days ? " · " + days : ""}`;
  }
  return "Manuell";
}

function computeSuggestedNextDate(agenda){
  if (agenda.anchorType === "internalRule") return nextInternalRuleDate(agenda.anchor, todayISO());
  return null;
}

// ── Anker-Auswahl beim Anlegen ───────────────────────────────────────
function AnchorTypePicker({ value, onChange }){
  const types = [
    { id: "outlook", label: "Outlook-Termin" },
    { id: "internalRule", label: "Eigene Regel" },
    { id: "manual", label: "Manuell" },
  ];
  return (
    <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
      {types.map(ty => (
        <button key={ty.id} onClick={() => onChange(ty.id)} style={{
          padding: "6px 12px", fontSize: 12, borderRadius: 20,
          background: value === ty.id ? "var(--col-accent)" : "var(--col-bg-sec)",
          color: value === ty.id ? "var(--col-bg)" : "var(--col-text-sec)",
          border: value === ty.id ? "none" : "1px solid var(--col-border)",
          fontWeight: 500, cursor: "pointer",
        }}>{ty.label}</button>
      ))}
    </div>
  );
}

function OutlookEventPicker({ events, value, onChange }){
  const upcoming = (events || []).filter(ev => ev.start?.dateTime).slice(0, 30);
  if (upcoming.length === 0) {
    return <p style={{ fontSize: 11, color: "var(--col-text-3)" }}>Keine Outlook-Termine geladen (nächste 14 Tage).</p>;
  }
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 4, maxHeight: 220, overflowY: "auto" }}>
      {upcoming.map(ev => {
        const sel = value === ev.id;
        const dt = ev.start?.dateTime ? new Date(ev.start.dateTime) : null;
        return (
          <button key={ev.id} onClick={() => onChange(ev)} style={{
            display: "flex", justifyContent: "space-between", gap: 8, textAlign: "left",
            padding: "6px 9px", borderRadius: 6, fontSize: 12,
            background: sel ? "var(--col-accent-wash)" : "var(--col-bg)",
            border: sel ? "1.5px solid var(--col-accent)" : "1px solid var(--col-border-soft)",
            color: "var(--col-text)", cursor: "pointer",
          }}>
            <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{ev.subject || "(ohne Titel)"}</span>
            {dt && <span className="mono" style={{ fontSize: 10, color: "var(--col-text-3)", flexShrink: 0 }}>{dt.toLocaleDateString("de-CH", { day: "2-digit", month: "2-digit" })} {dt.toLocaleTimeString("de-CH", { hour: "2-digit", minute: "2-digit" })}</span>}
          </button>
        );
      })}
    </div>
  );
}

function WeekdayPicker({ value, onChange }){
  return (
    <div style={{ display: "flex", gap: 4 }}>
      {WEEKDAY_LABELS.map(w => {
        const sel = (value || []).includes(w.dow);
        return (
          <button key={w.dow} onClick={() => onChange(sel ? value.filter(d => d !== w.dow) : [...(value || []), w.dow])} style={{
            width: 30, height: 30, borderRadius: "50%", fontSize: 11,
            background: sel ? "var(--col-accent)" : "var(--col-bg-sec)",
            color: sel ? "var(--col-bg)" : "var(--col-text-sec)",
            border: "none", cursor: "pointer", fontWeight: sel ? 600 : 400,
          }}>{w.l}</button>
        );
      })}
    </div>
  );
}

// ── Neue Traktandenliste anlegen ─────────────────────────────────────
function NewAgendaForm({ calEvents, onCreate, onCancel }){
  const [title, setTitle] = useState("");
  const [anchorType, setAnchorType] = useState("manual");
  const [outlookEv, setOutlookEv] = useState(null);
  const [ruleDays, setRuleDays] = useState([1]);
  const [everyNWeeks, setEveryNWeeks] = useState(1);
  const [manualDate, setManualDate] = useState(null);

  function create(){
    if (!title.trim()) return;
    let anchor = {};
    if (anchorType === "outlook" && outlookEv) {
      anchor = { eventId: outlookEv.id, seriesMasterId: outlookEv.seriesMasterId || null, subject: outlookEv.subject || null };
    } else if (anchorType === "internalRule") {
      anchor = { days: ruleDays, everyNWeeks: everyNWeeks || 1 };
    }
    const nextDate = anchorType === "internalRule"
      ? nextInternalRuleDate(anchor, todayISO())
      : anchorType === "manual" ? manualDate : (outlookEv?.start?.dateTime ? outlookEv.start.dateTime.slice(0, 10) : null);
    onCreate({
      id: Date.now() + Math.random(), title: title.trim(), anchorType, anchor,
      nextDate, items: [], createdDate: todayISO(),
      createdAt: Date.now(), updatedAt: Date.now(), deletedAt: null,
    });
  }

  return (
    <div style={{ background: "var(--col-bg-sec)", border: "1px solid var(--col-border-soft)", borderRadius: 8, padding: 12, marginBottom: 10 }}>
      <div style={{ fontSize: 11, fontWeight: 600, color: "var(--col-text-sec)", marginBottom: 8 }}>Neue Traktandenliste</div>
      <input placeholder="z.B. Teambesprechung" value={title} onChange={e => setTitle(e.target.value)}
        style={{ width: "100%", boxSizing: "border-box", fontSize: 12, marginBottom: 8 }} autoFocus />
      <div style={{ marginBottom: 8 }}><AnchorTypePicker value={anchorType} onChange={setAnchorType} /></div>
      {anchorType === "outlook" && <div style={{ marginBottom: 8 }}><OutlookEventPicker events={calEvents} value={outlookEv?.id} onChange={setOutlookEv} /></div>}
      {anchorType === "internalRule" && (
        <div style={{ display: "flex", flexDirection: "column", gap: 6, marginBottom: 8 }}>
          <WeekdayPicker value={ruleDays} onChange={setRuleDays} />
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <span style={{ fontSize: 11, color: "var(--col-text-sec)" }}>alle</span>
            <input type="number" min={1} max={12} value={everyNWeeks} onChange={e => setEveryNWeeks(Math.max(1, parseInt(e.target.value) || 1))}
              style={{ width: 50, fontSize: 12 }} />
            <span style={{ fontSize: 11, color: "var(--col-text-sec)" }}>Wochen</span>
          </div>
        </div>
      )}
      {anchorType === "manual" && <div style={{ marginBottom: 8 }}><DatePicker value={manualDate} onChange={setManualDate} label="Nächster Termin (optional)" /></div>}
      <div style={{ display: "flex", gap: 6 }}>
        <button onClick={create} disabled={!title.trim()} style={{ flex: 1, padding: "7px", fontSize: 12, borderRadius: 6, background: "var(--col-accent)", color: "var(--col-bg)", fontWeight: 500, cursor: "pointer" }}>Anlegen</button>
        <button onClick={onCancel} style={{ padding: "7px 12px", fontSize: 12, borderRadius: 6, border: "1px solid var(--col-border)", color: "var(--col-text-sec)", cursor: "pointer" }}>Abbrechen</button>
      </div>
    </div>
  );
}

// ── Verschieben-Popup beim Abschliessen ──────────────────────────────
function MoveOpenItemsPopup({ agenda, calEvents, openCount, onConfirm, onClose }){
  const suggested = computeSuggestedNextDate(agenda);
  const [date, setDate] = useState(suggested);
  const [outlookEv, setOutlookEv] = useState(null);

  function confirm(){
    if (agenda.anchorType === "outlook" && outlookEv) {
      onConfirm({ nextDate: outlookEv.start?.dateTime?.slice(0, 10) || null, anchor: { ...agenda.anchor, eventId: outlookEv.id, seriesMasterId: outlookEv.seriesMasterId || null, subject: outlookEv.subject || null } });
    } else {
      onConfirm({ nextDate: date, anchor: agenda.anchor });
    }
  }

  return (
    <div style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.35)", zIndex: 2400, display: "flex", alignItems: "center", justifyContent: "center", padding: 16 }} onClick={onClose}>
      <div style={{ background: "var(--col-bg)", borderRadius: 14, padding: "20px 22px", width: "100%", maxWidth: 360, boxShadow: "0 24px 60px rgba(0,0,0,0.3)" }} onClick={e => e.stopPropagation()}>
        <div style={{ fontSize: 14, fontWeight: 700, color: "var(--col-text)", marginBottom: 6 }}>{openCount} Punkt{openCount === 1 ? "" : "e"} nicht besprochen</div>
        <p style={{ fontSize: 12, color: "var(--col-text-sec)", marginBottom: 12 }}>Auf den nächsten Termin verschieben?</p>
        {agenda.anchorType === "outlook"
          ? <OutlookEventPicker events={calEvents} value={outlookEv?.id} onChange={setOutlookEv} />
          : <DatePicker value={date} onChange={setDate} label="Nächster Termin" />}
        <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
          <button onClick={confirm} style={{ flex: 1, padding: "9px", fontSize: 13, borderRadius: 8, background: "var(--col-accent)", color: "var(--col-bg)", fontWeight: 600, cursor: "pointer" }}>Verschieben</button>
          <button onClick={onClose} style={{ padding: "9px 14px", fontSize: 13, borderRadius: 8, border: "1px solid var(--col-border)", color: "var(--col-text-sec)", cursor: "pointer" }}>Abbrechen</button>
        </div>
      </div>
    </div>
  );
}

// ── Detailansicht ─────────────────────────────────────────────────────
function AgendaDetail({ agenda, calEvents, onUpdate, onDelete, onClose, isMobile }){
  const [newItem, setNewItem] = useState("");
  const [showMovePopup, setShowMovePopup] = useState(false);
  const [confirmDelete, setConfirmDelete] = useState(false);
  const items = agenda.items || [];
  const openItems = items.filter(i => !i.done);
  const doneItems = items.filter(i => i.done);
  const outlookMissing = agenda.anchorType === "outlook" && agenda.anchor?.eventId && !(calEvents || []).some(ev => String(ev.id) === String(agenda.anchor.eventId));

  function addItem(){
    if (!newItem.trim()) return;
    onUpdate({ ...agenda, items: [...items, { id: Date.now() + Math.random(), text: newItem.trim(), done: false, createdDate: todayISO() }], updatedAt: Date.now() });
    setNewItem("");
  }
  function toggleItem(id){
    onUpdate({ ...agenda, items: items.map(i => String(i.id) === String(id) ? { ...i, done: !i.done } : i), updatedAt: Date.now() });
  }
  function deleteItem(id){
    onUpdate({ ...agenda, items: items.filter(i => String(i.id) !== String(id)), updatedAt: Date.now() });
  }
  function finishMeeting(){
    if (openItems.length > 0) { setShowMovePopup(true); return; }
    setShowMovePopup(true);
  }
  function applyMove({ nextDate, anchor }){
    onUpdate({ ...agenda, nextDate, anchor, updatedAt: Date.now() });
    setShowMovePopup(false);
  }
  function decoupleFromOutlook(){
    onUpdate({ ...agenda, anchorType: "manual", anchor: { nextDate: null }, updatedAt: Date.now() });
  }

  return (
    <div style={isMobile ? { position: "fixed", bottom: 0, left: 0, right: 0, zIndex: 301, background: "var(--col-bg)", borderRadius: "16px 16px 0 0", padding: "16px 14px", paddingBottom: "calc(70px + env(safe-area-inset-bottom,0px))", maxHeight: "88vh", overflowY: "auto", boxShadow: "0 -8px 32px rgba(0,0,0,0.18)" } : { background: "var(--col-bg)", border: "1px solid var(--col-border-soft)", borderRadius: 8, padding: 14, position: "sticky", top: 24 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 8, marginBottom: 4 }}>
        <span style={{ fontSize: 15, fontWeight: 600, color: "var(--col-text)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{agenda.title}</span>
        <button onClick={onClose} style={{ padding: "3px 7px", fontSize: 12, borderRadius: 6, border: "1px solid var(--col-border)", color: "var(--col-text-sec)", cursor: "pointer" }}>×</button>
      </div>
      <div style={{ fontSize: 11, color: "var(--col-text-3)", marginBottom: 4 }}>{anchorLabel(agenda)}</div>
      {agenda.nextDate && <div className="mono" style={{ fontSize: 11, color: "var(--col-accent)", marginBottom: 10 }}>Nächster Termin: {fmtDate(agenda.nextDate)}</div>}
      {outlookMissing && (
        <div style={{ fontSize: 11, color: "#92400e", background: "#fef3c7", borderRadius: 6, padding: "6px 8px", marginBottom: 10 }}>
          Termin existiert nicht mehr in Outlook.
          <button onClick={decoupleFromOutlook} style={{ marginLeft: 6, fontSize: 11, color: "var(--col-accent)", background: "none", border: "none", cursor: "pointer", textDecoration: "underline", padding: 0 }}>Entkoppeln</button>
        </div>
      )}

      <div style={{ display: "flex", gap: 6, marginBottom: 10 }}>
        <input placeholder="Neuer Punkt…" value={newItem} onChange={e => setNewItem(e.target.value)}
          onKeyDown={e => { if (e.key === "Enter") addItem(); }}
          style={{ flex: 1, fontSize: 12 }} />
        <button onClick={addItem} disabled={!newItem.trim()} style={{ padding: "6px 12px", fontSize: 12, borderRadius: 6, background: "var(--col-accent)", color: "var(--col-bg)", fontWeight: 500, cursor: "pointer" }}>+</button>
      </div>

      <div style={{ display: "flex", flexDirection: "column", gap: 4, marginBottom: 12 }}>
        {openItems.map(i => (
          <div key={i.id} style={{ display: "flex", alignItems: "center", gap: 8, padding: "6px 8px", borderRadius: 6, background: "var(--col-bg-sec)" }}>
            <button onClick={() => toggleItem(i.id)} style={{ width: 16, height: 16, borderRadius: "50%", border: "1.5px solid var(--col-accent)", background: "transparent", flexShrink: 0, cursor: "pointer" }} />
            <span style={{ flex: 1, fontSize: 12.5, color: "var(--col-text)" }}>{i.text}</span>
            <button onClick={() => deleteItem(i.id)} style={{ background: "none", border: "none", color: "var(--col-text-3)", fontSize: 13, cursor: "pointer", padding: 0 }}>✕</button>
          </div>
        ))}
        {openItems.length === 0 && <p style={{ fontSize: 11, color: "var(--col-text-3)", fontStyle: "italic" }}>Keine offenen Punkte.</p>}
      </div>

      {doneItems.length > 0 && (
        <div style={{ paddingTop: 8, borderTop: "1px solid var(--col-border-soft)", display: "flex", flexDirection: "column", gap: 3 }}>
          {doneItems.map(i => (
            <div key={i.id} onClick={() => toggleItem(i.id)} style={{ display: "flex", alignItems: "center", gap: 6, cursor: "pointer", opacity: 0.55 }}>
              <span style={{ fontSize: 11, color: "#16a34a", flexShrink: 0 }}>✓</span>
              <span style={{ fontSize: 11, color: "var(--col-text-sec)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{i.text}</span>
            </div>
          ))}
        </div>
      )}

      <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
        <button onClick={finishMeeting} style={{ flex: 1, padding: "8px", fontSize: 12, borderRadius: 8, background: "var(--col-accent)", color: "var(--col-bg)", fontWeight: 500, cursor: "pointer" }}>Termin abgeschlossen</button>
        {!confirmDelete
          ? <button onClick={() => setConfirmDelete(true)} style={{ padding: "8px 10px", fontSize: 12, borderRadius: 8, border: "1px solid var(--col-border)", color: "var(--col-text-sec)", cursor: "pointer" }}>Löschen</button>
          : <button onClick={() => { onDelete(agenda.id); onClose(); }} style={{ padding: "8px 10px", fontSize: 11, borderRadius: 8, background: "#b91c1c", color: "#fff", border: "none", fontWeight: 600, cursor: "pointer" }}>Sicher?</button>}
      </div>

      {showMovePopup && <MoveOpenItemsPopup agenda={agenda} calEvents={calEvents} openCount={openItems.length} onConfirm={applyMove} onClose={() => setShowMovePopup(false)} />}
    </div>
  );
}

// ── Hauptansicht ──────────────────────────────────────────────────────
function AgendaView({ agendas, calEvents, isMobile, onAdd, onUpdate, onDelete }){
  const [selectedId, setSelectedId] = useState(null);
  const [showNew, setShowNew] = useState(false);
  const list = agendas || [];
  const sel = list.find(a => String(a.id) === String(selectedId)) || null;

  return (
    <div style={{ display: "grid", gridTemplateColumns: isMobile ? "1fr" : "1fr 320px", gap: 16, alignItems: "start" }}>
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
          <span className="cap" style={{ color: "var(--col-text-3)" }}>Traktandenlisten ({list.length})</span>
          <button onClick={() => setShowNew(x => !x)} style={{ padding: "5px 12px", fontSize: 11, borderRadius: 20, background: showNew ? "var(--col-bg-sec)" : "var(--col-accent)", color: showNew ? "var(--col-text-sec)" : "var(--col-bg)", border: showNew ? "1px solid var(--col-border)" : "none", fontWeight: 500, cursor: "pointer" }}>{showNew ? "Abbrechen" : "Neue Liste"}</button>
        </div>

        {showNew && <NewAgendaForm calEvents={calEvents} onCreate={a => { onAdd(a); setShowNew(false); setSelectedId(a.id); }} onCancel={() => setShowNew(false)} />}

        {list.length === 0 && !showNew && (
          <div style={{ padding: "32px 0", textAlign: "center" }}>
            <p className="serif" style={{ fontSize: 15, color: "var(--col-text-sec)", fontStyle: "italic", marginBottom: 6 }}>Noch keine Traktandenliste.</p>
            <p style={{ fontSize: 12, color: "var(--col-text-3)" }}>Lege eine neue Liste an, z.B. für eine wiederkehrende Besprechung.</p>
          </div>
        )}

        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {list.map(a => {
            const isSel = sel?.id === a.id;
            const openCount = (a.items || []).filter(i => !i.done).length;
            return (
              <div key={a.id} onClick={() => setSelectedId(isSel ? null : a.id)} style={{
                padding: "10px 12px", borderRadius: 8, cursor: "pointer",
                background: isSel ? "var(--col-accent-wash)" : "var(--col-bg)",
                border: isSel ? "1.5px solid var(--col-accent)" : "1px solid var(--col-border-soft)",
              }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 8 }}>
                  <span style={{ fontSize: 13, fontWeight: 500, color: isSel ? "var(--col-accent)" : "var(--col-text)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{a.title}</span>
                  {a.nextDate && <span className="mono" style={{ fontSize: 10, color: "var(--col-text-3)", flexShrink: 0 }}>{fmtDate(a.nextDate)}</span>}
                </div>
                <div style={{ display: "flex", gap: 10, marginTop: 3 }}>
                  <span style={{ fontSize: 10, color: "var(--col-text-3)" }}>{anchorLabel(a)}</span>
                  {openCount > 0 && <span className="mono" style={{ fontSize: 10, color: "var(--col-accent)" }}>{openCount} offen</span>}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {sel && isMobile && <div onClick={() => setSelectedId(null)} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.35)", zIndex: 300 }} />}
      {sel && <AgendaDetail agenda={sel} calEvents={calEvents} onUpdate={onUpdate} onDelete={onDelete} onClose={() => setSelectedId(null)} isMobile={isMobile} />}
    </div>
  );
}

Object.assign(window, { AgendaView });

})();
