/* Calendrier — Deadlines, lancements, échéances, paiements + sync Outlook/Teams */

// Publié depuis Outlook · partagé par Clarens. Tu peux le remplacer si tu changes de calendrier.
const OUTLOOK_CALENDAR_URL = "https://outlook.live.com/owa/calendar/00000000-0000-0000-0000-000000000000/de351be9-7ab2-4f4e-9ff7-cccfdaa64413/cid-314F3480A7F9852E/index.html";

// Aucun événement mock. Le calendrier est alimenté par le flux ICS Outlook
// (`/api/calendar/ics`) — voir useEffect ci-dessous. Les autres événements
// (tâches, expéditions, paiements) seront branchés sur D1 quand disponibles.
const EVENTS = [];

const TYPE_META = {
  task:     { tone: "blue",   icon: "check"    },
  supplier: { tone: "muted",  icon: "users"    },
  shipment: { tone: "amber",  icon: "truck"    },
  payment:  { tone: "red",    icon: "dollar"   },
  launch:   { tone: "green",  icon: "rocket"   },
  system:   { tone: "muted",  icon: "settings" },
  meeting:  { tone: "accent", icon: "users"    },
  outlook:  { tone: "accent", icon: "calendar" },
};

// Best-effort type detection from Outlook event title
function detectType(title = "") {
  const t = title.toLowerCase();
  if (/meeting|réunion|call|standup|sync/.test(t)) return "meeting";
  if (/livraison|delivery|fba|expédition/.test(t)) return "shipment";
  if (/paiement|payment|facture|invoice/.test(t)) return "payment";
  if (/lancement|launch|release/.test(t)) return "launch";
  return "outlook";
}

const LOCAL_EVENTS_KEY = "kcc_calendar_events_v1";
function loadLocalEvents() {
  try { return JSON.parse(localStorage.getItem(LOCAL_EVENTS_KEY) || "[]"); } catch (_) { return []; }
}
function saveLocalEvents(list) {
  try { localStorage.setItem(LOCAL_EVENTS_KEY, JSON.stringify(list)); } catch (_) {}
}

const Calendar = ({ onNavigate }) => {
  // Today is 2026-05-10 per user's context
  const today = "2026-05-10";
  const [view, setView] = useState("upcoming"); // upcoming | week | all | outlook
  const [outlookEvents, setOutlookEvents] = useState([]);
  const [icsStatus, setIcsStatus] = useState("idle"); // idle | loading | ok | error
  const [icsError, setIcsError] = useState("");
  const [localEvents, setLocalEvents] = useState(loadLocalEvents);
  const [showNew, setShowNew] = useState(false);
  const [draft, setDraft] = useState({ date: today, time: "09:00", title: "", type: "task", owner: "clarens" });

  const persistLocal = (list) => { setLocalEvents(list); saveLocalEvents(list); };
  const addLocal = () => {
    if (!draft.title.trim()) return;
    persistLocal([...localEvents, { ...draft, id: "loc-" + Date.now().toString(36), source: "local" }]);
    setShowNew(false);
    setDraft({ date: today, time: "09:00", title: "", type: "task", owner: "clarens" });
  };
  const updateLocal = (id, patch) => persistLocal(localEvents.map(e => e.id === id ? { ...e, ...patch } : e));
  const removeLocal = (id) => persistLocal(localEvents.filter(e => e.id !== id));

  // Fetch Outlook ICS once on mount
  useEffect(() => {
    let cancelled = false;
    setIcsStatus("loading");
    fetch("/api/calendar/ics")
      .then(async (r) => {
        if (!r.ok) throw new Error(`Proxy ${r.status}`);
        return r.text();
      })
      .then((txt) => {
        if (cancelled) return;
        const parsed = (window.parseICS ? window.parseICS(txt) : []).map((e) => ({
          date: e.start,
          time: e.startTime || "—",
          title: e.summary,
          type: detectType(e.summary),
          owner: "outlook",
          source: "outlook",
          location: e.location,
          description: e.description,
        }));
        setOutlookEvents(parsed);
        setIcsStatus("ok");
      })
      .catch((err) => {
        if (cancelled) return;
        setIcsError(err.message);
        setIcsStatus("error");
      });
    return () => { cancelled = true; };
  }, []);

  // Merge local EVENTS + Outlook events + user-created local events
  const merged = [...EVENTS, ...outlookEvents, ...localEvents];

  let visible = [...merged];
  if (view === "upcoming") visible = visible.filter(e => e.date >= today).slice(0, 12);
  else if (view === "week") {
    const weekEnd = new Date(today);
    weekEnd.setDate(weekEnd.getDate() + 7);
    const weekEndStr = weekEnd.toISOString().slice(0, 10);
    visible = visible.filter(e => e.date >= today && e.date <= weekEndStr);
  }
  // Sort by date+time
  visible.sort((a, b) => (a.date + (a.time || "")).localeCompare(b.date + (b.time || "")));

  // Group by date
  const byDate = {};
  visible.forEach(e => { (byDate[e.date] ||= []).push(e); });

  const fmtDate = (d) => {
    const [y, m, day] = d.split("-");
    const months = ["jan", "fév", "mars", "avr", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc"];
    return `${parseInt(day)} ${months[parseInt(m) - 1]}`;
  };

  return (
    <div className="page" style={{ maxWidth: 1000 }}>
      <div className="page-head">
        <div>
          <div className="page-title">Calendrier</div>
          <div className="page-sub">
            {merged.length} événements · {outlookEvents.length} depuis Outlook ·{" "}
            {icsStatus === "loading" && <span style={{ color: "var(--text-faint)" }}>sync ICS…</span>}
            {icsStatus === "ok" && <span style={{ color: "var(--green)" }}>● ICS synchronisé</span>}
            {icsStatus === "error" && <span style={{ color: "var(--amber)" }}>● ICS non disponible ({icsError})</span>}
          </div>
        </div>
        <div className="row" style={{ gap: 6 }}>
          <button className="btn" data-variant="primary" onClick={() => setShowNew(true)}>
            <Icon name="plus" size={12} /> Nouvel événement
          </button>
          <button className="btn" data-variant={view === "upcoming" ? "primary" : "ghost"} onClick={() => setView("upcoming")}>Prochains 8</button>
          <button className="btn" data-variant={view === "week" ? "primary" : "ghost"} onClick={() => setView("week")}>Cette semaine</button>
          <button className="btn" data-variant={view === "all" ? "primary" : "ghost"} onClick={() => setView("all")}>Tous · {merged.length}</button>
          <button className="btn" data-variant={view === "outlook" ? "primary" : "ghost"} onClick={() => setView("outlook")}>
            <Icon name="calendar" size={12} /> Outlook · Teams
          </button>
        </div>
      </div>

      {showNew && (
        <div className="card" style={{ padding: 14, marginBottom: 14 }}>
          <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 10 }}>Nouvel événement local</div>
          <div className="grid" style={{ gridTemplateColumns: "1fr 100px 100px 100px 110px auto", gap: 8 }}>
            <input className="input" placeholder="Titre" value={draft.title}
                   onChange={e => setDraft(d => ({ ...d, title: e.target.value }))} autoFocus />
            <input className="input" type="date" value={draft.date}
                   onChange={e => setDraft(d => ({ ...d, date: e.target.value }))} />
            <input className="input" type="time" value={draft.time}
                   onChange={e => setDraft(d => ({ ...d, time: e.target.value }))} />
            <select className="input" value={draft.type} onChange={e => setDraft(d => ({ ...d, type: e.target.value }))}>
              {Object.keys(TYPE_META).filter(t => t !== "outlook").map(t => <option key={t} value={t}>{t}</option>)}
            </select>
            <select className="input" value={draft.owner} onChange={e => setDraft(d => ({ ...d, owner: e.target.value }))}>
              {USERS.map(u => <option key={u.id} value={u.id}>{u.name}</option>)}
            </select>
            <div className="row" style={{ gap: 6 }}>
              <button className="btn" data-variant="primary" onClick={addLocal}>Ajouter</button>
              <button className="btn" data-variant="ghost" onClick={() => setShowNew(false)}>Annuler</button>
            </div>
          </div>
        </div>
      )}

      {view === "outlook" && (
        <div className="card" style={{ padding: 0, overflow: "hidden" }}>
          <div className="card-head" style={{ borderBottom: "1px solid var(--border-subtle)" }}>
            <div>
              <div className="card-title">Calendrier Outlook partagé</div>
              <div className="muted" style={{ fontSize: 11, marginTop: 2 }}>
                Lecture seule · synchronisé depuis outlook.live.com
              </div>
            </div>
            <a className="btn" href={OUTLOOK_CALENDAR_URL} target="_blank" rel="noopener noreferrer">
              <Icon name="external" size={12} /> Ouvrir dans Outlook
            </a>
          </div>
          <iframe
            src={OUTLOOK_CALENDAR_URL}
            title="Calendrier Outlook"
            style={{ width: "100%", height: "75vh", border: "none", background: "white" }}
            sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
          />
          <div className="muted" style={{ padding: "10px 14px", fontSize: 10.5, borderTop: "1px solid var(--border-subtle)", color: "var(--text-faint)" }}>
            Note: si l'iframe reste vide, Outlook bloque l'embed (X-Frame-Options). Utilise « Ouvrir dans Outlook » ou publie ton calendrier au format <span className="mono">ICS</span> pour une vraie sync bidirectionnelle.
          </div>
        </div>
      )}

      {view !== "outlook" && (<>

      {/* Type legend */}
      <div className="row" style={{ gap: 8, marginBottom: 14, flexWrap: "wrap" }}>
        {Object.entries(TYPE_META).map(([type, meta]) => (
          <div key={type} className="row" style={{ gap: 4, fontSize: 11.5, color: "var(--text-dim)" }}>
            <Badge tone={meta.tone} dot />
            <span style={{ textTransform: "capitalize" }}>{type}</span>
          </div>
        ))}
      </div>

      {/* Timeline */}
      <div className="stack" style={{ gap: 14 }}>
        {Object.entries(byDate).map(([date, events]) => {
          const isToday = date === today;
          const past = date < today;
          return (
            <div key={date}>
              <div className="row" style={{ gap: 10, marginBottom: 8 }}>
                <div
                  style={{
                    width: 56, padding: "6px 8px", borderRadius: 8,
                    background: isToday ? "var(--accent)" : past ? "var(--bg-2)" : "var(--bg-3)",
                    color: isToday ? "white" : past ? "var(--text-faint)" : "var(--text)",
                    textAlign: "center", fontSize: 11, fontWeight: 600,
                  }}
                >
                  {fmtDate(date)}
                </div>
                {isToday && <Badge tone="blue">Aujourd'hui</Badge>}
                <span className="mono" style={{ fontSize: 11, color: "var(--text-faint)" }}>{events.length} événement{events.length > 1 ? "s" : ""}</span>
              </div>
              <div className="stack" style={{ gap: 6, marginLeft: 66 }}>
                {events.map((e, i) => {
                  const meta = TYPE_META[e.type] || TYPE_META.task;
                  const isLocal = e.source === "local" && e.id;
                  return (
                    <div key={i} className="card" style={{ padding: 10 }}>
                      <div className="between">
                        <div className="row" style={{ gap: 8 }}>
                          <Badge tone={meta.tone} dot>
                            <Icon name={meta.icon} size={10} style={{ marginRight: 3 }} />
                            {e.type}
                          </Badge>
                          <span style={{ fontSize: 13, fontWeight: 500 }}>
                            {isLocal
                              ? <EditableField value={e.title} onSave={(v) => updateLocal(e.id, { title: v })} width={260}/>
                              : e.title}
                          </span>
                        </div>
                        <div className="row" style={{ gap: 8 }}>
                          {e.time !== "—" && (
                            <span className="mono" style={{ fontSize: 11, color: "var(--text-faint)" }}>
                              {isLocal
                                ? <EditableField value={e.time} onSave={(v) => updateLocal(e.id, { time: v })} width={60}/>
                                : e.time}
                            </span>
                          )}
                          {e.owner !== "system" && <Avatar user={e.owner} size="sm" />}
                          {isLocal && (
                            <button
                              className="icon-btn"
                              title="Supprimer"
                              onClick={() => removeLocal(e.id)}
                              style={{ width: 22, height: 22, opacity: 0.4 }}
                            >
                              <Icon name="x" size={11} />
                            </button>
                          )}
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          );
        })}
        {Object.keys(byDate).length === 0 && (
          <div className="card" style={{ padding: 30, textAlign: "center", color: "var(--text-faint)" }}>
            Aucune échéance dans cette plage.
          </div>
        )}
      </div>
      </>)}
    </div>
  );
};

window.Calendar = Calendar;
