"use client";

import { useCallback, useEffect, useState } from "react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import useAxios from "@/hooks/useAxios";
import { Post } from "@/types/types";
import { getPostMedia } from "@/lib/explore/postMedia";
import ExploreVideoThumb from "@/components/explore/ExploreVideoThumb";
import { buildPostPath } from "@/lib/postSlug";
import { cacheReelsSeedPost } from "@/lib/reelsSeedPost";
import { useTranslation } from "react-i18next";

const ASPECT_RATIOS = [
  "aspect-[2/3]",
  "aspect-[3/4]",
  "aspect-[4/5]",
  "aspect-[5/6]",
  "aspect-square",
  "aspect-[3/5]",
] as const;
const SKELETON_COUNT = 8;

function hashAspect(postId: string): (typeof ASPECT_RATIOS)[number] {
  let hash = 0;
  for (let i = 0; i < postId.length; i++) {
    hash = (hash + postId.charCodeAt(i)) % ASPECT_RATIOS.length;
  }
  return ASPECT_RATIOS[hash];
}

function ActivityCardSkeleton({ seed }: { seed: number }) {
  const aspect = ASPECT_RATIOS[seed % ASPECT_RATIOS.length];
  return (
    <div
      className={`mb-2 w-full break-inside-avoid overflow-hidden rounded-2xl bg-neutral-200 dark:bg-neutral-800 ${aspect} animate-pulse`}
    />
  );
}

type Props = {
  endpoint: string;
};

export default function ActivityPostGrid({ endpoint }: Props) {
  const { t } = useTranslation("common");
  const { request } = useAxios();
  const router = useRouter();
  const [posts, setPosts] = useState<Post[]>([]);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(false);
  const [fetchingMore, setFetchingMore] = useState(false);

  const loadPage = useCallback(
    async (pageNum: number) => {
      const res = await request<{ posts: Post[]; totalPages: number }>(
        "GET",
        `${endpoint}?page=${pageNum}&limit=12`,
        null,
        { noToast: true }
      );
      return res;
    },
    [request, endpoint]
  );

  useEffect(() => {
    setLoading(true);
    loadPage(1)
      .then((res) => {
        setPosts(res?.posts || []);
        setHasMore((res?.totalPages || 1) > 1);
        setPage(1);
      })
      .catch(() => setPosts([]))
      .finally(() => setLoading(false));
  }, [loadPage]);

  const fetchMore = useCallback(() => {
    if (fetchingMore || !hasMore) return;
    setFetchingMore(true);
    const nextPage = page + 1;
    loadPage(nextPage)
      .then((res) => {
        setPosts((prev) => [...prev, ...(res?.posts || [])]);
        setHasMore(nextPage < (res?.totalPages || 1));
        setPage(nextPage);
      })
      .catch(() => setHasMore(false))
      .finally(() => setFetchingMore(false));
  }, [fetchingMore, hasMore, page, loadPage]);

  useEffect(() => {
    const handleScroll = () => {
      if (
        window.innerHeight + window.scrollY >=
        document.body.offsetHeight - 800
      ) {
        fetchMore();
      }
    };
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, [fetchMore]);

  const openPost = (post: Post) => {
    cacheReelsSeedPost(post);
    router.push(buildPostPath(post._id, post));
  };

  if (loading) {
    return (
      <div className="columns-2 gap-2">
        {Array.from({ length: SKELETON_COUNT }).map((_, i) => (
          <ActivityCardSkeleton key={i} seed={i} />
        ))}
      </div>
    );
  }

  if (posts.length === 0) {
    return (
      <p className="py-16 text-center text-sm text-neutral-500">
        {t("models.nothingFound")}
      </p>
    );
  }

  return (
    <div className="columns-2 gap-2">
      {posts.map((post) => {
        const media = getPostMedia(post);
        if (!media) return null;
        const aspect = hashAspect(post._id);
        return (
          <button
            key={post._id}
            type="button"
            onClick={() => openPost(post)}
            className={`gentle-transition relative mb-2 block w-full overflow-hidden rounded-2xl bg-neutral-200 text-right dark:bg-neutral-900 active:scale-[0.98] ${aspect}`}
          >
            {media.kind === "video" ? (
              <ExploreVideoThumb src={media.src} poster={media.poster} />
            ) : (
              <Image
                src={media.src}
                alt=""
                fill
                className="object-cover"
                sizes="50vw"
                unoptimized
              />
            )}
          </button>
        );
      })}
      {fetchingMore
        ? Array.from({ length: 4 }).map((_, i) => (
            <ActivityCardSkeleton key={`more-${i}`} seed={i} />
          ))
        : null}
    </div>
  );
}
