"use client";

import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useInfiniteQuery } from "@tanstack/react-query";
import Cookies from "js-cookie";
import { fetchPosts } from "@/api/fetchPosts";
import {
  AcademyExploreItem,
  fetchAcademyExplore,
} from "@/api/fetchAcademyExplore";
import { trackExploreInteraction } from "@/api/trackExploreInteraction";
import { Post } from "@/types/types";
import { MutedProvider } from "@/components/models/ModelPage/MainModelCardPost";
import ReelsPostCard from "@/components/posts/ReelsPostCard";
import ReelsAcademyCard from "@/components/explore/ReelsAcademyCard";
import BoldIcon from "@/components/ui/BoldIcon";
import PageLoader from "@/components/ui/PageLoader";
import { ExploreFilterId } from "@/constants/exploreFilters";
import { buildExplorePostFilters } from "@/lib/explore/buildPostFilters";

// چند آیتم مانده به انتها، صفحهٔ بعد در پس‌زمینه پیش‌بارگذاری شود
const PREFETCH_AHEAD = 5;

export type ExploreReelItem =
  | { kind: "post"; key: string; post: Post }
  | { kind: "academy"; key: string; academy: AcademyExploreItem };

type ExploreReelsViewProps = {
  initialId: string;
  initialType?: "post" | "academy";
  showClose?: boolean;
};

function interleaveAcademy(
  posts: ExploreReelItem[],
  academy: ExploreReelItem[],
  page: number
): ExploreReelItem[] {
  if (!academy.length) return posts;
  const result: ExploreReelItem[] = [];
  let academyIdx = 0;
  const interval = 5;

  posts.forEach((post, index) => {
    result.push(post);
    const globalIndex = (page - 1) * posts.length + index;
    if ((globalIndex + 1) % interval === 0 && academyIdx < academy.length) {
      result.push(academy[academyIdx]);
      academyIdx += 1;
    }
  });

  while (academyIdx < academy.length) {
    result.push(academy[academyIdx]);
    academyIdx += 1;
  }

  return result;
}

export default function ExploreReelsView({
  initialId,
  initialType = "post",
  showClose = true,
}: ExploreReelsViewProps) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const token = Cookies.get("token") || "";
  const scrollRef = useRef<HTMLDivElement>(null);
  const scrolledRef = useRef(false);

  const filterParam = (searchParams.get("filter") ||
    "all") as ExploreFilterId;
  const lat = searchParams.get("lat");
  const lng = searchParams.get("lng");
  const coords =
    lat && lng ? { lat: parseFloat(lat), lng: parseFloat(lng) } : null;

  const postFilters = buildExplorePostFilters(filterParam, coords);
  const includeAcademy =
    filterParam === "all" || filterParam === "academy";
  const academyOnly = filterParam === "academy";

  const initialKey =
    initialType === "academy" ? `academy-${initialId}` : `post-${initialId}`;
  const [activeKey, setActiveKey] = useState(initialKey);

  const { data, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage } =
    useInfiniteQuery({
      queryKey: [
        "explore-reels",
        filterParam,
        coords?.lat,
        coords?.lng,
        postFilters,
        academyOnly,
      ],
      enabled: !(filterParam === "near_me" && !coords),
      queryFn: async ({ pageParam = 1 }) => {
        const page = pageParam as number;

        if (academyOnly) {
          const academyResult = await fetchAcademyExplore(page, 10, token);
          return {
            page,
            posts: [] as Post[],
            academyItems: academyResult.items,
            hasMore: academyResult.hasNextPage,
          };
        }

        const [postsResult, academyResult] = await Promise.all([
          fetchPosts(
            page,
            10,
            {
              ...postFilters,
              feedMode: "reels",
              seedPostId: page === 1 ? initialId : undefined,
            },
            token
          ),
          includeAcademy
            ? fetchAcademyExplore(page, 10, token)
            : Promise.resolve({ items: [], hasNextPage: false }),
        ]);

        return {
          page,
          posts: postsResult.posts ?? [],
          academyItems: academyResult.items,
          hasMore:
            (postsResult.posts?.length ?? 0) > 0 ||
            academyResult.hasNextPage,
        };
      },
      getNextPageParam: (lastPage, pages) =>
        lastPage.hasMore ? pages.length + 1 : undefined,
      initialPageParam: 1,
    });

  const items: ExploreReelItem[] = useMemo(() => {
    const seen = new Set<string>();
    const merged: ExploreReelItem[] = [];

    for (const page of data?.pages ?? []) {
      const pagePosts: ExploreReelItem[] = [];
      const pageAcademy: ExploreReelItem[] = [];

      for (const post of page.posts) {
        if (post.status !== "accept") continue;
        const key = `post-${post._id}`;
        if (seen.has(key)) continue;
        seen.add(key);
        pagePosts.push({ kind: "post", key, post });
      }

      if (includeAcademy) {
        for (const academy of page.academyItems) {
          if (academy.status && academy.status !== "accept") continue;
          const key = `academy-${academy._id}`;
          if (seen.has(key)) continue;
          seen.add(key);
          pageAcademy.push({ kind: "academy", key, academy });
        }
      }

      const pageItems =
        filterParam === "all" || filterParam === "academy"
          ? interleaveAcademy(pagePosts, pageAcademy, page.page)
          : [...pagePosts, ...pageAcademy];

      merged.push(...pageItems);
    }

    if (filterParam === "trending" || filterParam === "best_month") {
      return merged.sort((a, b) => {
        const scoreA =
          a.kind === "post"
            ? (a.post.likesCount ?? 0) + (a.post.commentsCount ?? 0)
            : a.academy.likesCount ?? 0;
        const scoreB =
          b.kind === "post"
            ? (b.post.likesCount ?? 0) + (b.post.commentsCount ?? 0)
            : b.academy.likesCount ?? 0;
        return scoreB - scoreA;
      });
    }

    return merged;
  }, [data, filterParam, includeAcademy]);

  useEffect(() => {
    if (scrolledRef.current || !items.length || !scrollRef.current) return;
    const idx = items.findIndex((item) => item.key === initialKey);
    const targetIdx = idx >= 0 ? idx : 0;
    scrollRef.current.scrollTo({
      top: targetIdx * window.innerHeight,
      behavior: "auto",
    });
    scrolledRef.current = true;
    setActiveKey(items[targetIdx]?.key || initialKey);
  }, [items, initialKey]);

  const handleScroll = useCallback(() => {
    const el = scrollRef.current;
    if (!el || !items.length) return;

    const index = Math.round(el.scrollTop / window.innerHeight);
    const item = items[index];
    if (item && item.key !== activeKey) {
      setActiveKey(item.key);
    }

    // پیش‌بارگذاری صفحهٔ بعد چند آیتم زودتر تا از صفحهٔ لودینگ جلوگیری شود
    if (
      index >= items.length - PREFETCH_AHEAD &&
      hasNextPage &&
      !isFetchingNextPage
    ) {
      fetchNextPage();
    }
  }, [items, activeKey, hasNextPage, isFetchingNextPage, fetchNextPage]);

  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    el.addEventListener("scroll", handleScroll, { passive: true });
    return () => el.removeEventListener("scroll", handleScroll);
  }, [handleScroll]);

  // بافر پس‌زمینه: با نزدیک‌شدن به انتهای آیتم‌های لودشده، صفحهٔ بعد از قبل گرفته می‌شود
  const activeIndex = useMemo(
    () => items.findIndex((i) => i.key === activeKey),
    [items, activeKey]
  );

  useEffect(() => {
    if (activeIndex < 0) return;
    if (
      activeIndex >= items.length - PREFETCH_AHEAD &&
      hasNextPage &&
      !isFetchingNextPage
    ) {
      fetchNextPage();
    }
  }, [activeIndex, items.length, hasNextPage, isFetchingNextPage, fetchNextPage]);

  useEffect(() => {
    if (!token) return;
    const item = items.find((i) => i.key === activeKey);
    if (!item || item.kind !== "academy") return;

    trackExploreInteraction(
      {
        targetType: "academy",
        targetId: item.academy._id,
        authorId: item.academy.user_id,
        contentType: "academy",
        action: "view",
      },
      token
    );
  }, [activeKey, items, token]);

  if (filterParam === "near_me" && !coords) {
    return (
      <p className="py-20 text-center text-neutral-500">
        موقعیت مکانی برای اکسپلور نزدیک من یافت نشد.
      </p>
    );
  }

  if (isLoading) {
    return <PageLoader className="min-h-[100dvh]" />;
  }

  if (isError || !items.length) {
    return (
      <p className="py-20 text-center text-neutral-500">محتوایی یافت نشد.</p>
    );
  }

  return (
    <MutedProvider>
      <div className="relative min-h-[100dvh] bg-black">
        {showClose && (
          <button
            type="button"
            onClick={() => router.back()}
            className="gentle-transition fixed left-4 top-[calc(1rem+env(safe-area-inset-top))] z-[100] flex h-10 w-10 items-center justify-center rounded-full bg-black/40 text-white backdrop-blur-md active:scale-90"
            aria-label="بستن"
          >
            <BoldIcon name="close-circle" size={22} tinted className="text-white" />
          </button>
        )}
        <div
          ref={scrollRef}
          className="h-[100dvh] snap-y snap-mandatory overflow-y-auto overscroll-y-contain scroll-smooth"
        >
          {items.map((item) =>
            item.kind === "post" ? (
              <ReelsPostCard
                key={item.key}
                postData={item.post}
                isActive={item.key === activeKey}
              />
            ) : (
              <ReelsAcademyCard
                key={item.key}
                item={item.academy}
                isActive={item.key === activeKey}
              />
            )
          )}
          {isFetchingNextPage && (
            <div className="flex h-24 snap-start items-center justify-center">
              <PageLoader className="min-h-[80px]" />
            </div>
          )}
        </div>
      </div>
    </MutedProvider>
  );
}
