import "server-only";
import { db } from "./db";

/** Parse any YouTube URL form into an embeddable URL, or null if not YouTube. */
export function youtubeEmbedUrl(raw: string | null | undefined): string | null {
  if (!raw) return null;
  try {
    const u = new URL(raw);
    let id: string | null = null;
    if (/(^|\.)youtu\.be$/.test(u.hostname)) id = u.pathname.slice(1).split("/")[0];
    else if (/(^|\.)youtube\.com$/.test(u.hostname)) {
      if (u.pathname === "/watch") id = u.searchParams.get("v");
      else if (u.pathname.startsWith("/live/") || u.pathname.startsWith("/embed/")) id = u.pathname.split("/")[2];
    }
    if (!id) return null;
    return `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&rel=0`;
  } catch {
    return null;
  }
}

export type LiveFeedUpdate = {
  id: string;
  type: string;
  title: string;
  body: string | null;
  quote: string | null;
  statValue: string | null;
  statLabel: string | null;
  link: string | null;
  tags: string[];
  featured: boolean;
  speaker: { name: string; photoUrl: string | null; designation: string | null } | null;
  session: { id: string; title: string } | null;
  at: string; // ISO
};

export type LiveSessionInfo = {
  id: string;
  title: string;
  abstract: string | null;
  startAt: string;
  endAt: string;
  room: string | null;
  speakers: { name: string; photoUrl: string | null; designation: string | null; organization: string | null; speakerType: string }[];
};

/** Everything the live screen needs — served initially by the page and re-polled via /api/live/[id]/feed. */
export async function getLiveFeed(conferenceId: string) {
  const now = new Date();
  const [conf, updates, questions, sessions, attending, checkedIn] = await Promise.all([
    db.conference.findUnique({
      where: { id: conferenceId },
      select: { id: true, name: true, slug: true, status: true, type: true, streamUrl: true, hashtags: true, primaryColor: true, startAt: true, endAt: true, logoUrl: true },
    }),
    db.liveUpdate.findMany({
      where: { conferenceId },
      orderBy: { createdAt: "desc" },
      take: 120,
      include: { speaker: { select: { name: true, photoUrl: true, designation: true } }, session: { select: { id: true, title: true } } },
    }),
    db.liveQuestion.findMany({ where: { conferenceId, status: "APPROVED" }, orderBy: { createdAt: "desc" }, take: 20 }),
    db.session.findMany({
      where: { conferenceId },
      orderBy: { startAt: "asc" },
      include: { room: true, speakers: { include: { speaker: true } } },
    }),
    db.registration.count({ where: { conferenceId, status: "CONFIRMED" } }),
    db.checkIn.count({ where: { type: "CONFERENCE", registration: { conferenceId } } }),
  ]);
  if (!conf) return null;

  const toInfo = (s: (typeof sessions)[number]): LiveSessionInfo => ({
    id: s.id,
    title: s.title,
    abstract: s.abstract,
    startAt: s.startAt.toISOString(),
    endAt: s.endAt.toISOString(),
    room: s.room?.name ?? null,
    speakers: s.speakers.map(({ speaker }) => ({
      name: speaker.name,
      photoUrl: speaker.photoUrl,
      designation: speaker.designation,
      organization: speaker.organization,
      speakerType: speaker.speakerType,
    })),
  });
  const current = sessions.find((s) => s.startAt <= now && s.endAt > now && s.type !== "BREAK");
  const next = sessions.find((s) => s.startAt > now && s.type !== "BREAK");

  return {
    conference: {
      id: conf.id,
      name: conf.name,
      slug: conf.slug,
      status: conf.status,
      type: conf.type,
      embedUrl: youtubeEmbedUrl(conf.streamUrl),
      streamUrl: conf.streamUrl,
      hashtags: (conf.hashtags ?? "").split(",").map((h) => h.trim()).filter(Boolean),
      primaryColor: conf.primaryColor,
      startAt: conf.startAt.toISOString(),
      endAt: conf.endAt.toISOString(),
    },
    updates: updates.map((u): LiveFeedUpdate => ({
      id: u.id,
      type: u.type,
      title: u.title,
      body: u.body,
      quote: u.quote,
      statValue: u.statValue,
      statLabel: u.statLabel,
      link: u.link,
      tags: (u.tags ?? "").split(",").map((t) => t.trim()).filter(Boolean),
      featured: u.featured,
      speaker: u.speaker,
      session: u.session,
      at: u.createdAt.toISOString(),
    })),
    questions: questions.map((q) => ({ id: q.id, name: q.name, question: q.question, at: q.createdAt.toISOString() })),
    currentSession: current ? toInfo(current) : null,
    nextSession: next ? toInfo(next) : null,
    counts: { attending, checkedIn },
    serverTime: now.toISOString(),
  };
}

export type LiveFeed = NonNullable<Awaited<ReturnType<typeof getLiveFeed>>>;
