/* Announcement bar.
   Reads events.json and rotates through ALL upcoming events (hides ones whose date has passed).
   Two display modes:
     • Fixed overlay  — opt in with <body data-anno-fixed>; self-mounts at the top of <body>.
     • Inline sticky  — render <AnnouncementBar inline /> inside a page (sits below a hero, pins on scroll).
   Dismissible; reappears automatically when the set of upcoming events changes. */

(function () {
  const { useState, useEffect, useRef } = React;

  /* ---------------------------------------------------------------------------
     EVENTS — edit these directly. The bar shows all UPCOMING events and hides
     ones whose date has passed. No separate file needed, so nothing can "fail
     to upload." (If an events.json file IS present next to the page it will be
     used instead — but it is entirely optional.)
     date = YYYY-MM-DD (Pacific). For a multi-day event add endDate + displayDate.
  --------------------------------------------------------------------------- */
  const DEFAULT_EVENTS = [
    {
      id: "new-moon-cacao-2026-07-12",
      title: "New Moon Cacao Ceremony",
      emoji: "\uD83C\uDF19",
      date: "2026-07-12",
      time: "12:00 PM",
      location: "Santa Monica Studio",
      url: "https://momence.com/l/XehqJXEk"
    },
    {
      id: "full-moon-beach-2026-07-29",
      title: "Full Moon Beach Session",
      emoji: "\uD83C\uDF15",
      date: "2026-07-29",
      time: "6:30 PM",
      location: "Santa Monica Beach",
      url: "https://momence.com/l/6khAjLBy"
    },
    {
      id: "sound-healer-training-2026-07-31",
      title: "Sound Healer Training",
      emoji: "\uD83D\uDC69\u200D\uD83C\uDF93",
      date: "2026-07-31",
      endDate: "2026-08-02",
      displayDate: "July 31 \u2013 August 2",
      time: "",
      location: "Santa Monica Studio",
      url: "https://momence.com/l/mXh7MwW2"
    },
    {
      id: "reiki-1-2026-08-07",
      title: "Reiki 1 Training & Certification",
      emoji: "\u2728",
      date: "2026-08-07",
      endDate: "2026-08-09",
      displayDate: "August 7\u20139",
      time: "",
      location: "Santa Monica Studio",
      url: "https://momence.com/l/QQh5el5G"
    }
  ];

  /* Upcoming through the END of an event's (last) day, local time. */
  function isUpcoming(ev) {
    const last = (ev.endDate || ev.date) + "T23:59:59";
    return new Date(last).getTime() >= Date.now();
  }

  function formatDate(dateStr) {
    const d = new Date(dateStr + "T12:00:00");
    return d.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" });
  }

  function upcomingEvents(events) {
    return (events || [])
      .filter((e) => e && e.date && isUpcoming(e))
      .sort((a, b) => a.date.localeCompare(b.date));
  }

  function AnnouncementBar(props) {
    const inline = !!(props && props.inline);
    const [events, setEvents] = useState([]);
    const [idx, setIdx] = useState(0);
    const [dismissed, setDismissed] = useState(false);
    const paused = useRef(false);

    useEffect(() => {
      let alive = true;

      function apply(list) {
        if (!alive) return;
        const up = upcomingEvents(list);
        if (!up.length) return;
        const sig = up.map((e) => e.id).join(",");
        const wasDismissed = localStorage.getItem("cs_anno_dismissed") === sig;
        setEvents(up);
        setDismissed(wasDismissed);
        if (!wasDismissed && !inline) document.documentElement.classList.add("cs-has-anno");
      }

      /* Baked-in events show immediately — no network needed. */
      apply(DEFAULT_EVENTS);

      /* Optional: if an events.json is present, let it override the defaults. */
      fetch("events.json", { cache: "no-store" })
        .then((r) => (r.ok ? r.json() : null))
        .then((data) => {
          if (data && Array.isArray(data.events) && data.events.length) apply(data.events);
        })
        .catch(() => {});

      return () => { alive = false; };
    }, []);

    /* Auto-rotate through the events (pause on hover/focus). */
    useEffect(() => {
      if (events.length < 2) return;
      const t = setInterval(() => {
        if (!paused.current) setIdx((p) => (p + 1) % events.length);
      }, 3000);
      return () => clearInterval(t);
    }, [events.length]);

    function close() {
      const sig = events.map((e) => e.id).join(",");
      if (sig) localStorage.setItem("cs_anno_dismissed", sig);
      if (!inline) document.documentElement.classList.remove("cs-has-anno");
      setDismissed(true);
    }

    if (!events.length || dismissed) return null;

    const ev = events[Math.min(idx, events.length - 1)];
    const dateLabel = ev.displayDate || formatDate(ev.date);
    const meta = [dateLabel, ev.time, ev.location].filter(Boolean).join(" · ");

    const pause = () => { paused.current = true; };
    const resume = () => { paused.current = false; };
    const ext = /^https?:/i.test(ev.url || "");

    return (
      <div
        className={["cs-anno", inline ? "cs-anno--inline" : ""].filter(Boolean).join(" ")}
        role="region"
        aria-label="Upcoming events"
        onMouseEnter={pause}
        onMouseLeave={resume}
        onFocusCapture={pause}
        onBlurCapture={resume}
      >
        <a className="cs-anno__link" href={ev.url} {...(ext ? { target: "_blank", rel: "noopener" } : {})}>
          <span className="cs-anno__dot" aria-hidden="true" />
          <span className="cs-anno__text">
            <span className="cs-anno__title">{ev.title}</span>
            {ev.emoji
              ? <span className="cs-anno__emoji" aria-hidden="true">{ev.emoji}</span>
              : <span className="cs-anno__sep" aria-hidden="true">—</span>}
            <span className="cs-anno__meta">{meta}</span>
          </span>
          <span className="cs-anno__cta">
            Reserve
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M5 12h14M13 6l6 6-6 6" />
            </svg>
          </span>
        </a>

        <div className="cs-anno__controls">
          {events.length > 1 && (
            <div className="cs-anno__dots" role="tablist" aria-label="Choose event">
              {events.map((e, i) => (
                <button
                  key={e.id}
                  className={["cs-anno__pip", i === idx ? "is-active" : ""].filter(Boolean).join(" ")}
                  role="tab"
                  aria-selected={i === idx}
                  aria-label={e.title}
                  onClick={() => setIdx(i)}
                />
              ))}
            </div>
          )}
          <button className="cs-anno__close" aria-label="Dismiss announcement" onClick={close}>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" aria-hidden="true">
              <path d="M6 6l12 12M18 6 6 18" />
            </svg>
          </button>
        </div>
      </div>
    );
  }

  /* Fixed overlay mode: self-mount only when the page opts in with <body data-anno-fixed>. */
  if (document.body.hasAttribute("data-anno-fixed")) {
    const host = document.createElement("div");
    document.body.insertBefore(host, document.body.firstChild);
    ReactDOM.createRoot(host).render(<AnnouncementBar />);
  }

  window.AnnouncementBar = AnnouncementBar;
})();
