/* global React */
/* Ultra Mode — shared chrome. Exposes components on window.* so each page
   (index.html, article.html, …) can compose them in its own Babel script. */

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

  // ── Theme ────────────────────────────────────────────────────────────
  function applyTheme(theme) {
    document.documentElement.setAttribute("data-theme", theme);
    const color = theme === "dark" ? "#0a0a0a" : "#f5f5f7";
    let meta = document.querySelector('meta[name="theme-color"]');
    if (!meta) {
      meta = document.createElement("meta");
      meta.setAttribute("name", "theme-color");
      document.head.appendChild(meta);
    }
    meta.setAttribute("content", color);
  }
  function readStoredTheme() {
    try {
      const v = localStorage.getItem("um.theme");
      if (v === "dark" || v === "light") return v;
    } catch (e) {}
    return null;
  }
  function systemTheme() {
    return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  }
  function readTheme() { return readStoredTheme() || systemTheme(); }
  applyTheme(readTheme());

  function useTheme() {
    const [theme, setTheme] = useState(readTheme());
    useEffect(() => { applyTheme(theme); }, [theme]);
    useEffect(() => {
      const mq = window.matchMedia("(prefers-color-scheme: dark)");
      const onChange = (e) => {
        if (!readStoredTheme()) setTheme(e.matches ? "dark" : "light");
      };
      mq.addEventListener("change", onChange);
      return () => mq.removeEventListener("change", onChange);
    }, []);
    const setAndPersist = (next) => {
      try { localStorage.setItem("um.theme", next); } catch (e) {}
      setTheme(next);
    };
    return [theme, setAndPersist];
  }
  window.useTheme = useTheme;

  // ── Search overlay ───────────────────────────────────────────────────
  function SearchOverlay({ open, onClose }) {
    const [q, setQ] = useState("");
    const [active, setActive] = useState(0);
    const inputRef = useRef(null);

    useEffect(() => {
      if (open) {
        setQ(""); setActive(0);
        setTimeout(() => inputRef.current?.focus(), 30);
      }
    }, [open]);

    useEffect(() => {
      if (!open) return;
      const onKey = (e) => {
        if (e.key === "Escape") onClose();
        if (e.key === "ArrowDown") { e.preventDefault(); setActive(a => a + 1); }
        if (e.key === "ArrowUp") { e.preventDefault(); setActive(a => Math.max(0, a - 1)); }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, [open, onClose]);

    useEffect(() => { if (open && window.lucide) window.lucide.createIcons(); });

    const { ARTICLES, VIDEOS } = window.UM_DATA;
    const results = useMemo(() => {
      const ql = q.trim().toLowerCase();
      if (!ql) {
        return { articles: ARTICLES.slice(0, 4), videos: VIDEOS.slice(0, 3), suggested: true };
      }
      const matches = (s) => s && s.toLowerCase().includes(ql);
      return {
        articles: ARTICLES.filter(a => matches(a.title) || matches(a.product) || matches(a.cat) || matches(a.lede)).slice(0, 6),
        videos: VIDEOS.filter(v => matches(v.title) || matches(v.tag)).slice(0, 4),
        suggested: false,
      };
    }, [q]);

    const flatLen = results.articles.length + results.videos.length;
    if (!open) return null;
    const empty = q.trim() && flatLen === 0;

    return (
      <div className="um-search-scrim" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
        <div className="um-search-modal" role="dialog" aria-label="Search Ultra Mode">
          <div className="um-search-input-row">
            <i data-lucide="search"></i>
            <input
              ref={inputRef}
              className="um-search-input"
              type="text"
              placeholder="Search reviews, news, videos…"
              value={q}
              onChange={(e) => { setQ(e.target.value); setActive(0); }}
            />
            <span className="um-search-esc">esc</span>
          </div>
          <div className="um-search-results">
            {empty ? (
              <div className="um-search-empty">
                <div style={{ fontSize: 26, marginBottom: 8 }}>🔍</div>
                <div>No results for "{q}".</div>
              </div>
            ) : (
              <>
                {results.articles.length > 0 && (
                  <>
                    <div className="um-search-section-head">{results.suggested ? "Suggested · Articles" : "Articles"}</div>
                    {results.articles.map((a, i) => (
                      <a
                        key={a.slug}
                        href={`article.html?slug=${a.slug}`}
                        className={`um-search-row ${i === active ? "is-active" : ""}`}
                        onMouseEnter={() => setActive(i)}
                      >
                        <div className="um-search-row-thumb" style={{ background: a.grad }}>
                          <i data-lucide="file-text"></i>
                        </div>
                        <div className="um-search-row-body">
                          <div className="um-search-row-title">{a.title}</div>
                          <div className="um-search-row-meta">{a.kind.toUpperCase()} · {a.cat}</div>
                        </div>
                        <i data-lucide="arrow-up-right" style={{ width: 16, height: 16, color: "var(--um-fg-faint)" }}></i>
                      </a>
                    ))}
                  </>
                )}
                {results.videos.length > 0 && (
                  <>
                    <div className="um-search-section-head">Videos</div>
                    {results.videos.map((v, i) => {
                      const idx = results.articles.length + i;
                      return (
                        <a
                          key={v.slug}
                          href={`video.html?slug=${v.slug}`}
                          className={`um-search-row ${idx === active ? "is-active" : ""}`}
                          onMouseEnter={() => setActive(idx)}
                        >
                          <div className="um-search-row-thumb" style={{ background: v.grad }}>
                            <i data-lucide="play"></i>
                          </div>
                          <div className="um-search-row-body">
                            <div className="um-search-row-title">{v.title}</div>
                            <div className="um-search-row-meta">VIDEO · {v.duration} · {v.views} views</div>
                          </div>
                          <i data-lucide="arrow-up-right" style={{ width: 16, height: 16, color: "var(--um-fg-faint)" }}></i>
                        </a>
                      );
                    })}
                  </>
                )}
              </>
            )}
          </div>
          <div className="um-search-foot">
            <span><kbd style={{ fontFamily: "inherit", padding: "1px 5px", background: "rgba(0,0,0,0.06)", borderRadius: 4 }}>↑↓</kbd> Navigate</span>
            <span><kbd style={{ fontFamily: "inherit", padding: "1px 5px", background: "rgba(0,0,0,0.06)", borderRadius: 4 }}>↵</kbd> Open</span>
            <span><kbd style={{ fontFamily: "inherit", padding: "1px 5px", background: "rgba(0,0,0,0.06)", borderRadius: 4 }}>esc</kbd> Close</span>
            <span style={{ marginLeft: "auto" }}>Press <kbd style={{ fontFamily: "inherit", padding: "1px 5px", background: "rgba(0,0,0,0.06)", borderRadius: 4 }}>/</kbd> anywhere to search</span>
          </div>
        </div>
      </div>
    );
  }
  window.SearchOverlay = SearchOverlay;

  // ── Nav ──────────────────────────────────────────────────────────────
  function Nav({ current }) {
    const [theme, setTheme] = useTheme();
    const [searchOpen, setSearchOpen] = useState(false);

    useEffect(() => {
      const onKey = (e) => {
        const tag = (e.target?.tagName || "").toLowerCase();
        if (tag === "input" || tag === "textarea") return;
        if (e.key === "/" || (e.key === "k" && (e.metaKey || e.ctrlKey))) {
          e.preventDefault();
          setSearchOpen(true);
        }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, []);

    useEffect(() => { if (window.lucide) window.lucide.createIcons(); });

    const links = [
      { href: "reviews.html", id: "reviews", label: "Reviews" },
      { href: "news.html", id: "news", label: "News" },
      { href: "video.html", id: "videos", label: "Videos" },
      { href: "category.html", id: "category", label: "Categories" },
      { href: "about.html", id: "about", label: "About" },
    ];

    return (
      <>
        <nav className="um-nav">
          <a href="index.html" className="um-lockup um-nav-lockup">
            <span className="um-ultra-word">Ultra</span><span className="um-mode-word">Mode</span>
          </a>
          <ul className="um-nav-links">
            {links.map(l => (
              <li key={l.id}>
                <a href={l.href} className={current === l.id ? "is-current" : ""}>{l.label}</a>
              </li>
            ))}
          </ul>
          <div className="um-nav-right">
            <button className="um-search-pill" onClick={() => setSearchOpen(true)}>
              <i data-lucide="search"></i>
              <span>Search</span>
              <kbd>⌘K</kbd>
            </button>
            <button
              className="um-icon-btn"
              onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
              aria-label={theme === "dark" ? "Switch to light theme" : "Switch to dark theme"}
              title={theme === "dark" ? "Light mode" : "Dark mode"}
            >
              <i data-lucide={theme === "dark" ? "sun" : "moon"}></i>
            </button>
            <a href="newsletter.html" className="um-btn um-btn-primary um-btn-sm">Subscribe</a>
          </div>
        </nav>
        <SearchOverlay open={searchOpen} onClose={() => setSearchOpen(false)} />
      </>
    );
  }
  window.Nav = Nav;

  // ── Editorial card ───────────────────────────────────────────────────
  function EdCard({ a }) {
    return (
      <a className="um-edcard" href={`article.html?slug=${a.slug}`}>
        <div className="um-edcard-thumb" style={{ background: a.grad }}>
          <span className="um-edcard-thumb-cat">{a.cat || a.kind}</span>
          {a.score && (
            <div className="um-edcard-thumb-score">
              {a.score}<sup>/10</sup>
            </div>
          )}
        </div>
        <div className="um-eyebrow">
          <span>{a.kind}</span>{a.cat ? <><span className="um-dot" /><span>{a.cat}</span></> : null}
        </div>
        <h3 className="um-edcard-title">{a.title}</h3>
        {a.lede && <p className="um-edcard-lede">{a.lede}</p>}
        <div className="um-edcard-meta">
          <span>{a.author}</span><span>·</span><span>{a.dateLabel}</span><span>·</span><span>{a.read} min</span>
        </div>
      </a>
    );
  }
  window.EdCard = EdCard;

  // ── Hover preview ────────────────────────────────────────────────────
  function HoverPreview({ item, anchor }) {
    if (!item || !anchor) return null;
    const r = anchor.getBoundingClientRect();
    const top = Math.max(80, r.top);
    const left = Math.min(window.innerWidth - 340, r.right + 16);
    return (
      <div className="um-hover-preview is-visible" style={{ top, left }}>
        <div className="um-hover-preview-thumb" style={{ background: item.grad }}></div>
        <div className="um-hover-preview-body">
          <div className="um-eyebrow" style={{ marginBottom: 6 }}>
            <span>{item.kind}</span>{item.cat ? <><span className="um-dot" /><span>{item.cat}</span></> : null}
          </div>
          <h4 className="um-hover-preview-title">{item.title}</h4>
          {item.lede && <p style={{ fontSize: 12, color: "var(--um-fg-muted)", margin: "6px 0 0", lineHeight: 1.4 }}>{item.lede}</p>}
          <div className="um-hover-preview-meta" style={{ marginTop: 10 }}>
            {item.author} · {item.read} min{item.score ? ` · ${item.score}/10` : ""}
          </div>
        </div>
      </div>
    );
  }
  window.HoverPreview = HoverPreview;

  // ── Article row ──────────────────────────────────────────────────────
  function ArticleRow({ a, onHover, onLeave }) {
    const ref = useRef(null);
    return (
      <a
        className="um-article-row"
        href={`article.html?slug=${a.slug}`}
        ref={ref}
        onMouseEnter={() => onHover && onHover(a, ref.current)}
        onMouseLeave={() => onLeave && onLeave()}
      >
        <div className="um-eyebrow um-article-row-tag">
          <span>{a.kind}</span>{a.cat ? <><span className="um-dot" /><span>{a.cat}</span></> : null}
        </div>
        <h3 className="um-article-row-title">{a.title}</h3>
        <div className="um-article-row-meta">
          {a.dateLabel} · {a.read} min{a.score ? ` · ${a.score}/10` : ""}
        </div>
        <i data-lucide="arrow-right" className="um-article-row-arrow"></i>
      </a>
    );
  }
  window.ArticleRow = ArticleRow;

  // ── Newsletter ───────────────────────────────────────────────────────
  function NewsletterForm() {
    const [email, setEmail] = useState("");
    const [status, setStatus] = useState({ kind: "idle", msg: "" });

    const validate = (val) => {
      if (!val) return "Add an email to subscribe.";
      if (!/^\S+@\S+\.\S+$/.test(val)) return "That doesn't look like a valid email.";
      return null;
    };

    const submit = (e) => {
      e.preventDefault();
      const err = validate(email);
      if (err) { setStatus({ kind: "error", msg: err }); return; }
      setStatus({ kind: "done", msg: "" });
    };

    useEffect(() => { if (window.lucide) window.lucide.createIcons(); }, [status.kind]);

    if (status.kind === "done") {
      return (
        <div className="um-newsletter-done">
          <i data-lucide="check-circle"></i>
          <span>You're in. See you Saturday.</span>
        </div>
      );
    }
    return (
      <>
        <form
          className={`um-newsletter-form ${status.kind === "error" ? "has-error" : ""}`}
          onSubmit={submit}
          noValidate
        >
          <input
            type="email"
            placeholder="you@apple.com"
            value={email}
            onChange={(e) => { setEmail(e.target.value); if (status.kind === "error") setStatus({ kind: "idle", msg: "" }); }}
            className="um-newsletter-input"
          />
          <button className="um-btn um-btn-ultra um-btn-pill" type="submit">Subscribe</button>
        </form>
        {status.kind === "error" && <p className="um-newsletter-error">{status.msg}</p>}
      </>
    );
  }
  window.NewsletterForm = NewsletterForm;

  function NewsletterCTA() {
    return (
      <section className="um-newsletter">
        <div className="um-newsletter-inner">
          <div className="um-eyebrow" style={{ color: "rgba(255,255,255,0.7)" }}>
            <span>Saturday Mode</span><span className="um-dot" /><span>Free weekly</span>
          </div>
          <h2 className="um-h2 um-newsletter-title">The week in Apple, decoded.</h2>
          <p className="um-lede um-newsletter-lede">
            Reviews, hot takes, and one really good link, every Saturday morning.
          </p>
          <NewsletterForm />
          <div className="um-newsletter-foot">
            76,400 readers · No spam · Unsubscribe anytime
          </div>
        </div>
      </section>
    );
  }
  window.NewsletterCTA = NewsletterCTA;

  // ── Footer ───────────────────────────────────────────────────────────
  function Footer() {
    return (
      <footer className="um-footer">
        <div className="um-footer-grid">
          <div className="um-footer-brand">
            <a href="index.html" className="um-lockup um-footer-lockup">
              <span className="um-ultra-word">Ultra</span><span className="um-mode-word">Mode</span>
            </a>
            <p className="um-footer-tag">Apple <span className="um-dot" /> Decoded</p>
            <p className="um-footer-blurb">
              Reviews, news, and field tests, in print and on YouTube. We love this stuff. We don't shill.
            </p>
          </div>
          <div>
            <h5 className="um-footer-head">Editorial</h5>
            <ul>
              <li><a href="reviews.html">Reviews</a></li>
              <li><a href="news.html">News</a></li>
              <li><a href="category.html">Categories</a></li>
              <li><a href="reviews.html">Buying guides</a></li>
            </ul>
          </div>
          <div>
            <h5 className="um-footer-head">Channel</h5>
            <ul>
              <li><a href="video.html">YouTube</a></li>
              <li><a href="newsletter.html">Newsletter</a></li>
              <li><a>Podcast</a></li>
              <li><a>RSS</a></li>
            </ul>
          </div>
          <div>
            <h5 className="um-footer-head">Company</h5>
            <ul>
              <li><a href="about.html">About</a></li>
              <li><a href="about.html">Hosts</a></li>
              <li><a>Contact</a></li>
              <li><a>Press kit</a></li>
            </ul>
          </div>
        </div>
        <div className="um-footer-rule" />
        <div className="um-footer-base">
          <span>© 2026 Ultra Mode</span>
          <span>Made in California (mostly)</span>
        </div>
      </footer>
    );
  }
  window.Footer = Footer;
})();
