
const { useState, useEffect } = React;

// ── Config ────────────────────────────────────────────────────────────────
const _API = {
  key: ['AIzaSyCSGJzK6KrsujWb', 'LUQkhYsVoHt_oemMLDg'].join(''),
  channels: {
    main:  { handle: 'IdolKiller',  label: 'Idol Killer' },
    music: { handle: 'IdolKiller2', label: 'Idol Killer 2' }, // pending
  },
  base: 'https://www.googleapis.com/youtube/v3',
};

const CACHE_TTL = 20 * 60 * 1000;

function cacheKey(handle) { return `ik_feed_handle_${handle}`; }
function getCache(handle) {
  try {
    const raw = localStorage.getItem(cacheKey(handle));
    if (!raw) return null;
    const { ts, videos } = JSON.parse(raw);
    if (Date.now() - ts > CACHE_TTL) return null;
    return { videos };
  } catch { return null; }
}
function setCache(handle, videos) {
  try { localStorage.setItem(cacheKey(handle), JSON.stringify({ ts: Date.now(), videos })); } catch {}
}
function clearChannelCache(handle) {
  // Clear old ID-based caches too
  try {
    localStorage.removeItem(cacheKey(handle));
    localStorage.removeItem('ik_feed_UCjZ83CJKuU03jmeeKRP4wiw');
    localStorage.removeItem('ik_feed_UCh8NcWbRDzwszrgvZ6nmVcw');
    localStorage.removeItem('ik_videos_v2');
    localStorage.removeItem('ik_videos_cache');
  } catch {}
}

// ── Step 1: resolve handle → uploads playlist ID ─────────────────────────
async function fetchUploadsPlaylistId(handle) {
  const url = `${_API.base}/channels?part=contentDetails&forHandle=${encodeURIComponent(handle)}&key=${_API.key}`;
  const res = await fetch(url);
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.error?.message || `HTTP ${res.status}`);
  }
  const data = await res.json();
  const uploadsId = data.items?.[0]?.contentDetails?.relatedPlaylists?.uploads;
  if (!uploadsId) throw new Error(`Could not resolve uploads playlist for @${handle}`);
  return uploadsId;
}

// ── Step 2: playlistItems.list → all videos ──────────────────────────────
async function fetchPlaylistVideos(playlistId, onProgress) {
  const BASE = `${_API.base}/playlistItems`;
  let videos = [];
  let pageToken = '';
  let pages = 0;

  do {
    const url = `${BASE}?part=snippet&playlistId=${playlistId}&maxResults=50&key=${_API.key}${pageToken ? '&pageToken=' + pageToken : ''}`;
    const res = await fetch(url);
    if (!res.ok) {
      const err = await res.json().catch(() => ({}));
      throw new Error(err.error?.message || `HTTP ${res.status}`);
    }
    const data = await res.json();
    pageToken = data.nextPageToken || '';
    pages++;

    const batch = (data.items || [])
      .filter(item => {
        const t = item.snippet?.title || '';
        return t !== 'Private video' && t !== 'Deleted video';
      })
      .map(item => {
        const s = item.snippet;
        const videoId = s.resourceId?.videoId || '';
        const thumbs = s.thumbnails || {};
        const thumb = (thumbs.maxres || thumbs.high || thumbs.medium || thumbs.default || {}).url
          || `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
        return {
          id: videoId,
          title: s.title || '',
          date: s.publishedAt || '',
          description: s.description || '',
          thumb,
          category: classifyVideo(s.title, s.description || ''),
        };
      });

    videos = videos.concat(batch);
    if (onProgress) onProgress(videos.length);
  } while (pageToken && pages < 40);

  return videos;
}

// ── Combined: handle → videos (with cache) ─────────────────────────────
async function fetchChannelVideos(handle, onProgress) {
  const cached = getCache(handle);
  if (cached) { if (onProgress) onProgress(cached.videos.length); return cached; }

  const playlistId = await fetchUploadsPlaylistId(handle);
  const videos = await fetchPlaylistVideos(playlistId, onProgress);
  setCache(handle, videos);
  return { videos };
}

// ── Classifier ────────────────────────────────────────────────────────────
const CATEGORIES = ['All', 'Calvinism', 'Original Sin', 'Atonement', 'Molinism', 'Dynamic Omniscience', 'Debates & Responses', 'Church History', 'Theology'];

function classifyVideo(title, description) {
  const t = (title + ' ' + (description || '')).toLowerCase();
  if (/calvin|tulip|predestination|reformed|total depravity|irresistible grace|limited atonement|perseverance of/.test(t)) return 'Calvinism';
  if (/original sin|inherited sin|adam.s sin|federal head/.test(t)) return 'Original Sin';
  if (/atonement|penal sub|ransom|propitiation|expiation/.test(t)) return 'Atonement';
  if (/molinis|middle knowledge|counterfactual|luis de molina/.test(t)) return 'Molinism';
  if (/omniscience|open theism|foreknow|dynamic omniscience|greg boyd|open view/.test(t)) return 'Dynamic Omniscience';
  if (/\bdebate\b|respond|reply|refut| vs |against|rebuttal|james white|response to/.test(t)) return 'Debates & Responses';
  if (/church history|church father|origen|augustine|early church|patristic|irenaeus|tertullian|clement|justin martyr|chrysostom/.test(t)) return 'Church History';
  return 'Theology';
}

// ── Status bar ────────────────────────────────────────────────────────────
function StatusBar({ count, loading, progress, error, onRefresh }) {
  if (error) return (
    <div className="status-bar status-bar--error">
      <span>⚠ {error}</span>
      <button onClick={onRefresh}>Retry</button>
    </div>
  );
  if (loading && count === 0) return (
    <div className="status-bar status-bar--loading">
      <div className="loading-spinner" style={{width:'16px',height:'16px'}}></div>
      <span>{progress > 0 ? `Loading… ${progress} videos fetched` : 'Connecting to YouTube…'}</span>
    </div>
  );
  return (
    <div className="status-bar status-bar--ok">
      <span>✓ {count} videos loaded from YouTube</span>
      <button onClick={onRefresh}>↺ Refresh</button>
    </div>
  );
}

// ── Video section (reusable) ──────────────────────────────────────────────
function VideoSection({ handle, label, eyebrow, onVideoClick, perPage = 12 }) {
  const [videos, setVideos] = useState([]);
  const [loading, setLoading] = useState(true);
  const [progress, setProgress] = useState(0);
  const [error, setError] = useState('');
  const [activeCategory, setActiveCategory] = useState('All');
  const [searchQuery, setSearchQuery] = useState('');
  const [page, setPage] = useState(1);

  function load() {
    if (!handle) { setLoading(false); return; }
    setLoading(true);
    setError('');
    setProgress(0);
    fetchChannelVideos(handle, n => setProgress(n))
      .then(({ videos: vids }) => { setVideos(vids); setLoading(false); })
      .catch(err => { setError(err.message); setLoading(false); });
  }

  useEffect(() => { load(); }, [handle]);
  useScrollReveal(label + activeCategory + page + videos.length);
  useEffect(() => { setPage(1); }, [activeCategory, searchQuery]);

  const counts = {};
  videos.forEach(v => { counts[v.category] = (counts[v.category] || 0) + 1; });

  const filtered = videos.filter(v => {
    const matchCat = activeCategory === 'All' || v.category === activeCategory;
    const matchSearch = !searchQuery || v.title.toLowerCase().includes(searchQuery.toLowerCase());
    return matchCat && matchSearch;
  });
  const paginated = filtered.slice(0, page * perPage);
  const hasMore = paginated.length < filtered.length;

  return (
    <section className="video-section">
      <div className="video-section-header">
        <div className="section-inner">
          <p className="section-eyebrow">{eyebrow}</p>
          <h2 className="section-title">{label} <span className="accent">Videos</span></h2>
        </div>
      </div>

      <div className="watch-controls">
        <StatusBar count={videos.length} loading={loading} progress={progress} error={error}
          onRefresh={() => { clearChannelCache(handle); load(); }} />

        {videos.length > 0 && (
          <>
            <div className="search-bar">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
              <input type="text" placeholder={`Search ${videos.length} videos…`} value={searchQuery}
                onChange={e => setSearchQuery(e.target.value)} />
              {searchQuery && <button style={{color:'var(--text-faint)',fontSize:'16px'}} onClick={() => setSearchQuery('')}>✕</button>}
            </div>
            <div className="category-tabs">
              <button className={`cat-tab${activeCategory === 'All' ? ' active' : ''}`} onClick={() => setActiveCategory('All')}>
                All ({videos.length})
              </button>
              {CATEGORIES.filter(c => c !== 'All').map(c => counts[c] ? (
                <button key={c} className={`cat-tab${activeCategory === c ? ' active' : ''}`} onClick={() => setActiveCategory(c)}>
                  {c} ({counts[c]})
                </button>
              ) : null)}
            </div>
          </>
        )}
      </div>

      {loading && videos.length === 0 && (
        <div className="loading-state">
          <div className="loading-spinner"></div>
          <p>{progress > 0 ? `${progress} videos loaded…` : 'Fetching from YouTube…'}</p>
        </div>
      )}

      <div className="videos-grid">
        {paginated.map(v => <VideoCard key={v.id} video={v} onClick={onVideoClick} />)}
        {!loading && filtered.length === 0 && videos.length > 0 && (
          <div className="empty-state">
            <p>No videos found{searchQuery ? ` for "${searchQuery}"` : ` in ${activeCategory}`}</p>
          </div>
        )}
      </div>

      {hasMore && !loading && (
        <div className="load-more-wrap">
          <button className="ik-btn-outline" onClick={() => setPage(p => p + 1)}>
            Load More — {filtered.length - paginated.length} remaining
          </button>
        </div>
      )}
    </section>
  );
}

// ── Watch Page ─────────────────────────────────────────────────────────────
function WatchPage({ onVideoClick }) {
  return (
    <main className="watch-page">
      <div className="page-header">
        <div className="page-header-inner">
          <p className="section-eyebrow">Content Library</p>
          <h1 className="page-title">Watch <span className="accent">Videos</span></h1>
          <p className="page-subtitle">In-depth theology, apologetics, and church history from Warren McGrew.</p>
        </div>
      </div>

      {/* Section 1: Main Channel — resolved via @IdolKiller handle */}
      <VideoSection
        handle={_API.channels.main.handle}
        label="Idol Killer"
        eyebrow="Main Channel · @IdolKiller"
        onVideoClick={onVideoClick}
      />

      {/* Divider */}
      <div className="channel-divider">
        <div className="channel-divider-line"></div>
        <span>Also on YouTube</span>
        <div className="channel-divider-line"></div>
      </div>

      {/* Section 2: Idol Killer 2 — resolved via @IdolKiller2 handle */}
      <VideoSection
        handle={_API.channels.music.handle}
        label="Idol Killer 2"
        eyebrow="Music & Short-Form · @IdolKiller2"
        onVideoClick={onVideoClick}
      />

      <Footer />
    </main>
  );
}

// Expose for home page featured section
async function fetchRecentVideos(n) {
  try {
    const { videos } = await fetchChannelVideos(_API.channels.main.handle, null);
    return videos.slice(0, n);
  } catch { return []; }
}

Object.assign(window, { WatchPage, fetchRecentVideos });
