/* global React, window */
// Worship Planner — Artwork tab view.
// Renders the visual-art index (window.ART) for the current Sunday, mirroring
// the hymns layout: a "for the day" strip for art keyed to the whole service,
// then one column per reading (OT / Psalm / Epistle / Gospel). Each column
// shows the first few pieces and reveals the rest behind a "show more"
// disclosure. Art is metadata-only — the plate links out to a source image
// when the index has a resolved URL.
//
// Exposed as window.ArtworkView; planner.jsx mounts it in the artwork tab.
// Props: { sunday, hidden (Set of skipped passages), toggleHidden(passage),
//         effTrack (active lectionary track) }
// Art entries may carry a `track` tag (semi|comp|cct|standard); the columns
// filter by the active track via the shared window.trackAllows, exactly like
// the contemporary-songs and solo tabs.

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

  const ART_PASSAGES = ["ot", "psalm", "epistle", "gospel"];
  const INITIAL_VISIBLE = 4;

  // ---- plan glue (mirrors anthems / handbells) ----
  const slug = (s) => (s || "").toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 44);
  function planKeyFor(art, passage) { return `art:${passage}:${slug(art.title)}${art.artist ? ":" + slug(art.artist) : ""}`; }
  function planHymnFor(art) {
    const bits = [];
    if (art.artist) bits.push(art.artist);
    if (art.medium) bits.push(art.medium);
    if (art.year) bits.push(String(art.year));
    return { title: art.title, note: bits.join(" \u00b7 "), artwork: true, _artist: art.artist || "", _year: art.year || "" };
  }

  // "https://www.metmuseum.org/..." -> "metmuseum.org"
  function artHost(url) {
    try { return new URL(url).hostname.replace(/^www\./, ""); }
    catch (_) { return ""; }
  }

  // Minimal framed-landscape glyph — the stand-in for an unshipped image.
  function PlateGlyph() {
    return (
      <svg className="wp-art-thumb-frame" width="22" height="22" viewBox="0 0 24 24"
        fill="none" stroke="currentColor" strokeWidth="1.1"
        strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <rect x="3" y="4.5" width="18" height="15" rx="1" />
        <path d="M3.5 15.5 L9 11 L12.5 14.5 L16 11.5 L20.5 15.5" />
        <circle cx="15.6" cy="8.6" r="1.5" />
      </svg>);
  }

  // Full-bleed lightbox shown when a thumbnail is clicked.
  function ArtLightbox({ art, onClose }) {
    useEffect(() => {
      const onKey = (e) => { if (e.key === "Escape") onClose(); };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, [onClose]);
    return (
      <div className="wp-art-lightbox" onClick={onClose}>
        <div className="wp-art-lightbox-inner" onClick={(e) => e.stopPropagation()}>
          <button className="wp-art-lightbox-x" onClick={onClose} aria-label="Close">×</button>
          <img className="wp-art-lightbox-img" src={art.img} alt={art.title} />
          <div className="wp-art-lightbox-cap">
            <div className="wp-art-lightbox-t">{art.title}</div>
            <div className="wp-art-lightbox-by">
              <span>{art.artist}</span>
              {art.year && <span className="wp-art-lightbox-yr"> · {art.year}</span>}
            </div>
            {art.url &&
              <a className="wp-art-lightbox-src" href={art.url} target="_blank" rel="noopener noreferrer">
                source — {artHost(art.url)} ↗
              </a>}
          </div>
        </div>
      </div>);
  }

  function ArtPlate({ art, passage, onZoom }) {
    const [failed, setFailed] = useState(false);
    // A resolved, still-loading-OK image: show the thumbnail, click to enlarge.
    if (art.img && !failed) {
      return (
        <button type="button" className="wp-art-thumb has-img"
          title="Click to enlarge"
          onClick={(e) => { e.stopPropagation(); onZoom(art); }}>
          <img className="wp-art-thumb-img" src={art.img} alt={art.title}
            loading="lazy" onError={() => setFailed(true)} />
          <span className="wp-art-thumb-zoom" aria-hidden="true">⤢</span>
        </button>);
    }
    // No image (or it failed to load): fall back to the source-link / glyph plate.
    if (art.url) {
      return (
        <a className="wp-art-thumb" href={art.url} target="_blank" rel="noopener noreferrer"
          title={`View source — ${artHost(art.url)}`} onClick={(e) => e.stopPropagation()}>
          <PlateGlyph />
          <span className="wp-art-thumb-go" aria-hidden="true">↗</span>
        </a>);
    }
    return (
      <div className="wp-art-thumb is-nolink" title="No source link in the index">
        <PlateGlyph />
      </div>);
  }

  function ArtCard({ art, passage, onZoom, selected, toggle }) {
    const sel = selected || new Set();
    const tog = toggle || (() => {});
    const k = planKeyFor(art, passage);
    const isSelected = sel.has(k);
    return (
      <div className={`wp-art-card ${isSelected ? "is-selected" : ""}`} data-passage={passage}>
        <button className="wp-art-check" onClick={() => tog(k, planHymnFor(art), passage)}
          aria-pressed={isSelected} title={isSelected ? "Remove from plan" : "Add to service plan"}>
          <svg width="14" height="14" viewBox="0 0 14 14">
            {isSelected ?
              <path d="M3 7 L6 10 L11 4" stroke="currentColor" strokeWidth="1.75" fill="none" /> :
              <circle cx="7" cy="7" r="5" stroke="currentColor" strokeWidth="1" fill="none" opacity="0.4" />}
          </svg>
        </button>
        <ArtPlate art={art} passage={passage} onZoom={onZoom} />
        <div className="wp-art-body">
          <div className="wp-art-title">{art.title}</div>
          <div className="wp-art-byline">
            <span className="wp-art-artist">{art.artist}</span>
            {art.medium &&
              <><span className="wp-art-byline-sep">·</span><span>{art.medium}</span></>}
            {art.year &&
              <><span className="wp-art-byline-sep">·</span><span className="wp-art-year">{art.year}</span></>}
          </div>
          {art.tradition && <span className="wp-art-trad">{art.tradition}</span>}
          {art.blurb && <p className="wp-art-blurb">{art.blurb}</p>}
          {art.warning &&
            <div className="wp-art-warning">
              <span className="wp-art-warning-icon" aria-hidden="true">
                <svg width="13" height="13" viewBox="0 0 16 16">
                  <path d="M8 1 L15 14 L1 14 Z M8 6 L8 10 M8 12 L8 12.5"
                    stroke="currentColor" fill="none" strokeWidth="1.25"
                    strokeLinejoin="round" />
                </svg>
              </span>
              <p className="wp-art-warning-t">{art.warning}</p>
            </div>}
          <div className="wp-art-foot">
            {art.url ?
              <a className="wp-art-view" href={art.url} target="_blank" rel="noopener noreferrer">
                <svg width="11" height="11" viewBox="0 0 12 12" fill="none"
                  stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M4.5 2 L10 2 L10 7.5 M10 2 L5 7 M9 7.5 L9 10 L2 10 L2 3 L4.5 3" />
                </svg>
                <span>{artHost(art.url)}</span>
              </a> :
              <span className="wp-art-nolink-note">no link · search by title</span>}
          </div>
        </div>
      </div>);
  }

  // The passage header — same structure/classes as the hymns tab so the
  // typography, color-coded tag, and skip toggle all match exactly.
  function ArtPassageHead({ pkey, reading, label }) {
    return (
      <section className="wp-passage" data-passage={pkey}>
        <div className="wp-passage-marker">
          <span className="wp-passage-tag">{label}</span>
        </div>
        <div className="wp-passage-body">
          <div className="wp-passage-ref">{reading?.ref}</div>
          {reading?.theme && <p className="wp-passage-theme">{reading.theme}</p>}
        </div>
      </section>);
  }

  function ArtColumn({ pkey, label, reading, items, onZoom, selected, toggle }) {
    const [expanded, setExpanded] = useState(false);
    const count = items.length;
    const overflow = count - INITIAL_VISIBLE;
    const visible = expanded ? items : items.slice(0, INITIAL_VISIBLE);

    return (
      <article className="wp-art-col" data-passage={pkey}>
        <ArtPassageHead pkey={pkey} label={label} reading={reading} />
        {count === 0 ?
            <div className="wp-art-empty">
              <p className="wp-art-empty-text">No artwork indexed for this reading.</p>
            </div> :
            <>
              <div className="wp-art-list">
                {visible.map((art, i) => <ArtCard key={i} art={art} passage={pkey} onZoom={onZoom} selected={selected} toggle={toggle} />)}
              </div>
              {overflow > 0 &&
                <button className="wp-disclosure wp-art-more" onClick={() => setExpanded((v) => !v)}>
                  <span className={`wp-disclosure-caret ${expanded ? "on" : ""}`}>
                    <svg width="9" height="9" viewBox="0 0 9 9"><path d="M2 2 L7 4.5 L2 7 Z" fill="currentColor" /></svg>
                  </span>
                  {expanded ? "Show fewer" : `Show ${overflow} more`}
                  {!expanded && <span className="wp-disclosure-count">{count}</span>}
                  <span className="wp-disclosure-hint">
                    {expanded ? "collapse to the first four" : "more pieces for this reading"}
                  </span>
                </button>}
            </>}
      </article>);
  }

  function ArtWholeStrip({ items, onZoom, selected, toggle }) {
    if (!items || items.length === 0) return null;
    return (
      <section className="wp-art-whole">
        <div className="wp-art-whole-h">
          <span className="wp-art-whole-h-l">For the day</span>
          <span className="wp-art-whole-h-s">Keyed to the service, not one reading</span>
        </div>
        <div className="wp-art-whole-grid">
          {items.map((art, i) => <ArtCard key={i} art={art} passage="whole" onZoom={onZoom} selected={selected} toggle={toggle} />)}
        </div>
      </section>);
  }

  function ArtworkView({ sunday, hidden, effTrack, selected, toggle }) {
    const used = hidden || new Set();
    const [zoom, setZoom] = useState(null);
    const entry = (window.ART || {})[sunday.id];
    const rawSlots = entry ? entry.slots || {} : {};
    const dayWarning = entry ? entry.dayWarning : null;

    // Keep only the pieces that show under the active track (untagged always show).
    const allow = (it) => (window.trackAllows ? window.trackAllows(it.track, effTrack) : true);
    const slots = {};
    ["whole"].concat(ART_PASSAGES).forEach((p) => { slots[p] = (rawSlots[p] || []).filter(allow); });
    const readingOf = (p) => (window.readingForTrack ? window.readingForTrack(sunday, p, effTrack) : sunday.readings[p]);

    const totalCount = ART_PASSAGES.reduce((n, p) => n + slots[p].length, 0) + slots.whole.length;

    if (!entry || totalCount === 0) {
      return (
        <section className="wp-art-empty" style={{ marginTop: 8 }}>
          <p className="wp-art-empty-text">
            No artwork has been indexed for {sunday.day} yet.
          </p>
        </section>);
    }

    return (
      <div className="wp-artwork">
        {dayWarning &&
          <div className="wp-art-daywarn">
            <span className="wp-art-daywarn-icon" aria-hidden="true">
              <svg width="16" height="16" viewBox="0 0 16 16">
                <path d="M8 1 L15 14 L1 14 Z M8 6 L8 10 M8 12 L8 12.5"
                  stroke="currentColor" fill="none" strokeWidth="1.25" strokeLinejoin="round" />
              </svg>
            </span>
            <div>
              <span className="wp-art-daywarn-l">Content advisory</span>
              <p className="wp-art-daywarn-b">{dayWarning}</p>
            </div>
          </div>}

        <ArtWholeStrip items={slots.whole || []} onZoom={setZoom} selected={selected} toggle={toggle} />

        <div className="wp-art-cols-h">
          <span>Art by reading</span>
          <span className="wp-art-cols-h-hint">Bulletin covers · projected slides · banners</span>
        </div>
        <div className="wp-art-cols">
          {ART_PASSAGES.filter((p) => !used.has(p)).map((p) =>
            <ArtColumn key={p} pkey={p}
              label={window.PASSAGE_LABELS[p]}
              reading={readingOf(p)}
              items={slots[p] || []} onZoom={setZoom} selected={selected} toggle={toggle} />)}
        </div>
        {zoom && <ArtLightbox art={zoom} onClose={() => setZoom(null)} />}
      </div>);
  }

  window.ArtworkView = ArtworkView;
})();
