"use client";

import React, { useEffect, useRef, useState, useCallback, useMemo } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useInfiniteQuery } from "@tanstack/react-query";
import { fetchPosts } from "@/api/fetchPosts";
import { fetchPostById } from "@/api/fetchPostById";
import { Post } from "@/types/types";
import { MutedProvider } from "@/components/models/ModelPage/MainModelCardPost";
import PageLoader from "@/components/ui/PageLoader";
import { Skeleton } from "@/components/ui/skeleton";
import Cookies from "js-cookie";
import BoldIcon from "@/components/ui/BoldIcon";
import ReelsPostCard from "./ReelsPostCard";
import { normalizeUserLevel } from "@/lib/userLevel";
import { readReelsSeedPost } from "@/lib/reelsSeedPost";
import { reorderColdStartFeed } from "@/lib/coldStartFeed";

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

interface PostFeedViewProps {
  initialPostId: string;
  initialPost?: Post | null;
  userId?: string;
  showClose?: boolean;
  videoOnly?: boolean;
  exploreMode?: boolean;
  feedMode?: "user" | "home" | "explore";
}

export default function PostFeedView({
  initialPostId,
  initialPost: initialPostProp,
  userId: userIdProp,
  showClose = true,
  videoOnly = false,
  exploreMode = false,
  feedMode: feedModeProp,
}: PostFeedViewProps) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const userIdFromQuery = searchParams.get("userId") || "";
  const feedFromQuery = searchParams.get("feed");
  const token = Cookies.get("token") || "";
  const scrollRef = useRef<HTMLDivElement>(null);
  const scrolledRef = useRef(false);
  const [activePostId, setActivePostId] = useState(initialPostId);
  const [seedPost, setSeedPost] = useState<Post | null>(
    initialPostProp || readReelsSeedPost(initialPostId) || null
  );
  const [seedLoading, setSeedLoading] = useState(!seedPost);

  useEffect(() => {
    let cancelled = false;
    scrolledRef.current = false;
    setActivePostId(initialPostId);

    const cached = readReelsSeedPost(initialPostId);
    if (cached) {
      setSeedPost(cached);
      setSeedLoading(false);
    } else if (initialPostProp) {
      setSeedPost(initialPostProp);
      setSeedLoading(false);
    } else {
      setSeedLoading(true);
    }

    fetchPostById(initialPostId, token).then((post) => {
      if (cancelled) return;
      if (post) {
        setSeedPost(post);
      }
      setSeedLoading(false);
    });

    return () => {
      cancelled = true;
    };
  }, [initialPostId, initialPostProp, token]);

  const feedMode =
    feedModeProp ||
    (feedFromQuery === "home"
      ? "home"
      : exploreMode
        ? "explore"
        : "user");

  const feedFilters = {
    expertise: searchParams.get("expertise") || "",
    province: searchParams.get("province") || "",
    city: searchParams.get("city") || "",
    userLevel: normalizeUserLevel(searchParams.get("userLevel") || ""),
    rateFilter: searchParams.get("rateFilter") || "",
    hashtag: searchParams.get("hashtag") || "",
    exploreFilter: searchParams.get("exploreFilter") || "",
    subExpertise: searchParams.get("subExpertise") || "",
  };

  const [resolvedUserId, setResolvedUserId] = useState(
    userIdProp || userIdFromQuery || ""
  );

  useEffect(() => {
    if (feedMode !== "user") {
      return;
    }
    if (userIdProp || userIdFromQuery) {
      setResolvedUserId(userIdProp || userIdFromQuery);
      return;
    }
    fetchPostById(initialPostId).then((post) => {
      const uid = post?.userId || post?.user_id;
      if (uid) setResolvedUserId(uid);
    });
  }, [initialPostId, userIdProp, userIdFromQuery, feedMode]);

  const queryFilters =
    feedMode === "user"
      ? { ...(resolvedUserId ? { _id: resolvedUserId } : {}) }
      : feedMode === "home"
        ? Object.fromEntries(
            Object.entries(feedFilters).filter(([, v]) => v)
          )
        : {};

  const algorithmFilters =
    feedMode === "home" || feedMode === "explore"
      ? {
          feedMode: "reels" as const,
          seedPostId: initialPostId,
        }
      : feedMode === "user"
        ? {
            feedMode: "reels" as const,
            seedPostId: initialPostId,
          }
        : {};

  const { data, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage } =
    useInfiniteQuery({
      queryKey: [
        "post-feed",
        feedMode,
        resolvedUserId,
        initialPostId,
        videoOnly,
        queryFilters,
        algorithmFilters,
      ],
      queryFn: ({ pageParam = 1 }) =>
        fetchPosts(
          pageParam as number,
          10,
          {
            ...queryFilters,
            ...(pageParam === 1
              ? algorithmFilters
              : feedMode === "home" || feedMode === "explore" || feedMode === "user"
                ? { feedMode: "reels" as const }
                : {}),
            ...(videoOnly ? { type: "video" } : {}),
          },
          token
        ),
      initialPageParam: 1,
      getNextPageParam: (lastPage, pages) =>
        lastPage.posts?.length ? pages.length + 1 : undefined,
      enabled:
        feedMode === "home" ||
        feedMode === "explore" ||
        !!resolvedUserId ||
        !!token,
    });

  const posts: Post[] = useMemo(() => {
    const apiPosts =
      data?.pages
        ?.flatMap((p) => p.posts)
        ?.filter(
          (p) =>
            p.status === "accept" && (!videoOnly || p.type === "video")
        ) ?? [];

    const seen = new Set<string>();
    const merged: Post[] = [];

    const addPost = (post: Post) => {
      const id = String(post._id);
      if (seen.has(id)) return;
      if (post.status !== "accept") return;
      if (videoOnly && post.type !== "video") return;
      seen.add(id);
      merged.push(post);
    };

    if (seedPost) addPost(seedPost);

    const restPosts =
      seedPost && (feedMode === "home" || feedMode === "explore")
        ? reorderColdStartFeed(apiPosts, seedPost)
        : apiPosts;

    restPosts.forEach(addPost);

    return merged;
  }, [data, seedPost, videoOnly, feedMode]);

  useEffect(() => {
    if (scrolledRef.current || seedLoading || !posts.length || !scrollRef.current) {
      return;
    }

    const idx = posts.findIndex(
      (p) => String(p._id) === String(initialPostId)
    );
    const targetIdx = idx >= 0 ? idx : 0;

    scrollRef.current.scrollTo({
      top: targetIdx * window.innerHeight,
      behavior: "auto",
    });
    scrolledRef.current = true;
    setActivePostId(posts[targetIdx]?._id || initialPostId);
  }, [posts, initialPostId, seedLoading]);

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

    const index = Math.round(el.scrollTop / window.innerHeight);
    const post = posts[index];
    if (post && String(post._id) !== String(activePostId)) {
      setActivePostId(post._id);
    }

    // پیش‌بارگذاری صفحهٔ بعد چند پست زودتر تا از صفحهٔ لودینگ جلوگیری شود
    if (
      index >= posts.length - PREFETCH_AHEAD &&
      hasNextPage &&
      !isFetchingNextPage
    ) {
      fetchNextPage();
    }
  }, [posts, activePostId, 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(
    () => posts.findIndex((p) => String(p._id) === String(activePostId)),
    [posts, activePostId]
  );

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

  if (feedMode === "user" && !resolvedUserId && isLoading) {
    return (
      <div className="space-y-4 p-4">
        <Skeleton className="h-[70vh] w-full rounded-2xl" />
      </div>
    );
  }

  if (
    (isLoading && !data) ||
    (seedLoading && !seedPost)
  ) {
    return <PageLoader className="min-h-[100dvh]" />;
  }

  if (isError || posts.length === 0) {
    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"
        >
          {posts.map((post) => (
            <ReelsPostCard
              key={post._id}
              postData={post}
              isActive={String(post._id) === String(activePostId)}
            />
          ))}
          {isFetchingNextPage && (
            <div className="flex h-24 snap-start items-center justify-center">
              <PageLoader className="min-h-[80px]" />
            </div>
          )}
        </div>
      </div>
    </MutedProvider>
  );
}
