// Curated TV channels + Radio stations + Tube streams.
// Pulled straight from packages/shared/src/curated/* so the on-screen
// labels match production. Stream URLs are real — the prototype now
// embeds the broadcaster's HLS feed where one's available, and falls
// back to YouTube live_stream embeds otherwise.

// ── Helpers ────────────────────────────────────────────────────────
// HLS playback used to be proxied through /api/stream?u=... — that fixed
// CORS but routed every segment through our Cloudflare Worker (= egress
// bandwidth we pay for). A probe of all 6 TV HLS streams confirmed each
// broadcaster's CDN serves `Access-Control-Allow-Origin: *`, so we play
// straight from their origin. Zero server bandwidth.
//
// The function is kept as a seam so we can re-enable proxying for any
// future channel whose CORS turns hostile, without touching tv.jsx.
function proxyHls(url) {
  return url;
}

// ── TV channels ────────────────────────────────────────────────────
// ytId mirrors packages/shared/src/curated/tv-audio.ts.
// hls (where present) is the direct broadcaster HLS manifest — preferred
// over the YouTube embed because the broadcaster CDN is 24/7 reliable and
// doesn't show "Live stream offline" between newsroom blocks.
const TV_CHANNELS = [
  { num: "02", name: "France 24", sub: "English", region: "FR", lang: "en", tag: "WORLD NEWS",
    hue: 220, lowerThird: "BREAKING — Paris summit opens",
    ytId: "UCQfwfsi5VrQ8yKZ-UWmAEFg",
    hls: "https://static.france24.com/live/F24_EN_LO_HLS/live_web.m3u8" },
  { num: "03", name: "DW News",   sub: "Deutsche Welle", region: "DE", lang: "en", tag: "EUROPE",
    hue: 12,  lowerThird: "LIVE — Berlin: parliamentary debate",
    ytId: "UCknLrEdhRCp1aegoMqRaCZg",
    hls: "https://dwamdstream102.akamaized.net/hls/live/2015525/dwstream102/index.m3u8" },
  { num: "04", name: "Al Jazeera", sub: "English", region: "QA", lang: "en", tag: "GLOBAL",
    hue: 38,  lowerThird: "DOHA — Foreign ministers convene",
    ytId: "UCNye-wNBqNL5ZzHSJj3l8Bg" },
  { num: "05", name: "TRT World", sub: "Türkiye", region: "TR", lang: "en", tag: "EURASIA",
    hue: 195, lowerThird: "ISTANBUL — Bosphorus traffic resumes",
    ytId: "UC7fWeaHhqgM4Ry-RMpM2YYw",
    hls: "https://tv-trtworld.medya.trt.com.tr/master.m3u8" },
  { num: "06", name: "NHK World", sub: "Japan",   region: "JP", lang: "en", tag: "ASIA-PACIFIC",
    hue: 0,   lowerThird: "TOKYO — Yen steadies against dollar",
    ytId: "UCSPEjw8F2nQDtmUKPFNF7_A" },
  { num: "07", name: "Sky News",  sub: "UK",      region: "UK", lang: "en", tag: "BRITAIN",
    hue: 215, lowerThird: "WESTMINSTER — Cabinet reshuffle imminent",
    ytId: "UCoMdktPbSTixAyNGwb-UYkQ" },
  { num: "08", name: "ABC News",  sub: "Australia", region: "AU", lang: "en", tag: "PACIFIC",
    hue: 168, lowerThird: "CANBERRA — Senate question time",
    ytId: "UCVgO39Bk5sMo66-6o6Aqb5w" },
  { num: "09", name: "Bloomberg", sub: "Television", region: "US", lang: "en", tag: "MARKETS",
    hue: 28,  lowerThird: "MARKETS — S&P futures up 0.3%",
    ytId: "UCIALMKvObZNtJ6AmdCLP7Lg" },
  { num: "10", name: "TaiwanPlus", sub: "News",    region: "TW", lang: "en", tag: "CROSS-STRAIT",
    hue: 122, lowerThird: "TAIPEI — Semiconductor exports rise",
    ytId: "UCdMEWO4I3yQjsX0LNVcBNCQ" },
  { num: "11", name: "France 24", sub: "Français", region: "FR", lang: "fr", tag: "ACTUALITÉ",
    hue: 220, lowerThird: "EN DIRECT — Élysée: déclaration imminente",
    ytId: "UCCCPCZNChQdGa9EkATeye4g",
    hls: "https://static.france24.com/live/F24_FR_LO_HLS/live_web.m3u8" },
  { num: "12", name: "Franceinfo", sub: "France Télévisions", region: "FR", lang: "fr", tag: "INFO",
    hue: 350, lowerThird: "PARIS — Trafic SNCF perturbé",
    ytId: "UCfkxvN2Z3cjehvP1Z-nqOEw" },
  { num: "13", name: "Euronews",  sub: "Français", region: "EU", lang: "fr", tag: "EUROPE",
    hue: 268, lowerThird: "BRUXELLES — Conseil européen ouvert",
    ytId: "UCW2QcQwYqf6LDMA-rMjicXg" },
  { num: "14", name: "France 24", sub: "Español",  region: "FR", lang: "es", tag: "MUNDO",
    hue: 220, lowerThird: "EN VIVO — Cumbre en París hoy",
    ytId: "UCUdOoVWuWmgo1wByzcsyKDQ",
    hls: "https://static.france24.com/live/F24_ES_LO_HLS/live_web.m3u8" },
  { num: "15", name: "DW Español", sub: "Deutsche Welle", region: "DE", lang: "es", tag: "EUROPA",
    hue: 12,  lowerThird: "BERLÍN — Debate parlamentario",
    ytId: "UCT4Jg0h_-xUSqfQbMmK7vfA",
    hls: "https://dwamdstream104.akamaized.net/hls/live/2015530/dwstream104/index.m3u8" },
  { num: "16", name: "Euronews",  sub: "Español",  region: "EU", lang: "es", tag: "MUNDO",
    hue: 268, lowerThird: "BRUSELAS — Consejo europeo abierto",
    ytId: "UCKgyVCGYflzqLI-ICR1IF6Q" },
  { num: "17", name: "ANN ニュース", sub: "テレビ朝日", region: "JP", lang: "ja", tag: "ニュース",
    hue: 0,   lowerThird: "東京 — 円相場 円高に振れる",
    ytId: "UCGCZAYq5Xxojl_tSXcVJhiQ" },
  { num: "18", name: "日テレNEWS", sub: "Nippon TV 24", region: "JP", lang: "ja", tag: "ライブ",
    hue: 348, lowerThird: "東京 — 政府が緊急会見を開く",
    ytId: "UCJD2Br_xC-3vY4nkJ9YPYDA" },

  // ── added 2026-05-15 — broader 24/7 coverage so up/down lands on
  // something currently live even when half the news channels are
  // between broadcasts. IDs verified against youtube.com/channel/<id>.
  { num: "19", name: "LiveNOW", sub: "from FOX", region: "US", lang: "en", tag: "BREAKING",
    hue: 0,   lowerThird: "LIVE — raw feeds, press conferences, breaking news",
    ytId: "UCT4Zg6XQAghCO04i9rNCevg" },
  { num: "20", name: "ABC News", sub: "Live · USA", region: "US", lang: "en", tag: "AMERICAS",
    hue: 215, lowerThird: "WASHINGTON — White House briefing scheduled",
    ytId: "UCBi2mrWuNuyYy4gbM6fU18Q" },
  { num: "21", name: "CBS News", sub: "USA", region: "US", lang: "en", tag: "USA",
    hue: 195, lowerThird: "NEW YORK — markets open mixed",
    ytId: "UC8p1vwvWtl6T73JiExfWs1g" },
  { num: "22", name: "NBC News NOW", sub: "USA", region: "US", lang: "en", tag: "USA",
    hue: 12,  lowerThird: "BREAKING — top stories of the hour",
    ytId: "UCeY0bbntWzzVIaj2z3QigXg" },
  { num: "23", name: "WION", sub: "World Is One News", region: "IN", lang: "en", tag: "SOUTH ASIA",
    hue: 38,  lowerThird: "NEW DELHI — global news from an Indian lens",
    ytId: "UC_gUM8rL-Lrg6O3adPW9K1g" },
  { num: "24", name: "Reuters", sub: "Global", region: "GL", lang: "en", tag: "WORLD WIRE",
    hue: 268, lowerThird: "WIRE — breaking news from correspondents worldwide",
    ytId: "UChqUTb7kYRX8-EiaN3XFrSQ" },
  { num: "25", name: "Euronews", sub: "English", region: "EU", lang: "en", tag: "EUROPE",
    hue: 268, lowerThird: "BRUSSELS — European parliament in session",
    ytId: "UCSrZ3UV4jOidv8ppoVuvW9Q" },
  { num: "26", name: "Africanews", sub: "English", region: "AF", lang: "en", tag: "AFRICA",
    hue: 122, lowerThird: "ADDIS ABABA — African Union summit update",
    ytId: "UCnTPVj-cKMMl2tjsi9JfNww" },
  { num: "27", name: "SABC News", sub: "South Africa", region: "ZA", lang: "en", tag: "AFRICA",
    hue: 150, lowerThird: "JOHANNESBURG — national news at the top of the hour",
    ytId: "UCb73HnH3sShVe-32Ot-PfBA" },
  { num: "28", name: "Times Now", sub: "India · English", region: "IN", lang: "en", tag: "SOUTH ASIA",
    hue: 350, lowerThird: "MUMBAI — newsroom debate continues",
    ytId: "UC6RJ7-PaXg6TIH2BzZfTV7w" },
  { num: "29", name: "TVE 24h", sub: "Canal 24 horas", region: "ES", lang: "es", tag: "ESPAÑA",
    hue: 28,  lowerThird: "MADRID — informativo continuo en español",
    ytId: "UCYjsHi1eqd9MhKWg_O5acIw" },
  { num: "30", name: "KBS World", sub: "한국어", region: "KR", lang: "ko", tag: "ASIA",
    hue: 320, lowerThird: "서울 — 한국 뉴스 24시간 라이브",
    ytId: "UCwd0BPb_g8DTUgyG6lyXkLg" },
  { num: "31", name: "WSJ Video", sub: "Wall Street Journal", region: "US", lang: "en", tag: "MARKETS",
    hue: 230, lowerThird: "NEW YORK — markets & business explainers",
    ytId: "UCK7tptUDHh-RYDsdxO1-5QQ" },
];

// ── Radio stations ────────────────────────────────────────────────
// Each station is a real public-broadcaster stream from
// packages/shared/src/curated/radio.ts. The `freq` is a fake FM dial
// position invented for the design — the dial UI needs spatial ordering,
// real FM frequencies don't apply to internet streams. The audio plays
// from `streamUrl` (proxied through /api/stream for CORS); `streamFormat`
// is "mp3" / "aac" (native <audio>) or "hls" (needs hls.js).
const RADIO_STATIONS = [
  // English
  { freq:  88.1, name: "BBC World Service", publisher: "BBC", lang: "en", region: "UK/Global", category: "news-talk",
    nowPlaying: "Newsday — global morning briefing",
    streamUrl: "https://stream.live.vc.bbcmedia.co.uk/bbc_world_service",
    streamFormat: "hls" },
  { freq:  89.5, name: "BBC Radio 4", publisher: "BBC", lang: "en", region: "UK", category: "news-talk",
    nowPlaying: "PM — afternoon news magazine",
    streamUrl: "https://stream.live.vc.bbcmedia.co.uk/bbc_radio_fourfm",
    streamFormat: "hls" },
  { freq:  90.7, name: "BBC Radio 5 Live", publisher: "BBC", lang: "en", region: "UK", category: "news-talk",
    nowPlaying: "Drive — sport & breaking news",
    streamUrl: "https://stream.live.vc.bbcmedia.co.uk/bbc_radio_five_live",
    streamFormat: "hls" },
  { freq:  91.9, name: "NHK World Radio", publisher: "NHK", lang: "en", region: "JP/Global", category: "news",
    nowPlaying: "News in English — top of the hour",
    streamUrl: "https://nhkwlive-ojp.akamaized.net/hls/live/2003459/nhkwlive-ojp-bw384/index.m3u8",
    streamFormat: "hls" },
  { freq:  93.3, name: "ABC NewsRadio", publisher: "ABC AU", lang: "en", region: "AU", category: "news",
    nowPlaying: "AM — Australian morning briefing",
    streamUrl: "https://live-radio01.mediahubaustralia.com/PBW/mp3/",
    streamFormat: "mp3" },
  { freq:  94.7, name: "ABC Radio National", publisher: "ABC AU", lang: "en", region: "AU", category: "culture",
    nowPlaying: "Big Ideas — long-form lectures",
    streamUrl: "https://live-radio01.mediahubaustralia.com/2RNW/mp3/",
    streamFormat: "mp3" },
  { freq:  96.1, name: "RNZ National", publisher: "RNZ", lang: "en", region: "NZ", category: "news-talk",
    nowPlaying: "Morning Report — with Corin Dann",
    streamUrl: "https://radionz-ice.streamguys1.com/national.mp3",
    streamFormat: "mp3" },
  { freq:  97.5, name: "DW English", publisher: "Deutsche Welle", lang: "en", region: "DE/Global", category: "news",
    nowPlaying: "World in Progress — features",
    streamUrl: "https://dw-edge1-stream02-cloudfront-eu.akamaized.net/dwa-aac-cv-eng/playlist.m3u8",
    streamFormat: "hls" },

  // Français
  { freq:  99.1, name: "Franceinfo", publisher: "Radio France", lang: "fr", region: "FR", category: "news",
    nowPlaying: "Le 19/20 — info en continu",
    streamUrl: "https://icecast.radiofrance.fr/franceinfo-midfi.mp3",
    streamFormat: "mp3" },
  { freq: 100.5, name: "France Inter", publisher: "Radio France", lang: "fr", region: "FR", category: "news-talk",
    nowPlaying: "Le 7/9 — Léa Salamé",
    streamUrl: "https://icecast.radiofrance.fr/franceinter-midfi.mp3",
    streamFormat: "mp3" },
  { freq: 101.9, name: "France Culture", publisher: "Radio France", lang: "fr", region: "FR", category: "culture",
    nowPlaying: "Les Matins — entretien",
    streamUrl: "https://icecast.radiofrance.fr/franceculture-midfi.mp3",
    streamFormat: "mp3" },

  // Español
  { freq: 103.3, name: "RNE Radio 5", publisher: "RTVE", lang: "es", region: "ES", category: "news",
    nowPlaying: "24 horas — todo noticias",
    streamUrl: "https://rtvelivestream.akamaized.net/rtvelive/rne_r5tn_main.m3u8",
    streamFormat: "hls" },
  { freq: 104.7, name: "RNE Radio 1", publisher: "RTVE", lang: "es", region: "ES", category: "news-talk",
    nowPlaying: "Las Mañanas — actualidad",
    streamUrl: "https://rtvelivestream.akamaized.net/rtvelive/rne_r1_main.m3u8",
    streamFormat: "hls" },
  { freq: 106.1, name: "RNE Radio 3", publisher: "RTVE", lang: "es", region: "ES", category: "culture",
    nowPlaying: "Hoy Empieza Todo — música y cultura",
    streamUrl: "https://rtvelivestream.akamaized.net/rtvelive/rne_r3_main.m3u8",
    streamFormat: "hls" },
  { freq: 107.5, name: "DW Español", publisher: "Deutsche Welle", lang: "es", region: "DE/Global", category: "news",
    nowPlaying: "Servicio en español",
    streamUrl: "https://dw-edge1-stream02-cloudfront-eu.akamaized.net/dwa-aac-cv-spa/playlist.m3u8",
    streamFormat: "hls" },

  // 日本語 (NHK domestic streams are geo-locked to Japan; outside JP the
  // CDN refuses and the player surfaces a clean failure. NHK World Radio
  // above is the unrestricted alternative.)
  { freq: 108.0, name: "NHK ラジオ第1", publisher: "NHK", lang: "ja", region: "JP", category: "news-talk",
    nowPlaying: "総合ラジオ — ※日本国外不可",
    streamUrl: "https://nhkradioakr1-i.akamaihd.net/hls/live/512290/1-r1/1-r1-01.m3u8",
    streamFormat: "hls",
    geoLocked: true },
  { freq: 108.3, name: "NHK ラジオ第2", publisher: "NHK", lang: "ja", region: "JP", category: "culture",
    nowPlaying: "教育ラジオ — ※日本国外不可",
    streamUrl: "https://nhkradioakr2-i.akamaihd.net/hls/live/512291/2-r2/2-r2-01.m3u8",
    streamFormat: "hls",
    geoLocked: true },
];

// ── Tube streams ──────────────────────────────────────────────────
// Hand-picked language-learning videos from
// packages/shared/src/curated/learn.ts, played via the standard YouTube
// embed. These are the kind of source channelroam's `/learn` route is
// already wired around — short conversation/listening videos, not pure
// 24/7 news.
const TUBE_STREAMS = [
  { videoId: "YVijbzh48kk", title: "Conversations in British Pubs — Easy English 225",
    channel: "Easy English", lang: "en", level: "intermediate", minutes: 12, hue: 215 },
  { videoId: "TwBYlBjbokU", title: "Everyday Conversations with Strangers",
    channel: "Easy English", lang: "en", level: "intermediate", minutes: 11, hue: 220 },
  { videoId: "y0h3bgc7jZc", title: "Stop making these ADVANCED grammar mistakes",
    channel: "English with Lucy", lang: "en", level: "advanced", minutes: 12, hue: 30 },
  { videoId: "5QE76OkYA4k", title: "Are YOU Mispronouncing These 50 Common English Words?",
    channel: "English with Lucy", lang: "en", level: "intermediate", minutes: 48, hue: 38 },
  { videoId: "N_hNCnh1dxs", title: "My Morning Routine — English Vocabulary Lesson",
    channel: "Speak English with Vanessa", lang: "en", level: "intermediate", minutes: 18, hue: 12 },
  { videoId: "Eps9alVTEHg", title: "SPEAK With Me — English Speaking Practice",
    channel: "Speak English with Vanessa", lang: "en", level: "intermediate", minutes: 13, hue: 350 },
  { videoId: "-ddNt8yWjIY", title: "Listening — The Networking Elevator",
    channel: "EnglishClass101", lang: "en", level: "intermediate", minutes: 12, hue: 195 },
  { videoId: "HI1TBCaSWQQ", title: "Shadowing — Tongue Twisters",
    channel: "linguamarina", lang: "en", level: "advanced", minutes: 17, hue: 268 },
  { videoId: "PUj6DhVKBYM", title: "Duolingo Says ませんか is 'Would You Like To'?",
    channel: "That Japanese Man Yuta", lang: "ja", level: "intermediate", minutes: 10, hue: 0 },
  { videoId: "qZg_MzMCsIY", title: "Still Saying あなた? Try This",
    channel: "That Japanese Man Yuta", lang: "ja", level: "intermediate", minutes: 19, hue: 348 },
  { videoId: "Joe0XXO6pf4", title: "Seika's Favorite Book — Beginner Japanese",
    channel: "Comprehensible Japanese", lang: "ja", level: "beginner", minutes: 15, hue: 122 },
];

// Add display extras (viewers, uptime) so the Tube UI has numbers to render.
const TUBE_STREAMS_DISPLAY = TUBE_STREAMS.map((v, i) => ({
  ...v,
  num: String(i + 1).padStart(2, "0"),
  name: v.channel,
  sub: v.title,
  region: v.lang.toUpperCase(),
  tag: v.level.toUpperCase(),
  viewers: Math.round(4_200 + Math.sin(i * 1.9) * 3_800 + i * 230),
  uptime: `${v.minutes}m`,
}));

Object.assign(window, {
  TV_CHANNELS,
  RADIO_STATIONS,
  TUBE_STREAMS: TUBE_STREAMS_DISPLAY,
  proxyHls,
});
