/* WhoDidItBetter, section V½ of the dossier.
   Famous covers of songs from the album, with an editorial verdict.

   Data shape (essay.whoDidItBetter):
     [
       {
         originalTrack: "Higher Ground",
         coverArtist:   "Red Hot Chili Peppers",
         coverYear:     1989,
         appearedOn:    "Mother's Milk",
         verdict:       "better" | "different" | "lesser",
         verdictBody:   "..."   // 60-100 word defense of the verdict
       }, ...
     ]

   Voice: pick a stance. No "both are great in their own way."
*/

const VERDICT_LABELS = {
  better:    { label: "Cover wins",     short: "Better" },
  different: { label: "Different beast", short: "Different" },
  lesser:    { label: "Doesn't touch it", short: "Lesser" },
};

/* ---------- CoverPlayButton, iTunes 30-second preview player per cover ----------
   Mirrors the track-by-track play behavior. Fetches the iTunes preview URL once
   on mount; click to play/pause. Coordinates with all other audio sources on the
   page (other covers + tracklist) via a window-level event so starting one
   pauses any others. */
function CoverPlayButton({ query, artistHint, kind, compact }) {
  const [status, setStatus] = React.useState("idle"); // idle | loading | playing | nopreview
  const urlRef = React.useRef(null);
  const audioRef = React.useRef(null);
  const queryRef = React.useRef(query);
  const myIdRef = React.useRef(null);

  // Assign a stable per-instance id once
  if (!myIdRef.current) {
    myIdRef.current = "wdib-" + Math.random().toString(36).slice(2, 9);
  }

  // Listen for global "audio started" events; pause this player if someone
  // else started.
  React.useEffect(() => {
    const handler = (ev) => {
      const sender = ev?.detail?.id;
      if (sender && sender !== myIdRef.current && audioRef.current && !audioRef.current.paused) {
        try { audioRef.current.pause(); } catch (e) {}
        setStatus("idle");
      }
    };
    window.addEventListener("bbr-audio-play", handler);
    return () => window.removeEventListener("bbr-audio-play", handler);
  }, []);

  // Fetch preview URL on mount
  React.useEffect(() => {
    queryRef.current = query;
    let cancelled = false;
    setStatus("idle");
    urlRef.current = null;
    fetch("https://itunes.apple.com/search?term=" + encodeURIComponent(query) + "&entity=song&limit=10&media=music")
      .then(r => r.json())
      .then(j => {
        if (cancelled || queryRef.current !== query) return;
        const results = j.results || [];
        const firstName = (artistHint || "").split(/[\s&,]/)[0].toLowerCase();
        const hit =
          (firstName && results.find(r => r.artistName && r.artistName.toLowerCase().includes(firstName) && r.previewUrl)) ||
          results.find(r => r.previewUrl) || null;
        if (hit) {
          urlRef.current = hit.previewUrl;
        } else {
          setStatus("nopreview");
        }
      })
      .catch(() => { if (!cancelled) setStatus("nopreview"); });
    return () => {
      cancelled = true;
      if (audioRef.current) {
        try { audioRef.current.pause(); } catch (e) {}
      }
    };
  }, [query, artistHint]);

  const togglePlay = (e) => {
    e.stopPropagation();
    if (status === "nopreview") return;

    // Announce that this player is starting; all other listeners will pause.
    window.dispatchEvent(new CustomEvent("bbr-audio-play", { detail: { id: myIdRef.current } }));
    // Also pause any in-DOM <audio> elements directly (tracklist on older builds).
    document.querySelectorAll("audio").forEach(a => {
      if (a !== audioRef.current) { try { a.pause(); } catch (err) {} }
    });

    if (!audioRef.current) {
      const a = new Audio();
      a.preload = "auto";
      a.addEventListener("ended", () => setStatus("idle"));
      a.addEventListener("playing", () => setStatus("playing"));
      a.addEventListener("error", () => setStatus("idle"));
      audioRef.current = a;
    }
    const a = audioRef.current;

    if (status === "playing") {
      a.pause();
      setStatus("idle");
      return;
    }

    if (urlRef.current) {
      a.src = urlRef.current;
      a.currentTime = 0;
      setStatus("loading");
      a.play().catch(() => setStatus("idle"));
    } else {
      // Preview hasn't landed yet, show loading, watcher below picks it up
      setStatus("loading");
      let tries = 0;
      const tick = () => {
        tries++;
        if (urlRef.current) {
          a.src = urlRef.current;
          a.currentTime = 0;
          a.play().catch(() => setStatus("idle"));
        } else if (tries < 30) {
          setTimeout(tick, 100);
        } else {
          setStatus("nopreview");
        }
      };
      tick();
    }
  };

  const labelText =
    status === "playing"    ? "Pause" :
    status === "loading"    ? "…" :
    status === "nopreview"  ? "No clip" :
                              "Play";

  return (
    <button
      className={"wdib-play" + (compact ? " wdib-play--compact" : "") + (status === "playing" ? " on" : "") + (status === "nopreview" ? " disabled" : "")}
      onClick={togglePlay}
      disabled={status === "nopreview"}
      title={status === "nopreview" ? "No preview available from Apple iTunes" : (kind === "cover" ? "Play 30-second cover preview" : "Play 30-second original preview")}
      aria-label={kind === "cover" ? "Play cover preview" : "Play original preview"}
    >
      <span className="wdib-play-icon" aria-hidden="true">
        {status === "loading" ? (
          <span className="wdib-play-spinner" />
        ) : status === "playing" ? (
          <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="5" width="4" height="14"/><rect x="14" y="5" width="4" height="14"/></svg>
        ) : (
          <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M7 5v14l12-7z"/></svg>
        )}
      </span>
      {!compact && <span className="wdib-play-label">{labelText}</span>}
    </button>
  );
}

function WhoDidItBetter({ covers, artist }) {
  // Hooks must run unconditionally (Rules of Hooks) — declare state before any
  // early return so the hook order is stable across renders.
  const [activeIdx, setActiveIdx] = React.useState(-1);
  if (!covers || !covers.length) return null;

  // Tallies (e.g. "2 covers · 1 wins · 1 doesn't touch it")
  const tally = covers.reduce((acc, c) => {
    acc[c.verdict] = (acc[c.verdict] || 0) + 1;
    return acc;
  }, {});

  return (
    <div className="wdib">
      {/* Header strip, short editorial intro + tally */}
      <div className="wdib-head">
        <div className="wdib-head-lede">
          <span className="wdib-head-label">Editorial verdicts on</span>
          <strong>{covers.length}</strong> notable cover{covers.length === 1 ? "" : "s"}
          {artist && <span className="wdib-head-of"> of {artist} songs</span>}
        </div>
        <div className="wdib-tally" aria-hidden="true">
          {["better", "different", "lesser"].map(v =>
            tally[v] ? (
              <span key={v} className={"wdib-tally-pill v-" + v}>
                <span className="wdib-tally-dot" />
                {tally[v]} {VERDICT_LABELS[v].short.toLowerCase()}
              </span>
            ) : null
          )}
        </div>
      </div>

      {/* Cover cards */}
      <ol className="wdib-list">
        {covers.map((c, i) => {
          const verdict = VERDICT_LABELS[c.verdict] || VERDICT_LABELS.different;
          const open = activeIdx === i;
          return (
            <li
              key={i}
              className={"wdib-item v-" + (c.verdict || "different") + (open ? " open" : "")}
            >
              <header className="wdib-item-head" onClick={() => setActiveIdx(open ? -1 : i)}>
                <CoverPlayButton
                  query={c.coverArtist + " " + c.originalTrack}
                  artistHint={c.coverArtist}
                  kind="cover"
                  compact={true}
                />
                <span className="wdib-name">{renderText(c.originalTrack)}</span>
                <span className="wdib-meta">
                  <span className="wdib-meta-sep" aria-hidden="true">·</span>
                  <span className="wdib-meta-artist">{renderText(c.coverArtist)}</span>
                  {c.coverYear && <span className="wdib-meta-year">({c.coverYear})</span>}
                </span>
                <span className="wdib-verdict-badge">{verdict.short}</span>
                <span className="wdib-verdict-chev" aria-hidden="true">{open ? "−" : "+"}</span>
              </header>
              <div className="wdib-item-body">
                <div className="wdib-item-body-inner">
                  {c.appearedOn && (
                    <div className="wdib-item-where">
                      On <em>{renderText(c.appearedOn)}</em>{c.coverYear ? ", " + c.coverYear : ""}
                    </div>
                  )}
                  <p>{renderText(c.verdictBody)}</p>
                </div>
              </div>
            </li>
          );
        })}
      </ol>
    </div>
  );
}

window.WhoDidItBetter = WhoDidItBetter;
