import { useEffect, useRef, useState } from "react";
import { useInfiniteQuery } from "@tanstack/react-query";
import { api, type FeedFilters, type Video } from "../lib/api";
import { toast } from "../lib/toast";
import VideoCard from "./VideoCard";

const PAGE = 60;

export default function Feed({
  filters,
  view,
}: {
  filters: FeedFilters;
  view: "grid" | "list";
}) {
  const [overrides, setOverrides] = useState<Record<string, string>>({});

  const query = useInfiniteQuery({
    queryKey: ["feed", filters],
    queryFn: ({ pageParam }) => api.feed(filters, pageParam as number, PAGE),
    initialPageParam: 0,
    getNextPageParam: (last) => (last.has_more ? last.offset + last.limit : undefined),
  });

  useEffect(() => setOverrides({}), [filters]);

  const sentinel = useRef<HTMLDivElement | null>(null);
  const { hasNextPage, isFetchingNextPage, fetchNextPage } = query;
  useEffect(() => {
    const el = sentinel.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) {
          fetchNextPage();
        }
      },
      { rootMargin: "800px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, [hasNextPage, isFetchingNextPage, fetchNextPage]);

  function onState(id: string, status: string) {
    setOverrides((o) => ({ ...o, [id]: status }));
    api.setState(id, status).catch(() => {});
    if (status === "hidden") {
      toast("Video hidden", { label: "Undo", onClick: () => onState(id, "new") });
    }
  }

  const items: Video[] = (query.data?.pages ?? [])
    .flatMap((p) => p.items)
    .map((v) => (overrides[v.id] ? { ...v, status: overrides[v.id] } : v))
    .filter((v) => {
      const ov = overrides[v.id];
      // In the Hidden view, drop just-unhidden items; elsewhere drop just-hidden ones.
      return filters.show === "hidden" ? ov !== "new" : ov !== "hidden";
    });

  if (query.isLoading) return <div className="p-8 text-muted">Loading feed…</div>;
  if (query.isError) return <div className="p-8 text-muted">Couldn't load the feed.</div>;
  if (items.length === 0)
    return <div className="p-8 text-muted">No videos match these filters.</div>;

  return (
    <div className="p-4">
      {view === "grid" ? (
        <div className="grid gap-x-4 gap-y-6 grid-cols-[repeat(auto-fill,minmax(260px,1fr))]">
          {items.map((v) => (
            <VideoCard key={v.id} video={v} view="grid" onState={onState} />
          ))}
        </div>
      ) : (
        <div className="max-w-4xl mx-auto flex flex-col gap-1">
          {items.map((v) => (
            <VideoCard key={v.id} video={v} view="list" onState={onState} />
          ))}
        </div>
      )}
      <div ref={sentinel} className="h-10" />
      {isFetchingNextPage && (
        <div className="text-center text-muted py-4">Loading more…</div>
      )}
    </div>
  );
}
