import api, { API_URL } from './api'; export type YouTubeVideo = { video_id: string; title: string; thumbnail_url: string; views_text?: string; views?: number; published_text?: string; published_date?: string; // YYYY-MM-DD }; export type YouTubeChannelPayload = { channel: string; channel_url: string; subscribers_text?: string; subscribers?: number; videos: YouTubeVideo[]; }; // Simple in-memory cache for YouTube payload (per-session) let ytMemCache: { payload: YouTubeChannelPayload | null; fetchedAt: number } | null = null; const YT_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour export const getCachedYouTube = async (): Promise => { const now = Date.now(); if (ytMemCache && now - ytMemCache.fetchedAt < YT_CACHE_TTL_MS) { return sortByPublishedDate(ytMemCache.payload) as YouTubeChannelPayload | null; } try { const res = await api.get('/youtube/videos'); const primary = res?.data as YouTubeChannelPayload | undefined; const hasVideos = Array.isArray(primary?.videos) && (primary!.videos.length > 0); // If backend responded with 204 or empty payload, fall back to the static cached JSON let out: YouTubeChannelPayload | null = null; if (res.status === 204 || !primary || !hasVideos) { out = await fetchStaticYouTubeCache(); } else { out = primary || null; } if (out) { ytMemCache = { payload: out, fetchedAt: now }; } return sortByPublishedDate(out) as YouTubeChannelPayload | null; } catch { // Fallback: fetch static cached JSON directly from backend /cache path to avoid stressing external API const out = await fetchStaticYouTubeCache(); if (out) { ytMemCache = { payload: out, fetchedAt: now }; } return out; } }; // Helper: fetch static cached JSON from /cache/prefetch const fetchStaticYouTubeCache = async (): Promise => { try { const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin; const url = `${origin}/cache/prefetch/youtube_channel.json`; const resp = await fetch(url, { cache: 'force-cache' }); if (!resp.ok) return null; const data = (await resp.json()) as YouTubeChannelPayload; return sortByPublishedDate(data); } catch { return null; } }; // Helper: ensure videos are sorted by most recent published_date const sortByPublishedDate = (payload: YouTubeChannelPayload | null | undefined): YouTubeChannelPayload | null => { if (!payload || !Array.isArray(payload.videos)) return payload ?? null; const copy: YouTubeChannelPayload = { ...payload, videos: [...payload.videos] }; copy.videos.sort((a, b) => { const ta = Date.parse(a.published_date || '') || 0; const tb = Date.parse(b.published_date || '') || 0; return tb - ta; // newest first }); return copy; };