"use client";

import useSWR from "swr";
import { useEffect, useRef } from "react";
import { RoomStatus } from "@/types";

async function fetcher(url: string) {
  const r = await fetch(url);
  if (!r.ok) {
    const err = new Error(r.status === 404 ? "NOT_FOUND" : "FETCH_ERROR");
    throw err;
  }
  return r.json();
}

export function useRoomPolling(roomId: string | undefined) {
  const { data, error, isLoading, mutate } = useSWR<RoomStatus>(
    roomId ? `/api/room/${roomId}` : null,
    fetcher,
    {
      revalidateOnFocus: true,
      shouldRetryOnError: (err) => err?.message !== "NOT_FOUND",
    },
  );

  const fallbackRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const notFound = error?.message === "NOT_FOUND";

  useEffect(() => {
    if (!roomId) return;
    const es = new EventSource(`/api/room/${roomId}/events`);

    es.onmessage = (e) => {
      try {
        const parsed = JSON.parse(e.data);
        if (parsed.roomId) {
          mutate(parsed, { revalidate: false });
        }
      } catch {
        /* malformed message */
      }
    };

    es.onerror = () => {
      if (!fallbackRef.current) {
        fallbackRef.current = setInterval(() => mutate(), 2000);
      }
    };

    es.onopen = () => {
      if (fallbackRef.current) {
        clearInterval(fallbackRef.current);
        fallbackRef.current = null;
      }
    };

    return () => {
      es.close();
      if (fallbackRef.current) {
        clearInterval(fallbackRef.current);
        fallbackRef.current = null;
      }
    };
  }, [roomId, mutate]);

  return {
    userCount: data?.userCount ?? 0,
    match: data?.match ?? null,
    matchType: data?.matchType ?? null,
    matchLikes: data?.matchLikes ?? 0,
    runnerUps: data?.runnerUps ?? [],
    likeCounts: data?.likeCounts ?? {},
    swipeCounts: data?.swipeCounts ?? {},
    restaurants: data?.restaurants ?? [],
    creatorId: data?.creatorId ?? "",
    locked: data?.locked ?? false,
    users: data?.users ?? [],
    userProfiles: data?.userProfiles ?? {},
    scene: data?.scene ?? "eat" as const,
    notFound,
    isLoading,
    error,
    mutate,
  };
}
