"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import Link from "next/link";
import { VideoCard, type VideoCardData } from "@/components/video-card";
import { Chip, EmptyState, FeedSkeleton } from "@/components/ui";
import { useSession } from "@/components/session-provider";
import { api } from "@/lib/api-client";

export function HomeFeed({
  initialItems,
  initialCategory,
  continueWatching,
}: {
  initialItems: VideoCardData[];
  initialCategory?: string;
  continueWatching?: VideoCardData[];
}) {
  const { categories, user, t } = useSession();
  const [items, setItems] = useState(initialItems);
  const [category, setCategory] = useState(initialCategory ?? "all");
  const [sort, setSort] = useState<"recommended" | "trending" | "recent" | "popular">("recommended");
  const [offset, setOffset] = useState(initialItems.length);
  const [hasMore, setHasMore] = useState(true);
  const [loading, setLoading] = useState(false);
  const sentinel = useRef<HTMLDivElement | null>(null);

  const load = useCallback(
    async (nextOffset: number, replace = false) => {
      setLoading(true);
      try {
        const params = new URLSearchParams({ offset: String(nextOffset), limit: "12", sort });
        if (category !== "all") params.set("category", category);
        if (user) params.set("subscribed", "0");
        const data = await api<{ items: VideoCardData[]; hasMore: boolean }>(`/api/videos?${params.toString()}`);
        setItems((prev) => (replace ? data.items : [...prev, ...data.items]));
        setOffset(nextOffset + data.items.length);
        setHasMore(data.hasMore && data.items.length > 0);
      } catch {
        setHasMore(false);
      } finally {
        setLoading(false);
      }
    },
    [category, sort, user],
  );

  const changeCategory = (slug: string) => {
    setCategory(slug);
    setItems([]);
    setOffset(0);
    setHasMore(true);
    void load(0, true);
    window.history.replaceState(null, "", slug === "all" ? "/" : `/?category=${slug}`);
  };

  const changeSort = (next: typeof sort) => {
    setSort(next);
    setItems([]);
    setOffset(0);
    setHasMore(true);
    void load(0, true);
  };

  useEffect(() => {
    const node = sentinel.current;
    if (!node) return;
    const observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting && hasMore && !loading) void load(offset);
    }, { rootMargin: "600px" });
    observer.observe(node);
    return () => observer.disconnect();
  }, [hasMore, loading, load, offset]);

  return (
    <div className="space-y-5">
      <div className="sticky top-14 z-20 -mx-4 bg-bg/95 px-4 py-3 backdrop-blur">
        <div className="no-scrollbar flex items-center gap-2 overflow-x-auto">
          {categories.map((item) => (
            <Chip key={item.slug} active={category === item.slug} onClick={() => changeCategory(item.slug)}>
              {item.emoji} {item.name}
            </Chip>
          ))}
        </div>
        <div className="mt-2 flex gap-2">
          {([
            ["recommended", "Recommended"],
            ["trending", "🔥 Trending"],
            ["recent", "🆕 New uploads"],
            ["popular", "⭐ Most viewed"],
          ] as const).map(([value, label]) => (
            <button
              key={value}
              onClick={() => changeSort(value)}
              className={`rounded-full px-3 py-1 text-xs font-semibold ${sort === value ? "bg-fg text-bg" : "bg-chip text-muted"}`}
            >
              {label}
            </button>
          ))}
        </div>
      </div>

      {continueWatching && continueWatching.length > 0 ? (
        <section className="space-y-3">
          <div className="flex items-center justify-between">
            <h2 className="text-lg font-semibold">Continue watching</h2>
            <Link href="/history" className="text-sm font-medium text-brand">History</Link>
          </div>
          <div className="no-scrollbar flex gap-4 overflow-x-auto pb-2">
            {continueWatching.map((video) => (
              <div key={video.id} className="w-64 shrink-0">
                <VideoCard video={video} />
              </div>
            ))}
          </div>
        </section>
      ) : null}

      {items.length === 0 && loading ? (
        <FeedSkeleton />
      ) : items.length === 0 ? (
        <EmptyState title={t("noResults")} hint="Try another category or upload the first video to it." />
      ) : (
        <div className="grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4">
          {items.map((video) => (
            <VideoCard key={video.id} video={video} />
          ))}
        </div>
      )}

      <div ref={sentinel} className="h-10" />
      {loading && items.length > 0 ? (
        <div className="flex justify-center py-4">
          <span className="h-8 w-8 animate-spin rounded-full border-2 border-muted border-t-brand" />
        </div>
      ) : null}
      {!hasMore && items.length > 0 ? (
        <p className="py-6 text-center text-sm text-muted">You have reached the end of this feed.</p>
      ) : null}
    </div>
  );
}
