import { useNavigate, useParams } from "react-router-dom";
import { useMemo, useCallback, useEffect, useState } from "react";
import { getTopicFeedConfig } from "../../config/topicFeedConfig";
import { useTopicFeed } from "../../hooks/useTopicFeed";
import { mapFeedItemToPostCardModel } from "../../utils/feedMapper";
import { AppBackground } from "./shared/AppBackground";
import { FeedHeader } from "./feed/FeedHeader";
import { FeedList } from "./feed/FeedList";
import { FeedEmptyState } from "./feed/FeedEmptyState";
import { FeedFloatingButton } from "./feed/FeedFloatingButton";
import { BottomNav } from "./BottomNav";
import { usePageTracking } from "../../hooks/usePageTracking";
import { useProfile } from "../context/ProfileContext";
import { toast } from "sonner";
import { backgroundImages } from "../../config/backgroundConfig";
import { loadTeamMembers, type TeamMember } from "../../services/feedService";

const preloadImage = (src?: string) => {
  if (!src) return Promise.resolve();

  return new Promise<void>((resolve) => {
    const image = new Image();
    image.onload = () => {
      if (image.decode) {
        image.decode().then(() => resolve()).catch(() => resolve());
        return;
      }
      resolve();
    };
    image.onerror = () => resolve();
    image.src = src;
  });
};

const getPostAssetKey = (post: ReturnType<typeof mapFeedItemToPostCardModel>) =>
  [post.id, post.image, post.authorAvatar].join("|");

export function FeedPage() {
  const { topicId } = useParams<{ topicId: string }>();
  const navigate = useNavigate();
  const { isProfileComplete } = useProfile();

  const topic = useMemo(() => getTopicFeedConfig(topicId), [topicId]);

  usePageTracking(topic?.title || "فید");

  const { feedItems, initialLoading, loadingMore, error, hasMore, loadMore, deletePost } =
    useTopicFeed(topic);

  const postCards = useMemo(() => {
    if (!topic) return [];
    return feedItems.map((item) => mapFeedItemToPostCardModel(item, topic.serverName));
  }, [feedItems, topic]);
  const [readyAssetKeys, setReadyAssetKeys] = useState<Set<string>>(() => new Set());
  const [hasShownInitialFeed, setHasShownInitialFeed] = useState(false);
  const [teamMembersByPost, setTeamMembersByPost] = useState<Record<string, TeamMember[]>>({});
  const [readyTeamMemberPostIds, setReadyTeamMemberPostIds] = useState<Set<string>>(() => new Set());

  useEffect(() => {
    let cancelled = false;
    const pendingPosts = postCards.filter((post) => !readyAssetKeys.has(getPostAssetKey(post)));

    if (pendingPosts.length === 0) return;

    Promise.all(
      pendingPosts.map(async (post) => {
        await Promise.all([preloadImage(post.image), preloadImage(post.authorAvatar)]);
        return getPostAssetKey(post);
      }),
    ).then((keys) => {
      if (cancelled) return;
      setReadyAssetKeys((current) => {
        const next = new Set(current);
        keys.forEach((key) => next.add(key));
        return next;
      });
    });

    return () => {
      cancelled = true;
    };
  }, [postCards, readyAssetKeys]);

  const visiblePostCards = useMemo(
    () => postCards.filter((post) => readyAssetKeys.has(getPostAssetKey(post))),
    [postCards, readyAssetKeys],
  );
  const postsRequiringTeamMembers = useMemo(
    () =>
      postCards.filter(
        (post) =>
          typeof post.teamMemberIds === "string" &&
          post.teamMemberIds.trim().length > 0,
      ),
    [postCards],
  );

  useEffect(() => {
    let cancelled = false;
    const pendingPosts = postsRequiringTeamMembers.filter(
      (post) => !readyTeamMemberPostIds.has(post.id),
    );

    if (pendingPosts.length === 0) return;

    Promise.all(
      pendingPosts.map(async (post) => {
        const response = await loadTeamMembers(post.teamMemberIds!.trim());
        return {
          id: post.id,
          members: response.success ? response.data : [],
        };
      }),
    ).then((results) => {
      if (cancelled) return;

      setTeamMembersByPost((current) => {
        const next = { ...current };
        results.forEach(({ id, members }) => {
          next[id] = members;
        });
        return next;
      });

      setReadyTeamMemberPostIds((current) => {
        const next = new Set(current);
        results.forEach(({ id }) => next.add(id));
        return next;
      });
    });

    return () => {
      cancelled = true;
    };
  }, [postsRequiringTeamMembers, readyTeamMemberPostIds]);

  const allCurrentAssetsReady =
    postCards.length === 0 || visiblePostCards.length === postCards.length;
  const allTeamMembersReady =
    postsRequiringTeamMembers.length === 0 ||
    postsRequiringTeamMembers.every((post) => readyTeamMemberPostIds.has(post.id));

  useEffect(() => {
    if (!initialLoading && postCards.length > 0 && allCurrentAssetsReady && allTeamMembersReady) {
      setHasShownInitialFeed(true);
    }
  }, [allCurrentAssetsReady, allTeamMembersReady, initialLoading, postCards.length]);

  const handleScroll = useCallback(
    (e: React.UIEvent<HTMLDivElement>) => {
      const currentRef = e.currentTarget;
      const scrollThreshold = currentRef.scrollHeight - currentRef.clientHeight - 80;

      if (currentRef.scrollTop >= scrollThreshold && !loadingMore && hasMore) {
        loadMore();
      }
    },
    [loadingMore, hasMore, loadMore]
  );

  const handleStartMission = useCallback(() => {
    // بررسی اینکه پروفایل کامل است یا خیر
    if (!isProfileComplete) {
      toast.error("لطفاً ابتدا پروفایل خود را در قسمت 'پروفایل من' تکمیل کنید", {
        duration: 3000,
        position: "top-center",
      });
      return;
    }
    navigate(`/challenges/${topicId}`);
  }, [navigate, topicId, isProfileComplete]);

  const handleBack = useCallback(() => {
    navigate("/");
  }, [navigate]);

  if (!topic) {
    return (
      <div className="flex items-center justify-center h-screen text-white">
        موضوع یافت نشد
      </div>
    );
  }

  const showEmptyState = !initialLoading && !error && postCards.length === 0;
  const showInitialMediaLoading =
    !initialLoading && postCards.length > 0 && !hasShownInitialFeed;
  const hasHiddenPendingPosts = visiblePostCards.length < postCards.length;

  return (
    <div className="feed-page-shell fixed inset-0 w-full h-screen overflow-hidden">
      <AppBackground position="fixed" zIndex={0} imageUrl={backgroundImages.feed} />

      <div className="relative z-10 max-w-md mx-auto h-full flex flex-col">
        <FeedHeader topicTitle={topic.title} subtitle="صفحه پست ها" onBack={handleBack} />

        {initialLoading || showInitialMediaLoading ? (
          <div className="flex-1 flex items-center justify-center">
            <div className="animate-spin rounded-full h-10 w-10 border-b-2 border-white"></div>
          </div>
        ) : showEmptyState ? (
          <FeedEmptyState accentColor={topic.accentColor} onStartMission={handleStartMission} />
        ) : (
          <FeedList
            posts={visiblePostCards.map((post) => ({
              ...post,
              preloadedTeamMembers: teamMembersByPost[post.id],
            }))}
            loadingMore={loadingMore || hasHiddenPendingPosts}
            error={error}
            onScroll={handleScroll}
            onDelete={deletePost}
          />
        )}
      </div>

      <FeedFloatingButton onClick={handleStartMission} />
      <BottomNav fixed />
    </div>
  );
}
