// Sayso — "sell around the player" clip viewer.
// Core principle: the clip stays a pure reel — never blocked, covered, or auto-stopped.
// Every Sayso / sales message lives in the empty real estate AROUND the clip:
//   desktop → left rail (clip index + progress) and right rail (active sell panel),
//   mobile  → a fixed top strip above the video.
// The video never loses a pixel; customer words stay inside the clip (verbatim + timecode),
// Sayso words stay in the margins. Auto-advances on end so playback is continuous.

const RL_CSS = `
  .pc-vc, .pfx-cell, .pc-tile, .pfh-morph, .pc-morph { cursor:pointer; }

  .rl-ov { position:fixed; inset:0; z-index:1000; background:rgba(8,6,5,0.96);
    display:flex; align-items:stretch; --rl-pink:#FF238C; }

  /* ── center stage: the clip (pure, centered, never covered) ── */
  .rl-stage { flex:1 1 auto; position:relative; min-width:0; }
  .rl-scroll { position:absolute; inset:0; overflow-y:auto; scroll-snap-type:y mandatory;
    overscroll-behavior:contain; scrollbar-width:none; }
  .rl-scroll::-webkit-scrollbar { display:none; }
  .rl-item { height:100%; scroll-snap-align:start; scroll-snap-stop:always;
    display:flex; align-items:center; justify-content:center; padding:24px; }
  .rl-card { position:relative; overflow:hidden; background:#15110f; border-radius:16px;
    height:min(84vh, 760px); aspect-ratio:9/16; box-shadow:0 24px 80px rgba(0,0,0,0.5); }
  .rl-card img.bg { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transform:scale(1.03); }
  @keyframes rlKen { 0% { transform:scale(1.03); } 100% { transform:scale(1.12); } }
  .rl-card.live img.bg { animation:rlKen 13s ease-in-out infinite alternate; }
  .rl-video { position:absolute; inset:0; width:100%; height:100%; border:0; z-index:1; background:#000; }
  .rl-card .scb { position:absolute; inset:0; z-index:2; pointer-events:none;
    background:linear-gradient(rgba(0,0,0,0) 58%, rgba(0,0,0,0.74)); }
  /* customer words — verbatim, with timecode — the ONLY text allowed on the clip */
  .rl-quote { position:absolute; left:18px; right:18px; bottom:18px; z-index:3; pointer-events:none; }
  .rl-quote q { display:block; quotes:none; font:600 18px/1.32 var(--font-sans); letter-spacing:-0.015em;
    color:#fff; text-shadow:0 1px 14px rgba(0,0,0,0.6); text-wrap:balance; }
  .rl-quote .tc { display:inline-flex; align-items:center; gap:7px; margin-top:10px;
    font:600 11px/1 var(--font-sans); letter-spacing:.06em; color:rgba(255,255,255,0.82); }
  .rl-quote .tc::before { content:""; width:6px; height:6px; border-radius:999px; background:var(--rl-pink); }

  /* ── side rails (desktop) ── */
  .rl-rail { flex:0 0 348px; display:flex; flex-direction:column; color:#fff; padding:54px 44px; }
  .rl-left { justify-content:center; gap:0; }
  .rl-right { justify-content:center; }

  .rl-brand { display:inline-flex; align-items:center; gap:9px; font:600 14px/1 var(--font-sans);
    letter-spacing:-0.01em; color:#fff; margin-bottom:40px; }
  .rl-brand img { width:26px; height:26px; }

  .rl-idxlbl { font:600 12px/1 var(--font-sans); letter-spacing:.14em; text-transform:uppercase;
    color:rgba(255,255,255,0.42); margin-bottom:18px; }
  .rl-idx { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
  .rl-idx button { appearance:none; background:none; border:0; cursor:pointer; width:100%; text-align:left;
    display:flex; align-items:center; gap:14px; padding:13px 0; color:rgba(255,255,255,0.5);
    font:600 17px/1.1 var(--font-sans); letter-spacing:-0.02em; border-top:1px solid rgba(255,255,255,0.1);
    transition:color .25s cubic-bezier(.2,0,0,1); }
  .rl-idx li:last-child button { border-bottom:1px solid rgba(255,255,255,0.1); }
  .rl-idx button:hover { color:rgba(255,255,255,0.85); }
  .rl-idx button .dot { width:7px; height:7px; border-radius:999px; background:currentColor; flex:none; opacity:.4; transition:opacity .25s; }
  .rl-idx button.on { color:#fff; }
  .rl-idx button.on .dot { background:var(--rl-pink); opacity:1; }

  .rl-prog { margin-top:30px; }
  .rl-prog .n { font:600 13px/1 var(--font-sans); letter-spacing:.04em; color:rgba(255,255,255,0.6); }
  .rl-prog .n b { color:#fff; }
  .rl-progbar { margin-top:11px; height:3px; border-radius:3px; background:rgba(255,255,255,0.16); overflow:hidden; }
  .rl-progbar i { display:block; height:100%; background:var(--rl-pink); border-radius:3px;
    transition:width .5s cubic-bezier(.2,0,0,1); }
  .rl-arrows { display:flex; gap:10px; margin-top:30px; }
  .rl-arrows button { appearance:none; cursor:pointer; width:42px; height:42px; border-radius:999px;
    border:1px solid rgba(255,255,255,0.18); background:rgba(255,255,255,0.06); color:#fff;
    display:flex; align-items:center; justify-content:center; transition:background .2s, border-color .2s; }
  .rl-arrows button:hover { background:rgba(255,255,255,0.16); }
  .rl-arrows button:disabled { opacity:.32; cursor:default; }

  /* center-stage side arrows — sideways navigation, always available (wraps) */
  .rl-side { position:absolute; top:50%; transform:translateY(-50%); z-index:6;
    width:46px; height:46px; border-radius:999px; border:0; cursor:pointer;
    background:rgba(0,0,0,0.34); backdrop-filter:blur(8px); color:#fff;
    display:flex; align-items:center; justify-content:center; transition:background .2s, transform .2s; }
  .rl-side:hover { background:rgba(0,0,0,0.6); }
  .rl-side:active { transform:translateY(-50%) scale(.94); }
  .rl-side-prev { left:20px; }
  .rl-side-next { right:20px; }

  /* right sell panel */
  .rl-ctx { display:inline-flex; align-items:center; gap:9px; font:600 12.5px/1 var(--font-sans);
    letter-spacing:.04em; color:rgba(255,255,255,0.6); }
  .rl-ctx .d { width:7px; height:7px; border-radius:999px; background:var(--rl-pink); flex:none; }
  .rl-ctx b { color:#fff; font-weight:600; }
  .rl-msg { font:600 clamp(24px,2vw,30px)/1.18 var(--font-sans); letter-spacing:-0.03em; color:#fff;
    margin:18px 0 0; text-wrap:balance; }
  .rl-btns { display:flex; flex-direction:column; align-items:stretch; gap:12px; margin-top:30px; }
  .rl-btn { appearance:none; cursor:pointer; display:inline-flex; align-items:center; justify-content:center; gap:10px;
    height:54px; padding:0 26px; border-radius:999px; font:600 16px/1 var(--font-sans); letter-spacing:-0.01em;
    border:1px solid transparent; transition:background .18s cubic-bezier(.2,0,0,1), border-color .18s, color .18s, transform .18s; }
  .rl-btn:active { transform:translateY(1px); }
  .rl-btn-pri { background:var(--rl-pink); color:#fff; }
  .rl-btn-pri:hover { background:#F0167E; }
  .rl-btn-sec { background:transparent; color:#fff; border-color:rgba(255,255,255,0.32); }
  .rl-btn-sec:hover { border-color:#fff; }
  .rl-link { align-self:flex-start; appearance:none; background:none; border:0; cursor:pointer; padding:4px 0;
    font:500 14px/1.3 var(--font-sans); color:rgba(255,255,255,0.62); border-bottom:1px solid rgba(255,255,255,0.26); }
  .rl-link:hover { color:#fff; }

  @keyframes rlFade { 0% { opacity:0; transform:translateY(8px); } 100% { opacity:1; transform:none; } }
  .rl-fade { animation:rlFade .42s cubic-bezier(.2,0,0,1) both; }

  /* close */
  .rl-x { position:absolute; top:20px; right:22px; z-index:20; appearance:none; border:0; cursor:pointer;
    width:42px; height:42px; border-radius:999px; background:rgba(255,255,255,0.12); color:#fff;
    display:flex; align-items:center; justify-content:center; transition:background .2s; }
  .rl-x:hover { background:rgba(255,255,255,0.24); }

  /* ── mobile: full-bleed clip + fixed top strip ── */
  .rl-topbar { display:none; }
  @media (max-width: 860px) {
    .rl-rail { display:none; }
    .rl-ov { display:block; --rl-strip:84px; }
    .rl-stage { position:absolute; left:0; right:0; top:var(--rl-strip); bottom:0; }
    .rl-side { width:38px; height:38px; }
    .rl-side-prev { left:8px; }
    .rl-side-next { right:8px; }
    .rl-item { padding:0; }
    .rl-card { width:100%; height:auto; max-height:100%; aspect-ratio:9/16; border-radius:0; box-shadow:none; }
    .rl-topbar { display:flex; position:fixed; top:0; left:0; right:0; z-index:15; height:var(--rl-strip);
      align-items:center; gap:14px; padding:0 16px; background:#0b0908; border-bottom:1px solid rgba(255,255,255,0.08); }
    .rl-tb-msg { flex:1 1 auto; min-width:0; font:600 15px/1.25 var(--font-sans); letter-spacing:-0.02em;
      color:#fff; text-wrap:balance; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
    .rl-tb-cta { flex:none; appearance:none; cursor:pointer; display:inline-flex; align-items:center; gap:7px;
      height:40px; padding:0 16px; border-radius:999px; background:var(--rl-pink); color:#fff; border:0;
      font:600 14px/1 var(--font-sans); letter-spacing:-0.01em; white-space:nowrap; }
    .rl-x { top:auto; bottom:18px; right:16px; background:rgba(0,0,0,0.42); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); }
    .rl-quote q { font-size:16px; }
  }
  @media (prefers-reduced-motion: reduce) {
    .rl-card.live img.bg { animation:none; }
    .rl-fade { animation:none; }
  }
`;

// ── the four real customer films — the sell experience runs on these ──
// The swipe player (Instagram-style) and the grid are now ONE dataset: both come
// from the central proof store, in the same order. Clicking grid story #i opens
// the swipe player at story #i — they can never drift apart again.
// Sell-margin copy is paired by position (purely persuasive, not clip-specific).
const RL_SELL = [
  { sell: "That's one cut from one interview. We'd pull 3\u20134 like it from yours.", sellShort: "3\u20134 cuts like this from your interview." },
  { sell: "This ran on autopilot after one shoot day. So would yours.", sellShort: "Set up once. Then it runs on autopilot." },
  { sell: "One interview. A full set of clips to run. Delivered in 20 days.", sellShort: "A full set of clips in 20 days." },
  { sell: "Real customer proof your sales team can send tomorrow.", sellShort: "Proof your sales team can send tomorrow." },
];
const _rlStore = (window.SaysoFilms ? window.SaysoFilms.get() : { proof: [], playlist: [] });
const _proofClips = (_rlStore.proof || []).map(function (p, i) {
  const sc = RL_SELL[i % RL_SELL.length];
  return { id: "rl-" + (p.key || i), logo: (p.company || p.brand || "").trim(), city: p.city, img: p.img,
    pos: p.pos || "center 18%", vid: p.id, vh: p.h, quote: p.hook, tc: p.dur, sell: sc.sell, sellShort: sc.sellShort };
});
// Player-only films (no home-page card): run AFTER the grid stories.
const _extraClips = (_rlStore.playlist || []).filter(function (p) { return p && p.id; }).map(function (p, i) {
  const sc = RL_SELL[(_proofClips.length + i) % RL_SELL.length];
  return { id: "pl-" + (p.key || i), logo: (p.brand || p.company || "More films").trim(), city: p.city || "",
    img: p.img || "", pos: p.pos || "center 18%", vid: p.id, vh: p.h, quote: p.quote || "", tc: p.dur || "",
    sell: p.sell || sc.sell, sellShort: p.sellShort || sc.sellShort };
});
const SELL_CLIPS = _proofClips.concat(_extraClips);

// escalation copy — switches in ambiently after a couple of clips
const RL_CONVO = "You've watched a few \u2014 want to see what we'd cut from your interview?";
const RL_CONVO_SHORT = "Want to see what we'd cut from your interview?";

// map a clicked element → starting clip index in SELL_CLIPS
function rlStartFor(t) {
  if (!t || !t.closest) return 0;
  const tile = t.closest(".pc-tile");
  if (tile) {
    const tiles = [...document.querySelectorAll(".pc-wall .pc-tile")];
    return Math.max(0, tiles.indexOf(tile));
  }
  return 0; // library / hero / any other video → start at the first film
}

function rlEmbed(r) {
  let u = "https://player.vimeo.com/video/" + r.vid + "?autoplay=1&muted=0&title=0&byline=0&portrait=0&playsinline=1&dnt=1";
  if (r.vh) u += "&h=" + r.vh;
  return u;
}

function RlIcon({ name }) {
  const common = { width: 19, height: 19, viewBox: "0 0 44 44", fill: "none", stroke: "currentColor", strokeWidth: 2.4, strokeLinecap: "round", strokeLinejoin: "round" };
  if (name === "plus") return <svg {...common}><path d="M22 12v20M12 22h20" /></svg>;
  if (name === "cal") return <svg {...common}><rect x="9" y="12" width="26" height="23" rx="4" /><path d="M9 19h26M16 9v6M28 9v6" /></svg>;
  if (name === "up") return <svg {...common}><path d="M12 27l10-10 10 10" /></svg>;
  if (name === "down") return <svg {...common}><path d="M12 17l10 10 10-10" /></svg>;
  if (name === "left") return <svg {...common}><path d="M27 12L17 22l10 10" /></svg>;
  if (name === "right") return <svg {...common}><path d="M17 12l10 10-10 10" /></svg>;
  return null;
}

// ── a single clip — pure reel: video + the customer's verbatim words only ──
function ReelCard({ r, active, onEnded }) {
  const wrapRef = React.useRef(null);
  const cardRef = React.useRef(null);
  React.useEffect(() => {
    if (!active || !wrapRef.current || typeof window.Vimeo === "undefined") return;
    const iframe = wrapRef.current.querySelector("iframe");
    if (!iframe) return;
    let player;
    try {
      player = new window.Vimeo.Player(iframe);
      player.on("ended", onEnded);
    } catch (e) { /* ignore */ }
    return () => {
      if (player) { try { player.off("ended"); player.unload && player.unload(); } catch (e) {} }
    };
  }, [active]);
  return (
    <div className={"rl-card" + (active ? " live" : "")} ref={cardRef}>
      {r.img
        ? <img className="bg" src={r.img} alt="" draggable="false" style={{ objectPosition: r.pos }} />
        : <div className="bg" style={{ position: "absolute", inset: 0, background: "#15110f" }} />}
      {active && (
        <div ref={wrapRef} style={{ position: "absolute", inset: 0, zIndex: 1 }}>
          <iframe className="rl-video" src={rlEmbed(r)} title={r.logo + " customer testimonial"} frameBorder="0" allow="autoplay; fullscreen; picture-in-picture"></iframe>
        </div>
      )}
      <div className="scb"></div>
      <div className="rl-quote">
        <q>{r.quote}</q>
        <span className="tc">{r.logo} · {r.tc}</span>
      </div>
    </div>
  );
}

// ── the overlay — clip in the middle, sell in the margins ──
function ReelsOverlay() {
  const [open, setOpen] = React.useState(false);
  const [act, setAct] = React.useState(0);
  const scRef = React.useRef(null);
  const openRef = React.useRef(false);
  const actRef = React.useRef(0); // live index — keydown handler reads this (avoids stale closure)
  const viewedRef = React.useRef(new Set());
  const [vcount, setVcount] = React.useState(0);
  openRef.current = open;

  React.useEffect(() => {
    window.__openReels = (group, startId, startIndex) => {
      const i = typeof startIndex === "number" ? startIndex : 0;
      viewedRef.current = new Set([i]);
      setVcount(1);
      actRef.current = i;
      setAct(i);
      setOpen(true);
    };
    const onClick = (e) => {
      if (openRef.current) return;
      const t = e.target;
      if (!t.closest) return;
      const hit = t.closest(".pc-tile, .pc-vc, .pfx-cell, .pfh-morph, .pc-morph");
      if (!hit) return;
      if (hit.closest(".pfx-card.is-main")) return; // main testimonial film has its own landscape player
      if (hit.closest("[data-own-video]") || (hit.matches && hit.matches("[data-own-video]"))) return; // cards wired to their own clip
      e.preventDefault(); e.stopPropagation();
      window.__openReels(null, null, rlStartFor(t));
    };
    document.addEventListener("click", onClick, true);
    return () => document.removeEventListener("click", onClick, true);
  }, []);

  React.useEffect(() => {
    if (!open) return;
    document.body.style.overflow = "hidden";
    const onKey = (e) => {
      if (e.key === "Escape") { setOpen(false); return; }
      if (e.key === "ArrowDown" || e.key === "ArrowRight") { e.preventDefault(); nav(1); }
      if (e.key === "ArrowUp" || e.key === "ArrowLeft") { e.preventDefault(); nav(-1); }
    };
    window.addEventListener("keydown", onKey);
    const el = scRef.current;
    actRef.current = act;
    if (el) requestAnimationFrame(() => { el.scrollTop = act * el.clientHeight; });
    return () => { document.body.style.overflow = ""; window.removeEventListener("keydown", onKey); };
  }, [open]);

  const goTo = (i) => {
    const el = scRef.current; if (!el) return;
    const len = SELL_CLIPS.length || 1;
    const n = ((i % len) + len) % len; // wrap: always lands on a real clip, never stuck
    actRef.current = n;
    el.scrollTo({ top: n * el.clientHeight, behavior: "smooth" });
    setAct(n);
    if (!viewedRef.current.has(n)) { viewedRef.current.add(n); setVcount(viewedRef.current.size); }
  };
  const nav = (d) => goTo(actRef.current + d);
  const onEnded = () => goTo(actRef.current + 1);

  const onScroll = () => {
    const el = scRef.current; if (!el) return;
    const i = Math.round(el.scrollTop / el.clientHeight);
    if (i !== actRef.current) {
      actRef.current = i;
      setAct(i);
      if (!viewedRef.current.has(i)) { viewedRef.current.add(i); setVcount(viewedRef.current.size); }
    }
  };

  if (!open) return null;
  const clip = SELL_CLIPS[act] || SELL_CLIPS[0];
  const esc = vcount >= 2;
  const goBook = () => { setOpen(false); requestAnimationFrame(() => { window.pcGo((window.PC_LINKS && window.PC_LINKS.planningCall) || "https://www.sayso.video/book-a-meeting"); }); };
  const msg = esc ? RL_CONVO : clip.sell;
  const msgShort = esc ? RL_CONVO_SHORT : clip.sellShort;

  return (
    <div className="rl-ov">
      {/* LEFT RAIL — index + progress (desktop) */}
      <aside className="rl-rail rl-left">
        <span className="rl-brand"><img src="assets/logos/sayso-icon.png" alt="" draggable="false" />Sayso</span>
        <div className="rl-idxlbl">Customer films</div>
        <ul className="rl-idx">
          {SELL_CLIPS.map((c, i) => (
            <li key={c.id}>
              <button type="button" className={i === act ? "on" : ""} onClick={() => goTo(i)}>
                <span className="dot"></span>{c.logo}
              </button>
            </li>
          ))}
        </ul>
        <div className="rl-prog">
          <span className="n"><b>{act + 1}</b> of {SELL_CLIPS.length}</span>
          <div className="rl-progbar"><i style={{ width: ((act + 1) / SELL_CLIPS.length * 100) + "%" }}></i></div>
        </div>
        <div className="rl-arrows">
          <button type="button" onClick={() => nav(-1)} aria-label="Previous"><RlIcon name="up" /></button>
          <button type="button" onClick={() => nav(1)} aria-label="Next"><RlIcon name="down" /></button>
        </div>
      </aside>

      {/* CENTER — the pure clip */}
      <div className="rl-stage">
        <button type="button" className="rl-side rl-side-prev" onClick={() => nav(-1)} aria-label="Previous film"><RlIcon name="left" /></button>
        <div className="rl-scroll" ref={scRef} onScroll={onScroll}>
          {SELL_CLIPS.map((r, i) => (
            <div key={r.id} className="rl-item">
              <ReelCard r={r} active={i === act} onEnded={onEnded} />
            </div>
          ))}
        </div>
        <button type="button" className="rl-side rl-side-next" onClick={() => nav(1)} aria-label="Next film"><RlIcon name="right" /></button>
      </div>

      {/* RIGHT RAIL — active sell panel (desktop) */}
      <aside className="rl-rail rl-right">
        <div className="rl-fade" key={act + "-" + esc}>
          <div className="rl-ctx"><span className="d"></span><b>{clip.logo}</b> · {clip.city}</div>
          <p className="rl-msg">{msg}</p>
          <div className="rl-btns">
            {esc ? (
              <React.Fragment>
                <button type="button" className="rl-btn rl-btn-pri" onClick={goBook}><RlIcon name="cal" />Book 10 minutes</button>
                <button type="button" className="rl-link" onClick={goBook}>Add Testimonial Ads</button>
              </React.Fragment>
            ) : (
              <React.Fragment>
                <button type="button" className="rl-btn rl-btn-pri" onClick={goBook}><RlIcon name="plus" />Add Testimonial Ads</button>
                <button type="button" className="rl-btn rl-btn-sec" onClick={goBook}><RlIcon name="cal" />Book 10 min</button>
              </React.Fragment>
            )}
          </div>
        </div>
      </aside>

      {/* MOBILE — fixed top strip (sits above the video, never over it) */}
      <div className="rl-topbar">
        <span className="rl-tb-msg rl-fade" key={"m" + act + "-" + esc}>{msgShort}</span>
        <button type="button" className="rl-tb-cta" onClick={goBook}>
          <RlIcon name={esc ? "cal" : "plus"} />{esc ? "Book 10 min" : "Add Clips"}
        </button>
      </div>

      <button type="button" className="rl-x" onClick={() => setOpen(false)} aria-label="Close">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"><path d="M5 5l14 14M19 5 5 19" /></svg>
      </button>
    </div>
  );
}

Object.assign(window, { RL_CSS, ReelsOverlay });
