/* ============================================================
   SERMONS PAGE
   ============================================================ */

const YT_API_KEY = 'AIzaSyDYsqthvDl1TygsQt0QPD4PDq4-Q5fsxSM';
const YT_CHANNEL_ID = 'UCvNeLuA60FRBdIHloA1bCpg';
const SHEET_ID = '1NAh-f3ydap1DI0mI7CaLMsUEN_Xy4pS2o9fRlrBYoTA';

// Cache helpers — TTL in ms
function cacheGet(key, ttl) {
  try {
    const raw = localStorage.getItem(key);
    if (!raw) return null;
    const { t, v } = JSON.parse(raw);
    if (Date.now() - t > ttl) return null;
    return v;
  } catch { return null; }
}
function cacheSet(key, v) {
  try { localStorage.setItem(key, JSON.stringify({ t: Date.now(), v })); } catch {}
}

function bestThumb(thumbs) {
  if (!thumbs) return null;
  return (thumbs.maxres && thumbs.maxres.url)
      || (thumbs.standard && thumbs.standard.url)
      || (thumbs.high && thumbs.high.url)
      || (thumbs.medium && thumbs.medium.url)
      || (thumbs.default && thumbs.default.url)
      || null;
}

function relativeDate(d) {
  if (!d) return '';
  const date = new Date(d);
  const days = Math.floor((Date.now() - date.getTime()) / 86400000);
  if (days < 1) return 'Today';
  if (days < 2) return 'Yesterday';
  if (days < 7) return `${days} days ago`;
  if (days < 14) return '1 week ago';
  if (days < 30) return `${Math.floor(days/7)} weeks ago`;
  if (days < 60) return '1 month ago';
  if (days < 365) return `${Math.floor(days/30)} months ago`;
  if (days < 730) return '1 year ago';
  return `${Math.floor(days/365)} years ago`;
}

function SermonsPage() {
  const [query, setQuery] = useState('');
  const [recent, setRecent] = useState(null);
  const [seriesList, setSeriesList] = useState(SERIES); // sheet ordering, hardcoded fallback
  const [seriesData, setSeriesData] = useState({}); // { [playlistId]: { thumb, itemCount, latestTitle, latestDate, latestVid } }

  // Fetch series list from Google Sheet (preserves editorial ordering)
  useEffect(() => {
    const cached = cacheGet('bb_sheet_series', 30 * 60 * 1000); // 30 min
    if (cached) { setSeriesList(cached); return; }
    const url = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?tqx=out:csv&gid=0`;
    fetch(url)
      .then(r => r.ok ? r.text() : Promise.reject(r.status))
      .then(csv => {
        const rows = [];
        let row = [], cell = '', inQ = false;
        for (let i = 0; i < csv.length; i++) {
          const c = csv[i];
          if (inQ) {
            if (c === '"' && csv[i+1] === '"') { cell += '"'; i++; }
            else if (c === '"') { inQ = false; }
            else { cell += c; }
          } else {
            if (c === '"') inQ = true;
            else if (c === ',') { row.push(cell); cell = ''; }
            else if (c === '\n') { row.push(cell); rows.push(row); row = []; cell = ''; }
            else if (c === '\r') {}
            else cell += c;
          }
        }
        if (cell || row.length) { row.push(cell); rows.push(row); }
        const parsed = rows.slice(1).map((r, i) => {
          const rawTitle = (r[0] || '').trim();
          const displayFlag = (r[1] || '').trim().toLowerCase();
          const url = (r[2] || '').trim();
          const m = url.match(/[?&]list=([^&]+)/);
          if (!rawTitle || !m) return null;
          const dash = rawTitle.indexOf(' - ');
          const title = dash > -1 ? rawTitle.slice(dash + 3) : rawTitle;
          const sub = dash > -1 ? rawTitle.slice(0, dash) : '';
          const showTitle = displayFlag === 'yes' || displayFlag === 'y' || displayFlag === 'true';
          return { title, sub, playlistId: m[1], tone: (i % 6) + 1, showTitle };
        }).filter(Boolean);
        if (parsed.length) {
          setSeriesList(parsed);
          cacheSet('bb_sheet_series', parsed);
        }
      })
      .catch(() => {});
  }, []);

  // Fetch recent uploads via YouTube Data API (uploads playlist = channelId with UC→UU)
  useEffect(() => {
    const cached = cacheGet('bb_recent_v2', 60 * 60 * 1000); // 1hr
    if (cached) { setRecent(cached); return; }
    const uploads = 'UU' + YT_CHANNEL_ID.slice(2);
    const url = `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=12&playlistId=${uploads}&key=${YT_API_KEY}`;
    fetch(url)
      .then(r => r.ok ? r.json() : Promise.reject(r.status))
      .then(j => {
        const items = (j.items || []).map(it => ({
          title: it.snippet.title,
          vid: it.snippet.resourceId?.videoId,
          link: `https://www.youtube.com/watch?v=${it.snippet.resourceId?.videoId}`,
          img: bestThumb(it.snippet.thumbnails),
          date: it.snippet.publishedAt
            ? new Date(it.snippet.publishedAt).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })
            : '',
          author: it.snippet.videoOwnerChannelTitle || 'Bethany Baptist',
        }));
        setRecent(items);
        if (items.length) cacheSet('bb_recent_v2', items);
      })
      .catch(() => setRecent([]));
  }, []);

  // Enrich each series with itemCount + latest video via API
  useEffect(() => {
    if (!seriesList.length) return;
    const cached = cacheGet('bb_series_data_v2', 6 * 60 * 60 * 1000); // 6hr
    if (cached) { setSeriesData(cached); return; }
    let cancelled = false;
    (async () => {
      const next = {};
      // Step 1: batch playlists info (50 at a time max — we have ~26)
      const ids = seriesList.map(s => s.playlistId);
      const chunks = [];
      for (let i = 0; i < ids.length; i += 50) chunks.push(ids.slice(i, i + 50));
      for (const chunk of chunks) {
        const url = `https://www.googleapis.com/youtube/v3/playlists?part=snippet,contentDetails&maxResults=50&id=${chunk.join(',')}&key=${YT_API_KEY}`;
        try {
          const r = await fetch(url);
          if (!r.ok) continue;
          const j = await r.json();
          for (const p of (j.items || [])) {
            next[p.id] = {
              thumb: bestThumb(p.snippet.thumbnails),
              itemCount: p.contentDetails?.itemCount || 0,
              latestTitle: null,
              latestDate: null,
              latestVid: null,
            };
          }
        } catch {}
      }
      if (cancelled) return;
      setSeriesData({ ...next });
      // Step 2: fetch the latest video for every series — used for "Latest:" line
      // on featured/recent, and for sorting the archive by recency.
      // Cost: ~1 unit per playlist × ~26 playlists = ~26 units. Negligible.
      for (const s of seriesList) {
        if (cancelled) return;
        try {
          const url = `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=1&playlistId=${s.playlistId}&key=${YT_API_KEY}`;
          const r = await fetch(url);
          if (!r.ok) continue;
          const j = await r.json();
          const it = (j.items || [])[0];
          if (it && next[s.playlistId]) {
            next[s.playlistId].latestTitle = it.snippet.title;
            next[s.playlistId].latestDate = it.snippet.publishedAt;
            next[s.playlistId].latestVid = it.snippet.resourceId?.videoId;
            if (!cancelled) setSeriesData({ ...next });
          }
        } catch {}
      }
      if (!cancelled && Object.keys(next).length) cacheSet('bb_series_data_v2', next);
    })();
    return () => { cancelled = true; };
  }, [seriesList]);

  const visible = useMemo(() => {
    if (!recent) return [];
    if (!query) return recent;
    const q = query.toLowerCase();
    return recent.filter(v => v.title.toLowerCase().includes(q) || (v.author||'').toLowerCase().includes(q));
  }, [recent, query]);

  // Tier the series: [0] = featured current, [1..3] = recent series, rest = archive
  const featured = seriesList[0];
  const recentSeries = seriesList.slice(1, 4);
  // Sort archive by latest-video date (newest first); fall back to sheet order if no date yet
  const archive = useMemo(() => {
    const arr = seriesList.slice(4);
    return arr.slice().sort((a, b) => {
      const da = seriesData[a.playlistId]?.latestDate;
      const db = seriesData[b.playlistId]?.latestDate;
      if (!da && !db) return 0;
      if (!da) return 1;
      if (!db) return -1;
      return new Date(db) - new Date(da);
    });
  }, [seriesList, seriesData]);

  return (
    <>
      <PageHead
        crumbs={[{label:'Home', href:'#/home'}, {label:'Sermons'}]}
        title={<>Sermons &amp; <em style={{fontStyle:'italic',color:'var(--c-accent)',fontWeight:400}}>Series</em></>}
        lede="Every Sunday message, carefully taught and freely shared. Watch live, catch up later, or dig into a full series."
      />

      {/* Hero player */}
      <section style={{ paddingTop: 40 }}>
        <div className="container">
          <div className="yt-hero" style={{ marginBottom: 32 }}>
            <div className="yt-player">
              <iframe
                className="yt-embed"
                src="https://www.youtube.com/embed/videoseries?list=UUvNeLuA60FRBdIHloA1bCpg&rel=0&modestbranding=1"
                title="Latest sermons from Bethany Baptist Church, Bangor"
                loading="lazy"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                referrerPolicy="strict-origin-when-cross-origin"
                allowFullScreen
              />
            </div>
            <div className="yt-player-info">
              <div>
                <div className="yt-live">Latest uploads <span className="dot"/></div>
                <div className="eyebrow" style={{ color: 'var(--c-muted)' }}>Live from our YouTube channel</div>
                <h3 style={{ marginTop: 10, fontSize: '1.8rem' }}>Watch the most recent messages</h3>
                <p style={{ marginTop: 12, color: 'var(--c-muted)', fontSize: 14 }}>
                  Updated automatically · new uploads appear here
                </p>
                <p style={{ fontSize: 15, marginTop: 16 }}>
                  Sunday morning and evening services, plus occasional teaching events — preached clearly, freely shared.
                </p>
              </div>
              <div className="row">
                <a href="https://www.youtube.com/@bethanybaptistbangor/videos" target="_blank" rel="noopener" className="btn btn-primary">Watch on YouTube <Icon.arrow/></a>
                <a href="https://www.youtube.com/@bethanybaptistbangor" target="_blank" rel="noopener" className="btn btn-outline">View channel</a>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* Recent messages — search + grid */}
      <section style={{ paddingTop: 24 }}>
        <div className="container">
          <div className="section-head" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: 20 }}>
            <div>
              <span className="eyebrow">
                {recent === null ? 'Loading…' : `${visible.length} recent message${visible.length === 1 ? '' : 's'}`}
              </span>
              <h2 style={{ marginTop: 10 }}>Recent <em>messages</em></h2>
            </div>
            <div className="sermon-search" style={{ marginTop: 0 }}>
              <Icon.search/>
              <input
                placeholder="Search recent messages…"
                value={query}
                onChange={e => setQuery(e.target.value)}
              />
            </div>
          </div>

          {recent === null && (
            <div className="sermon-row">
              {[0,1,2,3,4,5].map(i => (
                <div key={i} className="sermon-card" style={{ opacity: 0.5 }}>
                  <div className="sermon-thumb" style={{ background: 'var(--c-bg-2)' }}/>
                  <div className="sermon-info">
                    <div style={{ height: 12, width: '40%', background: 'var(--c-bg-2)', borderRadius: 4, marginBottom: 10 }}/>
                    <div style={{ height: 18, width: '80%', background: 'var(--c-bg-2)', borderRadius: 4 }}/>
                  </div>
                </div>
              ))}
            </div>
          )}

          {recent && recent.length === 0 && (
            <div style={{ textAlign: 'center', padding: '60px 20px', color: 'var(--c-muted)' }}>
              <p style={{ marginBottom: 16 }}>Couldn't load recent messages right now.</p>
              <a href="https://www.youtube.com/@bethanybaptistbangor/videos" target="_blank" rel="noopener" className="btn btn-primary">
                <Icon.youtube/> <span style={{ marginLeft: 4 }}>Watch on YouTube</span>
              </a>
            </div>
          )}

          {visible.length > 0 && (
            <div className="sermon-row">
              {visible.map((s, i) => (
                <a key={i} href={s.link} target="_blank" rel="noopener" className="sermon-card">
                  <div className="sermon-thumb">
                    <img src={s.img} alt="" loading="lazy"/>
                    <div className="play-icon">
                      <div><Icon.play style={{ color: 'var(--c-brand)' }}/></div>
                    </div>
                  </div>
                  <div className="sermon-info">
                    <div className="eyebrow" style={{ color: 'var(--c-accent)' }}>{s.date}</div>
                    <h4>{s.title}</h4>
                    <div className="sm-meta">
                      <span>{s.author}</span>
                    </div>
                  </div>
                </a>
              ))}
            </div>
          )}

          <div style={{ textAlign: 'center', marginTop: 48 }}>
            <a href="https://www.youtube.com/@bethanybaptistbangor?sub_confirmation=1" target="_blank" rel="noopener" className="btn btn-outline">
              <Icon.youtube/> <span style={{ marginLeft: 4 }}>Subscribe on YouTube</span>
            </a>
          </div>
        </div>
      </section>

      {/* Series — tiered: featured + recent + archive */}
      <section style={{ paddingTop: 64 }}>
        <div className="container">
          <div className="section-head">
            <span className="eyebrow">Browse by series</span>
            <h2 style={{ marginTop: 10 }}>Sermon <em>series</em></h2>
          </div>

          {/* Featured current series */}
          {featured && (
            <FeaturedSeries series={featured} data={seriesData[featured.playlistId]} />
          )}

          {/* Recently active series */}
          {recentSeries.length > 0 && (
            <div className="series-recent-grid">
              {recentSeries.map(s => (
                <SeriesMidCard key={s.playlistId} series={s} data={seriesData[s.playlistId]} />
              ))}
            </div>
          )}

          {/* Archive — denser image grid */}
          {archive.length > 0 && (
            <div className="series-archive">
              <div className="series-archive-head">
                <h3>Archive</h3>
                <span className="muted">{archive.length} earlier series</span>
              </div>
              <div className="series-archive-grid">
                {archive.map(s => (
                  <SeriesSmallCard key={s.playlistId} series={s} data={seriesData[s.playlistId]} />
                ))}
              </div>
            </div>
          )}
        </div>
      </section>
    </>
  );
}

function FeaturedSeries({ series, data }) {
  const thumb = data?.thumb;
  const count = data?.itemCount;
  const latest = data?.latestTitle;
  const latestRel = relativeDate(data?.latestDate);
  const playlistUrl = `https://www.youtube.com/playlist?list=${series.playlistId}`;
  const handleOpen = () => window.open(playlistUrl, '_blank', 'noopener');
  return (
    <div
      role="link" tabIndex={0}
      onClick={handleOpen}
      onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && (e.preventDefault(), handleOpen())}
      className="series-featured"
      style={{ cursor: 'pointer' }}
    >
      <div className="sf-img">
        {thumb && <img src={thumb} alt="" loading="lazy"/>}
        <div className="sf-badge">Currently preaching</div>
      </div>
      <div className="sf-body">
        {series.sub && <div className="eyebrow" style={{ color: 'var(--c-accent)' }}>{series.sub}</div>}
        <h3 className="sf-title">{series.title}</h3>
        <div className="sf-meta">
          {count > 0 && <span>{count} {count === 1 ? 'message' : 'messages'}</span>}
          {count > 0 && latest && <span className="sf-dot">·</span>}
          {latest && <span>Latest: <em>"{latest}"</em>{latestRel && <span className="muted"> · {latestRel}</span>}</span>}
        </div>
        <div className="row" style={{ marginTop: 24 }}>
          <a
            href={playlistUrl}
            target="_blank" rel="noopener"
            className="btn btn-primary"
            onClick={e => e.stopPropagation()}
          >
            Watch series <Icon.arrow/>
          </a>
          {data?.latestVid && (
            <a
              href={`https://www.youtube.com/watch?v=${data.latestVid}&list=${series.playlistId}`}
              target="_blank" rel="noopener"
              className="btn btn-outline"
              onClick={e => e.stopPropagation()}
            >
              Play latest
            </a>
          )}
        </div>
      </div>
    </div>
  );
}

function SeriesMidCard({ series, data }) {
  const thumb = data?.thumb;
  const count = data?.itemCount;
  const hideText = thumb && series.showTitle === false;
  return (
    <a
      href={`https://www.youtube.com/playlist?list=${series.playlistId}`}
      target="_blank" rel="noopener"
      className={`series-card ${thumb ? 'series-card--img' : `series-card--t${series.tone || 1}`} ${hideText ? 'series-card--notext' : ''}`}
    >
      {thumb && <img src={thumb} alt="" loading="lazy"/>}
      {!hideText && (
        <div className="sc-body">
          {series.sub && <div className="sc-meta">{series.sub}</div>}
          <h4>{series.title}</h4>
          {count > 0 && <div className="sc-count">{count} {count === 1 ? 'msg' : 'msgs'}</div>}
        </div>
      )}
      <svg className="sc-play" viewBox="0 0 24 24" width="28" height="28" fill="currentColor" aria-hidden="true">
        <path d="M8 5v14l11-7z"/>
      </svg>
    </a>
  );
}

function SeriesSmallCard({ series, data }) {
  const thumb = data?.thumb;
  const count = data?.itemCount;
  const hideText = thumb && series.showTitle === false;
  return (
    <a
      href={`https://www.youtube.com/playlist?list=${series.playlistId}`}
      target="_blank" rel="noopener"
      className={`series-card series-card--sm ${thumb ? 'series-card--img' : `series-card--t${series.tone || 1}`} ${hideText ? 'series-card--notext' : ''}`}
    >
      {thumb && <img src={thumb} alt="" loading="lazy"/>}
      {!hideText && (
        <div className="sc-body">
          {series.sub && <div className="sc-meta">{series.sub}</div>}
          <h4>{series.title}</h4>
          {count > 0 && <div className="sc-count">{count} {count === 1 ? 'msg' : 'msgs'}</div>}
        </div>
      )}
      <svg className="sc-play" viewBox="0 0 24 24" width="22" height="22" fill="currentColor" aria-hidden="true">
        <path d="M8 5v14l11-7z"/>
      </svg>
    </a>
  );
}

Object.assign(window, { SermonsPage });
