import { NextResponse } from "next/server";
import { readFile } from "node:fs/promises";
import path from "node:path";
import { config } from "@/lib/config";
import type { BroadcastPayload } from "@/lib/homeBroadcast";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

// Server-side fetch of the hosted broadcast JSON (avoids CORS, lets us cache).
// Contract: this route NEVER 500s — remote fails → bundled fallback; bundled
// missing → minimal inline payload. A fresh/offline install always renders.

const REMOTE_TIMEOUT_MS = 5000;
const CACHE_TTL_MS = 5 * 60 * 1000; // remote content changes rarely

let cached: { ts: number; body: BroadcastPayload } | null = null;

const INLINE_FALLBACK: BroadcastPayload = {
  version: "0",
  broadcast: { show: false },
  welcomeVideo: { show: false, version: 0 },
  links: [],
  latest: null,
  source: "fallback",
};

async function fetchRemote(url: string): Promise<BroadcastPayload | null> {
  const ac = new AbortController();
  const timer = setTimeout(() => ac.abort(), REMOTE_TIMEOUT_MS);
  try {
    const r = await fetch(url, { signal: ac.signal, cache: "no-store" });
    if (!r.ok) return null;
    const json: unknown = await r.json();
    if (!json || typeof json !== "object" || Array.isArray(json)) return null;
    return json as BroadcastPayload;
  } catch {
    return null;
  } finally {
    clearTimeout(timer);
  }
}

async function readBundledFallback(): Promise<BroadcastPayload | null> {
  try {
    const file = path.join(process.cwd(), "public", "broadcast.fallback.json");
    const json: unknown = JSON.parse(await readFile(file, "utf8"));
    if (!json || typeof json !== "object" || Array.isArray(json)) return null;
    return json as BroadcastPayload;
  } catch {
    return null;
  }
}

export async function GET() {
  const now = Date.now();
  if (cached && now - cached.ts < CACHE_TTL_MS) {
    return NextResponse.json(cached.body, { headers: { "X-Broadcast-Cache": "hit" } });
  }

  const remote = await fetchRemote(config.broadcastUrl);
  if (remote) {
    const body: BroadcastPayload = { ...remote, source: "remote" };
    cached = { ts: now, body };
    return NextResponse.json(body, { headers: { "X-Broadcast-Cache": "miss" } });
  }

  // Remote down: serve the last good copy if we have one (stale beats blank).
  if (cached) {
    return NextResponse.json(cached.body, { headers: { "X-Broadcast-Cache": "stale" } });
  }

  const bundled = await readBundledFallback();
  const body: BroadcastPayload = bundled ? { ...bundled, source: "fallback" } : INLINE_FALLBACK;
  return NextResponse.json(body, { headers: { "X-Broadcast-Cache": "fallback" } });
}
