import { createFileRoute, Link } from "@tanstack/react-router";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Radio, Mic, Calendar, Share2, Play, RefreshCw, AlertTriangle, Bell, MessageSquare } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { openGatavaseChat } from "@/components/gatavase-chat";
import {
  listSchedule,
  listApprovedQuestions,
  listEpisodes,
  submitQuestion,
  subscribeGoLive,
  liveStatus,
} from "@/lib/podcast.functions";

const TITLE = "Live Podcast — Gatavase Corporation";
const DESCRIPTION =
  "Watch the Gatavase live podcast: weekly streams on African technology, AI, engineering and entrepreneurship, broadcast from Kampala and Doha, with live Q&A and go-live alerts.";

export const Route = createFileRoute("/live-podcast")({
  head: () => ({
    meta: [
      { title: TITLE },
      { name: "description", content: DESCRIPTION },
      { property: "og:title", content: TITLE },
      { property: "og:description", content: DESCRIPTION },
      { property: "og:type", content: "website" },
      { property: "og:url", content: "/live-podcast" },
      { name: "twitter:card", content: "summary_large_image" },
    ],
    links: [{ rel: "canonical", href: "/live-podcast" }],
  }),
  component: LivePodcastPage,
});

const CHANNELS = [
  { name: "YouTube Live", handle: "@gatavase" },
  { name: "X / Twitter Spaces", handle: "@gatavase" },
  { name: "Gatavase Radio", handle: "gatavase.com/gatavase-radio" },
];

const CHANNEL_ID = "UC_x5XG1OV2P6uZZ5FSM9Ttw";

/** Ordered fallback sources — the player steps down the list when one fails. */
const SOURCES = [
  { label: "Primary CDN", url: `https://www.youtube.com/embed/live_stream?channel=${CHANNEL_ID}` },
  {
    label: "Backup (privacy CDN)",
    url: `https://www.youtube-nocookie.com/embed/live_stream?channel=${CHANNEL_ID}`,
  },
];

const BITRATES = [
  { label: "Auto", vq: "" },
  { label: "1080p", vq: "hd1080" },
  { label: "720p", vq: "hd720" },
  { label: "480p (data saver)", vq: "large" },
  { label: "360p (low bandwidth)", vq: "small" },
];

const STALL_TIMEOUT_MS = 12000;

function LivePodcastPage() {
  const scheduleQuery = useQuery({ queryKey: ["podcast-schedule"], queryFn: () => listSchedule() });
  const episodesQuery = useQuery({ queryKey: ["podcast-episodes"], queryFn: () => listEpisodes() });
  const questionsQuery = useQuery({
    queryKey: ["podcast-questions"],
    queryFn: () => listApprovedQuestions(),
    refetchInterval: 30000,
  });
  const status = useQuery({
    queryKey: ["podcast-live-status"],
    queryFn: () => liveStatus(),
    refetchInterval: 60000,
  });

  const schedule = scheduleQuery.data ?? [];
  const episodes = (episodesQuery.data ?? []).slice(0, 3);
  const isLive = status.data?.live === true;

  useBrowserGoLiveAlert(isLive, status.data && "title" in status.data ? status.data.title : "");

  return (
    <>
      <section className="hero-surface border-b border-border">
        <div className="mx-auto max-w-6xl px-5 py-20 md:py-24">
          <p className="inline-flex items-center gap-2 rounded-full border border-primary/40 bg-primary/10 px-3.5 py-1.5 text-xs font-medium text-primary">
            <span className="live-dot" aria-hidden="true" />{" "}
            {isLive ? "On air now" : "Live streaming"}
          </p>
          <h1 className="mt-6 max-w-3xl text-4xl font-bold md:text-5xl">
            The Gatavase <span className="text-gradient">Live Podcast</span>
          </h1>
          <p className="mt-5 max-w-2xl text-lg leading-relaxed text-muted-foreground">
            Conversations on African technology, AI engineering, and building companies across
            Kampala and Doha — streamed live, every week.
          </p>
          <div className="mt-8 flex flex-wrap gap-3">
            <Button asChild size="lg" variant="outline">
              <Link to="/episodes">Episode archive</Link>
            </Button>
            <Button size="lg" variant="outline" onClick={openGatavaseChat}>
              Ask Gatavase AI
            </Button>
          </div>
        </div>
      </section>

      <section className="mx-auto max-w-6xl px-5 py-14">
        <div className="grid gap-8 lg:grid-cols-[1.4fr_0.6fr]">
          <div className="space-y-6">
            <StreamPlayer />
            <QAPanel questions={questionsQuery.data ?? []} onSent={() => questionsQuery.refetch()} />
          </div>

          <aside className="space-y-5">
            <GoLiveAlerts />

            <div className="panel p-6">
              <h2 className="flex items-center gap-2 text-base font-semibold">
                <Calendar className="size-4 text-primary" /> Upcoming shows
              </h2>
              <ul className="mt-4 space-y-4">
                {schedule.length === 0 && (
                  <li className="text-sm text-muted-foreground">Schedule coming soon.</li>
                )}
                {schedule.map((s) => (
                  <li key={s.id}>
                    <p className="font-mono text-xs tracking-wide text-primary uppercase">
                      {new Date(s.starts_at).toLocaleString(undefined, {
                        weekday: "long",
                        hour: "2-digit",
                        minute: "2-digit",
                      })}
                      {s.status === "live" ? " · LIVE" : ""}
                    </p>
                    <p className="mt-1 text-sm font-medium">{s.title}</p>
                    <p className="text-sm text-muted-foreground">{s.topic}</p>
                  </li>
                ))}
              </ul>
            </div>

            <div className="panel p-6">
              <h2 className="flex items-center gap-2 text-base font-semibold">
                <Share2 className="size-4 text-primary" /> Where to watch
              </h2>
              <ul className="mt-4 space-y-2 text-sm text-muted-foreground">
                {CHANNELS.map((c) => (
                  <li key={c.name}>
                    <span className="text-foreground">{c.name}</span> — {c.handle}
                  </li>
                ))}
              </ul>
            </div>

            {episodes.length > 0 && (
              <div className="panel p-6">
                <h2 className="text-base font-semibold">Latest episodes</h2>
                <ul className="mt-4 space-y-3 text-sm">
                  {episodes.map((e) => (
                    <li key={e.id}>
                      <Link
                        to="/episodes/$slug"
                        params={{ slug: e.slug }}
                        className="text-foreground hover:text-primary"
                      >
                        {e.title}
                      </Link>
                      <p className="text-xs text-muted-foreground">{e.duration_minutes} min</p>
                    </li>
                  ))}
                </ul>
                <Button asChild variant="outline" size="sm" className="mt-4">
                  <Link to="/episodes">Browse the archive</Link>
                </Button>
              </div>
            )}
          </aside>
        </div>
      </section>

      <section className="border-t border-border py-16">
        <div className="mx-auto max-w-6xl px-5">
          <h2 className="text-2xl font-bold md:text-3xl">Be on the show</h2>
          <p className="mt-3 max-w-2xl text-sm leading-relaxed text-muted-foreground">
            Founders, engineers, artists and community builders — pitch a topic and join a live
            episode from our Kampala studio or remotely.
          </p>
          <div className="mt-7 flex flex-wrap gap-3">
            <Button asChild size="lg">
              <Link to="/contact">
                <Mic className="size-4" /> Apply as a guest
              </Link>
            </Button>
            <Button asChild size="lg" variant="outline">
              <Link to="/gatavase-podcast">Podcast archive</Link>
            </Button>
          </div>
        </div>
      </section>
    </>
  );
}

/* ---------------- player with retry + bitrate fallback ---------------- */

function StreamPlayer() {
  const [playing, setPlaying] = useState(false);
  const [sourceIndex, setSourceIndex] = useState(0);
  const [quality, setQuality] = useState(0);
  const [attempt, setAttempt] = useState(0);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const stallTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const source = SOURCES[Math.min(sourceIndex, SOURCES.length - 1)]!;
  const src = useMemo(() => {
    const vq = BITRATES[quality]!.vq;
    return `${source.url}&autoplay=1&rel=0${vq ? `&vq=${vq}` : ""}&_r=${attempt}`;
  }, [source.url, quality, attempt]);

  const clearStall = () => {
    if (stallTimer.current) clearTimeout(stallTimer.current);
    stallTimer.current = null;
  };

  const arm = useCallback(() => {
    clearStall();
    setLoading(true);
    setError(null);
    stallTimer.current = setTimeout(() => {
      setLoading(false);
      setError(
        "The stream did not start in time. This is usually a network or bandwidth issue — retry, lower the quality, or switch to the backup source.",
      );
    }, STALL_TIMEOUT_MS);
  }, []);

  useEffect(() => {
    if (playing) arm();
    return clearStall;
  }, [playing, src, arm]);

  function retry() {
    setAttempt((a) => a + 1);
    setPlaying(true);
  }

  function fallback() {
    setSourceIndex((i) => (i + 1) % SOURCES.length);
    setAttempt((a) => a + 1);
    setPlaying(true);
    toast.info("Switching to the backup stream source…");
  }

  function lowerQuality() {
    setQuality((q) => Math.min(q + 1, BITRATES.length - 1));
    setAttempt((a) => a + 1);
  }

  return (
    <div className="panel overflow-hidden">
      <div className="relative aspect-video w-full bg-black">
        {playing ? (
          <>
            <iframe
              key={src}
              src={src}
              title="Gatavase live podcast stream"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; picture-in-picture"
              allowFullScreen
              className="size-full"
              onLoad={() => {
                clearStall();
                setLoading(false);
              }}
              onError={() => {
                clearStall();
                setLoading(false);
                setError("The player could not load. Try again or switch source.");
              }}
            />
            {loading && (
              <div className="pointer-events-none absolute inset-0 grid place-items-center bg-black/50 text-sm text-muted-foreground">
                Connecting to {source.label}…
              </div>
            )}
          </>
        ) : (
          <button
            type="button"
            onClick={() => setPlaying(true)}
            className="grid size-full place-items-center bg-[radial-gradient(circle_at_50%_40%,color-mix(in_oklab,var(--primary)_28%,transparent),transparent_65%)]"
          >
            <span className="flex flex-col items-center gap-3">
              <span className="grid size-16 place-items-center rounded-full border border-primary/50 bg-primary/15 text-primary">
                <Play className="size-6" />
              </span>
              <span className="text-sm text-muted-foreground">Tap to load the live player</span>
            </span>
          </button>
        )}
      </div>

      {error && (
        <div className="flex flex-wrap items-center gap-3 border-t border-destructive/40 bg-destructive/10 px-5 py-3 text-sm">
          <AlertTriangle className="size-4 shrink-0 text-destructive" />
          <span className="flex-1 min-w-[12rem] text-muted-foreground">{error}</span>
          <Button size="sm" variant="outline" onClick={retry}>
            <RefreshCw className="size-3.5" /> Retry
          </Button>
          <Button size="sm" variant="outline" onClick={lowerQuality}>
            Lower quality
          </Button>
          <Button size="sm" onClick={fallback}>
            Backup source
          </Button>
        </div>
      )}

      <div className="flex flex-wrap items-center justify-between gap-3 px-5 py-4">
        <p className="flex items-center gap-2 text-sm font-medium">
          <Radio className="size-4 text-primary" /> Gatavase Studio · Kampala
        </p>
        <div className="flex items-center gap-2">
          <Label htmlFor="bitrate" className="text-xs text-muted-foreground">
            Quality
          </Label>
          <select
            id="bitrate"
            value={quality}
            onChange={(e) => {
              setQuality(Number(e.target.value));
              setAttempt((a) => a + 1);
            }}
            className="h-9 rounded-md border border-border bg-background px-2 text-xs"
          >
            {BITRATES.map((b, i) => (
              <option key={b.label} value={i}>
                {b.label}
              </option>
            ))}
          </select>
          <span className="text-xs text-muted-foreground">· {source.label}</span>
        </div>
      </div>
    </div>
  );
}

/* ---------------- go-live alerts ---------------- */

function useBrowserGoLiveAlert(isLive: boolean, title: string) {
  const notified = useRef(false);
  useEffect(() => {
    if (!isLive || notified.current) return;
    if (typeof window === "undefined" || !("Notification" in window)) return;
    if (localStorage.getItem("gatavase-live-push") !== "on") return;
    if (Notification.permission !== "granted") return;
    notified.current = true;
    new Notification("Gatavase Live Podcast is on air", {
      body: title || "The stream has just started. Tap to watch.",
      icon: "/favicon.png",
    });
  }, [isLive, title]);
}

function GoLiveAlerts() {
  const subscribe = useServerFn(subscribeGoLive);
  const [email, setEmail] = useState("");
  const [busy, setBusy] = useState(false);
  const [push, setPush] = useState(false);

  useEffect(() => {
    setPush(typeof window !== "undefined" && localStorage.getItem("gatavase-live-push") === "on");
  }, []);

  async function enablePush() {
    if (typeof window === "undefined" || !("Notification" in window)) {
      toast.error("This browser does not support notifications.");
      return;
    }
    const permission = await Notification.requestPermission();
    if (permission !== "granted") {
      toast.error("Notifications were blocked in your browser settings.");
      return;
    }
    localStorage.setItem("gatavase-live-push", "on");
    setPush(true);
    new Notification("Gatavase Live alerts enabled", {
      body: "We'll notify you the moment a stream starts.",
      icon: "/favicon.png",
    });
  }

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    try {
      await subscribe({ data: { email, browserPush: push } });
      toast.success("You're on the list — we'll email you when we go live.");
      setEmail("");
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not save your alert.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="panel p-6">
      <h2 className="flex items-center gap-2 text-base font-semibold">
        <Bell className="size-4 text-primary" /> Get go-live alerts
      </h2>
      <p className="mt-2 text-sm text-muted-foreground">
        Email plus optional browser notifications the moment a stream starts.
      </p>
      <form onSubmit={onSubmit} className="mt-4 space-y-3">
        <Input
          type="email"
          required
          placeholder="you@company.com"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <Button type="submit" className="w-full" disabled={busy}>
          {busy ? "Saving…" : "Notify me by email"}
        </Button>
      </form>
      <Button
        variant="outline"
        size="sm"
        className="mt-3 w-full"
        onClick={enablePush}
        disabled={push}
      >
        {push ? "Browser alerts enabled" : "Enable browser notifications"}
      </Button>
    </div>
  );
}

/* ---------------- live Q&A ---------------- */

function QAPanel({
  questions,
  onSent,
}: {
  questions: { id: string; display_name: string; question: string; answer: string | null }[];
  onSent: () => void;
}) {
  const send = useServerFn(submitQuestion);
  const [displayName, setDisplayName] = useState("");
  const [question, setQuestion] = useState("");
  const [website, setWebsite] = useState("");
  const [busy, setBusy] = useState(false);

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    try {
      await send({ data: { displayName, question, website } });
      toast.success("Question sent to the studio — it appears here once a host approves it.");
      setQuestion("");
      onSent();
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not send your question.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="panel p-6">
      <h2 className="flex items-center gap-2 text-base font-semibold">
        <MessageSquare className="size-4 text-primary" /> Live chat & Q&amp;A
      </h2>
      <form onSubmit={onSubmit} className="mt-4 grid gap-3 sm:grid-cols-[0.8fr_1.6fr_auto]">
        <Input
          placeholder="Your name"
          value={displayName}
          onChange={(e) => setDisplayName(e.target.value)}
          required
          minLength={2}
        />
        <Textarea
          placeholder="Ask the hosts a question…"
          value={question}
          onChange={(e) => setQuestion(e.target.value)}
          required
          minLength={5}
          rows={1}
          className="min-h-10"
        />
        <input
          type="text"
          tabIndex={-1}
          autoComplete="off"
          aria-hidden="true"
          value={website}
          onChange={(e) => setWebsite(e.target.value)}
          className="hidden"
        />
        <Button type="submit" disabled={busy}>
          {busy ? "Sending…" : "Send"}
        </Button>
      </form>

      <ul className="mt-6 max-h-80 space-y-4 overflow-y-auto pr-1">
        {questions.length === 0 && (
          <li className="text-sm text-muted-foreground">
            No questions yet — be the first to ask the hosts.
          </li>
        )}
        {questions.map((q) => (
          <li key={q.id} className="rounded-lg border border-border/70 p-3">
            <p className="text-xs font-medium text-primary">{q.display_name}</p>
            <p className="mt-1 text-sm">{q.question}</p>
            {q.answer && (
              <p className="mt-2 border-l-2 border-primary/50 pl-3 text-sm text-muted-foreground">
                {q.answer}
              </p>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}
