// YouTube channel integration. The Sermons page embeds curated playlists; the
// home page embeds the channel's uploads playlist. We use YouTube's own iframe
// player UI rather than scraping RSS, so this stays small and reliable.

const YT = {
  // Gerizim Hope Presbyterian Church (Korean main channel)
  channelId: 'UCcV6BoQvlHIhkNk8ln3GN-g',
  channelHandle: '@GHPChurch',
  channelUrl: 'https://www.youtube.com/@GHPChurch',
  // YouTube uploads playlist convention: replace the "UC" channel prefix with "UU".
  uploadsPlaylistId: 'UUcV6BoQvlHIhkNk8ln3GN-g',
  // Curated playlists, in display order. id, label_ko, label_en.
  playlists: [
    { id: 'PLZv23oAzOYyzaEb1XX_3iZ5INV3w4BWmV', ko: '주일예배',  en: "Lord's Day" },
    { id: 'PLZv23oAzOYyz0ygKxkqtmwZ1NHGIdia3W', ko: '수요예배',  en: 'Wednesday' },
    { id: 'PLZv23oAzOYyzN9t5jBvS08wD1eGUPe83g', ko: '새벽예배',  en: 'Dawn' },
    { id: 'PLZv23oAzOYyxqJ_MAWJMUhzce5oI5exrX', ko: '성경공부',  en: 'Bible Study' },
    { id: 'PLZv23oAzOYyxZCppOryyLru4qp9CCkOHz', ko: '특별집회',  en: 'Special' },
    { id: 'PLZv23oAzOYyzElN9pP4ucFQNWBS2y2br7', ko: '특송',      en: 'Songs' },
  ],
};

function YouTubeEmbed({ videoId, playlistId }) {
  const src = videoId
    ? `https://www.youtube.com/embed/${videoId}?rel=0&modestbranding=1`
    : `https://www.youtube.com/embed?listType=playlist&list=${playlistId}&rel=0&modestbranding=1`;

  return (
    <iframe
      key={videoId || playlistId}
      src={src}
      title="Gerizim Hope sermons"
      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
      allowFullScreen
      loading="lazy"
    />
  );
}

// --- YouTube Data API helpers ---
// Quota note: playlistItems.list = 1 unit, videos.list = 1 unit. Results cached
// in localStorage for 15 min to stay well under the 10k/day free quota.

const YT_API_BASE = 'https://www.googleapis.com/youtube/v3';
const YT_CACHE_TTL_MS = 15 * 60 * 1000;

function ytCacheGet(key) {
  try {
    const raw = localStorage.getItem(key);
    if (!raw) return null;
    const { ts, data } = JSON.parse(raw);
    if (Date.now() - ts > YT_CACHE_TTL_MS) return null;
    return data;
  } catch (_) { return null; }
}

function ytCacheSet(key, data) {
  try { localStorage.setItem(key, JSON.stringify({ ts: Date.now(), data })); } catch (_) {}
}

async function ytFetchPlaylistItems(playlistId, maxResults = 12) {
  const key = window.YT_API_KEY;
  if (!key) return null;
  const cacheKey = `yt:items:${playlistId}:${maxResults}`;
  const cached = ytCacheGet(cacheKey);
  if (cached) return cached;
  const url = `${YT_API_BASE}/playlistItems?part=snippet,contentDetails` +
    `&maxResults=${maxResults}&playlistId=${playlistId}&key=${key}`;
  const res = await fetch(url);
  if (!res.ok) return null;
  const json = await res.json();
  const items = (json.items || []).map((it) => {
    const t = it.snippet?.thumbnails || {};
    return {
      videoId: it.contentDetails?.videoId,
      title: it.snippet?.title,
      description: it.snippet?.description,
      publishedAt: it.contentDetails?.videoPublishedAt || it.snippet?.publishedAt,
      thumb: (t.medium || t.high || t.default || {}).url,
    };
  }).filter((v) => v.videoId && v.title && v.title !== 'Private video' && v.title !== 'Deleted video');
  ytCacheSet(cacheKey, items);
  return items;
}

async function ytFetchVideoStatuses(videoIds) {
  const key = window.YT_API_KEY;
  if (!key || !videoIds.length) return {};
  const ids = videoIds.slice(0, 50);
  const cacheKey = `yt:status:${ids.join(',')}`;
  const cached = ytCacheGet(cacheKey);
  if (cached) return cached;
  const url = `${YT_API_BASE}/videos?part=snippet,liveStreamingDetails` +
    `&id=${ids.join(',')}&key=${key}`;
  const res = await fetch(url);
  if (!res.ok) return {};
  const json = await res.json();
  const map = {};
  for (const v of (json.items || [])) {
    map[v.id] = { live: v.snippet?.liveBroadcastContent || 'none' };
  }
  ytCacheSet(cacheKey, map);
  return map;
}

// Returns true if the title contains Hangul characters.
function ytIsKorean(title = '') {
  return /[가-힯ᄀ-ᇿ㄰-㆏]/.test(title);
}

// Latest item from a playlist whose liveBroadcastContent is 'none'. Filters
// by lang ('ko' = Korean titles, 'en' = non-Korean titles). Falls back to any
// playable video if no language-matched item is found.
async function ytLatestPlayableVideo(playlistId, lang) {
  const items = await ytFetchPlaylistItems(playlistId, 20);
  if (!items || !items.length) return null;
  const statuses = await ytFetchVideoStatuses(items.map((i) => i.videoId));
  const isPlayable = (item) => { const s = statuses[item.videoId]; return !s || s.live === 'none'; };
  const langMatch = (item) => lang === 'ko' ? ytIsKorean(item.title) : !ytIsKorean(item.title);
  for (const item of items) {
    if (isPlayable(item) && langMatch(item)) return item;
  }
  for (const item of items) {
    if (isPlayable(item)) return item;
  }
  return items[0];
}

Object.assign(window, {
  YT, YouTubeEmbed,
  ytIsKorean, ytFetchPlaylistItems, ytFetchVideoStatuses, ytLatestPlayableVideo,
});
