// site-programme-hotpage.jsx
// Replaces the normal Programme page when festival.streaming.enabled === true.
// Toggle OFF → normal <Programme> loads instead (routing handled in site-shell.jsx).

const PH_STRANDS = {
  Fiction:      { color:"#ff5c70", dark:"#2d1019", desc:"Scripted, acted, directed — stories imagined and put on screen. From intimate drama to dark comedy, the oldest tradition in cinema still finding new ground." },
  Documentary:  { color:"#9b6fc0", dark:"#241646", desc:"Films rooted in reality. Observational, investigative, personal — work that bears witness to the world as it is, whether intimate or expansive." },
  Animation:    { color:"#ffc436", dark:"#2d230c", desc:"Hand-drawn, painted, and crafted frame by frame. Animation as a form in its own right — every second a deliberate work of craft." },
  Experimental: { color:"#5fd0d8", dark:"#0b2126", desc:"Films that question what cinema can be. Structural, essayistic, formally adventurous — work that doesn't fit neatly anywhere else." },
};

function phFallback(sc) {
  return `linear-gradient(135deg,${sc.dark} 0%,#16151a 100%)`;
}

function phStill(fl, ovr) {
  return (ovr && ovr.stillOverride) || fl.stillsImages?.[0]?.url || fl.bannerUrl || fl.poster || "";
}

function PHFilmCard({ fl, sc, ovr, navigate }) {
  const still   = phStill(fl, ovr);
  const hasVideo = !!(ovr && ovr.videoUrl);
  const [hov, setHov] = React.useState(false);

  function fmt(mins, secs) {
    const m = parseInt(mins)||0, s = parseInt(secs)||0;
    if (!m && !s) return "";
    return s ? m + "'" + String(s).padStart(2,"0") + "\"" : m + "'";
  }
  const runtime = fmt(fl.runtime, fl.runtimeSecs);

  return (
    <div
      onClick={() => navigate("/film/" + fl.id)}
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      style={{ flex:"none", width:"clamp(220px,20vw,290px)", cursor:"pointer",
        scrollSnapAlign:"start",
        transform: hov ? "translateY(-7px)" : "translateY(0)",
        transition:"transform .26s cubic-bezier(.2,.7,.3,1)" }}>

      {/* 16:9 thumbnail */}
      <div style={{ position:"relative", width:"100%", aspectRatio:"16/9",
        overflow:"hidden", background:sc.dark }}>
        {/* Fallback gradient */}
        <div style={{ position:"absolute", inset:0, zIndex:0, background:phFallback(sc) }}></div>
        {/* Still */}
        {still && (
          <img src={still} alt={fl.title}
            style={{ position:"absolute", inset:0, width:"100%", height:"100%",
              objectFit:"cover", zIndex:1,
              transform: hov ? "scale(1.04)" : "scale(1)",
              transition:"transform .5s cubic-bezier(.2,.7,.3,1)" }} />
        )}
        {/* Scrim */}
        <div style={{ position:"absolute", inset:0, zIndex:2, pointerEvents:"none",
          background:"linear-gradient(0deg,rgba(18,17,22,.94) 0%,rgba(18,17,22,.08) 55%,transparent 75%)" }}></div>
        {/* Strand colour tick */}
        <div style={{ position:"absolute", top:0, left:0, right:0, height:3, zIndex:3, background:sc.color }}></div>
        {/* Watch badge */}
        {hasVideo && (
          <div style={{ position:"absolute", top:10, right:10, zIndex:3,
            fontFamily:"monospace", fontSize:8, letterSpacing:".18em", textTransform:"uppercase",
            padding:"4px 8px", background:sc.color, color:"#141318", fontWeight:700 }}>
            Watch
          </div>
        )}
        {/* Play hover */}
        <div style={{ position:"absolute", inset:0, zIndex:3,
          display:"flex", alignItems:"center", justifyContent:"center",
          opacity: hov ? 1 : 0, background:"rgba(18,17,22,.36)", transition:".2s" }}>
          <span style={{ width:52, height:52,
            background:"rgba(255,255,255,.13)", border:"1.5px solid rgba(255,255,255,.82)",
            backdropFilter:"blur(8px)", display:"flex", alignItems:"center", justifyContent:"center" }}>
            <svg viewBox="0 0 24 24" fill="#fff" width="19" height="19" style={{ marginLeft:3 }}>
              <path d="M8 5v14l11-7z"/>
            </svg>
          </span>
        </div>
        {/* Title */}
        <div style={{ position:"absolute", left:14, right:14, bottom:12, zIndex:3,
          fontFamily:"var(--display)", fontSize:17, lineHeight:.94,
          textTransform:"uppercase", letterSpacing:"-.015em",
          color:"#f0eee9", textWrap:"balance" }}>{fl.title}</div>
      </div>

      {/* Caption */}
      <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between",
        gap:10, marginTop:9, padding:"0 2px" }}>
        <span style={{ fontSize:12, color:"rgba(240,238,233,.58)", overflow:"hidden",
          textOverflow:"ellipsis", whiteSpace:"nowrap" }}>dir. {fl.directors}</span>
        {runtime && (
          <span style={{ fontFamily:"monospace", fontSize:10,
            color:"rgba(240,238,233,.46)", whiteSpace:"nowrap" }}>{runtime}</span>
        )}
      </div>
    </div>
  );
}

function PHStrandSection({ strand, films, overrides, navigate, defaultOpen }) {
  const sc       = PH_STRANDS[strand] || PH_STRANDS.Fiction;
  const trackRef = React.useRef(null);
  const [canPrev, setCanPrev] = React.useState(false);
  const [canNext, setCanNext] = React.useState(true);

  const updateArrows = () => {
    const t = trackRef.current; if (!t) return;
    setCanPrev(t.scrollLeft > 4);
    setCanNext(t.scrollLeft < t.scrollWidth - t.clientWidth - 4);
  };

  const scroll = dir => {
    if (trackRef.current) trackRef.current.scrollBy({ left: dir * 600, behavior:"smooth" });
  };

  return (
    <div style={{ marginBottom:"clamp(40px,5vw,64px)" }}>
      {/* Strand header */}
      <div className="wrap" style={{ display:"flex", alignItems:"flex-end", justifyContent:"space-between",
        gap:"16px 28px", marginBottom:22, flexWrap:"wrap" }}>
        <div style={{ display:"flex", alignItems:"flex-start", gap:16 }}>
          <div style={{ width:4, minHeight:48, background:sc.color, flexShrink:0, marginTop:4 }}></div>
          <div>
            <div style={{ fontFamily:"var(--display)", fontSize:"clamp(22px,4vw,48px)",
              textTransform:"uppercase", letterSpacing:"-.02em", lineHeight:.92,
              color:"#f0eee9", marginBottom:10 }}>{strand}</div>
            <div style={{ fontSize:13, color:"rgba(240,238,233,.56)", lineHeight:1.6,
              maxWidth:480 }}>{sc.desc}</div>
          </div>
        </div>
        {/* Count + arrows */}
        <div style={{ display:"flex", alignItems:"center", gap:14, flexShrink:0 }}>
          <span style={{ fontFamily:"monospace", fontSize:10, letterSpacing:".16em",
            textTransform:"uppercase", color:"rgba(240,238,233,.38)" }}>
            {films.length} film{films.length !== 1 ? "s" : ""}
          </span>
          <div style={{ display:"flex", gap:7 }}>
            {[-1,1].map(dir => (
              <button key={dir} onClick={() => scroll(dir)}
                disabled={dir === -1 ? !canPrev : !canNext}
                style={{ width:40, height:40, borderRadius:"50%", background:"transparent",
                  border:"1px solid rgba(240,238,233,.2)", cursor:"pointer",
                  display:"flex", alignItems:"center", justifyContent:"center",
                  color:"#f0eee9", transition:".16s",
                  opacity: (dir === -1 ? !canPrev : !canNext) ? .22 : 1 }}>
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" width="16" height="16">
                  {dir === -1 ? <path d="M15 18l-6-6 6-6"/> : <path d="M9 18l6-6-6-6"/>}
                </svg>
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Rail — edge fade via separate overlay layers (opacity-transitionable) */}
        <div className="wrap">
          <div style={{ position:"relative" }}>
          <div ref={trackRef} onScroll={updateArrows}
            style={{ display:"flex", gap:16, overflowX:"auto",
              padding:"4px 0 12px",
              scrollSnapType:"x proximity", scrollBehavior:"smooth",
              msOverflowStyle:"none", scrollbarWidth:"none" }}>
            {films.map(fl => (
              <PHFilmCard key={fl.id} fl={fl} sc={sc}
                ovr={overrides[fl.id] || null} navigate={navigate} />
            ))}
          </div>
          <div style={{ position:"absolute", top:0, bottom:12, left:0, width:90, pointerEvents:"none",
            background:"linear-gradient(to right, var(--ink), transparent)",
            opacity: canPrev ? 1 : 0, transition:"opacity .35s ease" }} />
          <div style={{ position:"absolute", top:0, bottom:12, right:0, width:90, pointerEvents:"none",
            background:"linear-gradient(to left, var(--ink), transparent)",
            opacity: canNext ? 1 : 0, transition:"opacity .35s ease" }} />
          </div>
        </div>
      {/* Divider */}
      <div style={{ margin:"0 clamp(20px,4vw,48px)", marginTop:24,
        height:1, background:"linear-gradient(90deg,rgba(240,238,233,.1),transparent)" }}></div>
    </div>
  );
}

function ProgrammeHotpage({ navigate, strand: activeStrand }) {
  const d         = useSite();
  const f         = d.festival || {};
  const str       = f.streaming || {};
  const overrides = str.filmOverrides || {};
  const year      = String(f.year || new Date().getFullYear());

  const films = (d.films || []).filter(fl =>
    String(fl.year || f.year) === year
  );

  const totalFilms = films.length;
  const withVideo  = Object.values(overrides).filter(o => o.videoUrl).length;

  // Group by strand — order follows the CMS-configurable strand order (Programme → Strand settings)
  const phOrder = window.getStrandOrder(f);
  const byStrand = {};
  phOrder.forEach(s => { byStrand[s] = films.filter(fl => fl.strand === s); });

  // Auto-scroll to strand if navigated with #/programme/Fiction etc.
  const strandRefs = React.useRef({});
  React.useEffect(() => {
    if (!activeStrand) return;
    const el = strandRefs.current[activeStrand];
    if (el) {
      const top = el.getBoundingClientRect().top + window.scrollY - 90;
      window.scrollTo({ top, behavior:"smooth" });
    }
  }, [activeStrand]);

  return (
    <div style={{ background:"var(--ink)", minHeight:"100vh", color:"#f0eee9" }}>

      {/* ── Hero ── */}
      <div style={{ paddingBlock:"clamp(80px,10vh,120px) clamp(48px,6vh,72px)",
        borderBottom:"1px solid rgba(240,238,233,.08)" }}>
        <div className="wrap">
        {/* Live badge */}
        <div style={{ display:"inline-flex", alignItems:"center", gap:9, marginBottom:24,
          fontFamily:"monospace", fontSize:9, letterSpacing:".24em", textTransform:"uppercase",
          color:"#ff5c70" }}>
          <span style={{ width:7, height:7, borderRadius:"50%", background:"#ff5c70",
            animation:"ph-pulse 2s infinite", display:"inline-block" }}></span>
          Streaming Now · Sixth Edition {year}
        </div>
        <h1 style={{ fontFamily:"var(--display)", fontSize:"clamp(28px,7vw,110px)",
          letterSpacing:"-.03em", textTransform:"uppercase", lineHeight:.88,
          marginBottom:24, color:"#f0eee9" }}>
          The Programme
        </h1>
        <div style={{ display:"flex", alignItems:"center", gap:"clamp(16px,3vw,48px)",
          flexWrap:"wrap", overflow:"hidden" }}>
          <p style={{ fontSize:"clamp(13px,1.1vw,15px)", color:"rgba(240,238,233,.55)",
            lineHeight:1.7, maxWidth:440 }}>
            {totalFilms} films across four strands — free to stream during the festival week.
            {withVideo > 0 && ` ${withVideo} film${withVideo !== 1 ? "s" : ""} ready to watch now.`}
          </p>
          {/* Strand quick-links */}
          <div className="ph-strand-tabs" style={{ display:"flex", gap:8, flexWrap:"wrap" }}>
            {phOrder.filter(s => byStrand[s].length > 0).map(s => {
              const sc = PH_STRANDS[s];
              return (
                <button key={s}
                  onClick={() => {
                    const el = strandRefs.current[s];
                    if (el) { const top = el.getBoundingClientRect().top + window.scrollY - 90; window.scrollTo({ top, behavior:"smooth" }); }
                  }}
                  style={{ fontFamily:"monospace", fontSize:10, letterSpacing:".12em",
                    textTransform:"uppercase", padding:"9px 15px", borderRadius:0,
                    border:`1px solid ${sc.color}55`, background:"transparent",
                    color:sc.color, cursor:"pointer", transition:".14s" }}
                  onMouseEnter={e => { e.currentTarget.style.background = sc.color + "22"; }}
                  onMouseLeave={e => { e.currentTarget.style.background = "transparent"; }}>
                  {s} <span style={{ opacity:.6 }}>{String(byStrand[s].length).padStart(2,"0")}</span>
                </button>
              );
            })}
          </div>
        </div>
        </div>{/* close wrap */}
      </div>

      {/* ── Strand sections ── */}
      <div style={{ paddingTop:"clamp(40px,5vw,60px)" }}>
        {phOrder.filter(s => byStrand[s].length > 0).map(s => (
          <div key={s} ref={el => strandRefs.current[s] = el}>
            <PHStrandSection
              strand={s}
              films={byStrand[s]}
              overrides={overrides}
              navigate={navigate} />
          </div>
        ))}
      </div>

      {/* ── Footer note ── */}
      <div style={{ paddingBlock:"clamp(24px,3vw,36px) clamp(48px,6vh,72px)",
        borderTop:"1px solid rgba(240,238,233,.06)" }}>
        <div className="wrap">
        <p style={{ fontFamily:"monospace", fontSize:10, letterSpacing:".16em",
          textTransform:"uppercase", color:"rgba(240,238,233,.28)" }}>
          Films available to stream during the festival week only.
          All rights remain with the filmmakers.
        </p>
        </div>{/* close wrap */}
      </div>

      <style>{`
        @keyframes ph-pulse {
          0%  { box-shadow:0 0 0 0 rgba(255,92,112,.55); }
          70% { box-shadow:0 0 0 8px rgba(255,92,112,0); }
          100%{ box-shadow:0 0 0 0 rgba(255,92,112,0); }
        }
      `}</style>
    </div>
  );
}

Object.assign(window, { ProgrammeHotpage });
