import { useEffect, useState, useCallback, useRef, memo, useMemo } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Plus, ChevronRight, Loader2, ArrowUp, Sparkles, Users, RefreshCw } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { useQueryClient } from "@tanstack/react-query";
import { supabase, createRealtimeChannel } from "@/integrations/supabase/client";
import { useAuth } from "@/hooks/useAuth";
import { useLike } from "@/hooks/useLike";
import AppLayout from "@/components/AppLayout";
import BrandLogo from "@/components/BrandLogo";
import PostCard from "@/components/PostCard";
import StoryCard from "@/components/StoryCard";
import { AdInFeed } from "@/components/AdPost";
import { preloadPage } from "@/lib/preload";
import Avatar from "@/components/Avatar";
import { cn } from "@/lib/utils";

export const FEED_QUERY_KEY = ["feed-posts"];

const CHUNK_SIZE = 8;
const MemoPostCard = memo(PostCard);

interface Story {
  id: string;
  user_id: string;
  image_url: string;
  is_sponsored?: boolean;
  profiles?: any;
}

interface Post {
  id: string;
  user_id: string;
  image_url: string;
  image_urls?: string[] | null;
  caption: string | null;
  likes_count: number;
  comments_count: number;
  created_at: string;
  profiles?: any;
  liked_by_me?: boolean;
  media_type?: "image" | "video" | "audio";
  video_url?: string | null;
  thumbnail_url?: string | null;
  audio_url?: string | null;
  scale_type?: "original" | "square" | "wide" | "tall";
  music_metadata?: any;
  is_sponsored?: boolean;
  sponsor_name?: string;
  sponsor_url?: string;
}

const FeedPostSkeleton = () => (
  <div className="bg-[#0F172A] rounded-3xl p-5 space-y-4 shadow-sm border border-white/[0.04] overflow-hidden relative">
    <div className="absolute inset-0 -translate-x-full animate-[shimmer_2s_infinite] bg-gradient-to-r from-transparent via-white/5 to-transparent z-10" />
    <div className="flex items-center gap-3">
      <div className="w-10 h-10 rounded-full bg-slate-800/60" />
      <div className="space-y-2 flex-1">
        <div className="h-3 w-32 bg-slate-800/60 rounded-full" />
        <div className="h-2 w-20 bg-slate-800/40 rounded-full" />
      </div>
    </div>
    <div className="h-[320px] sm:h-[400px] w-full bg-slate-800/40 rounded-2xl" />
    <div className="flex items-center gap-4 pt-1">
      <div className="w-6 h-6 rounded-full bg-slate-800/60" />
      <div className="w-6 h-6 rounded-full bg-slate-800/60" />
      <div className="w-6 h-6 rounded-full bg-slate-800/60" />
    </div>
  </div>
);

export default function Feed() {
  const navigate = useNavigate();
  const { user } = useAuth();
  const { toggleLike } = useLike();
  const queryClient = useQueryClient();

  const [feedMode, setFeedMode] = useState<"for-you" | "following">("for-you");
  const [stories, setStories] = useState<Story[]>([]);
  const [posts, setPosts] = useState<Post[]>([]);
  const [followingUserIds, setFollowingUserIds] = useState<Set<string>>(new Set());
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [displayCount, setDisplayCount] = useState(CHUNK_SIZE);
  const [newPostsCount, setNewPostsCount] = useState(0);
  const [showScrollTop, setShowScrollTop] = useState(false);

  useEffect(() => {
    preloadPage("/messages");
    preloadPage("/notifications");
    preloadPage("/profile");
    preloadPage("/search");
  }, []);

  const storyScrollRef = useRef<HTMLDivElement>(null);
  const lastFeedTimestampRef = useRef<string | null>(null);
  const sentinelRef = useRef<HTMLDivElement>(null);

  // ── Algorithm: Calculate ranking score ──────────────────────────────────────
  const rankPosts = useCallback((rawPosts: Post[], followedIds: Set<string>): Post[] => {
    return [...rawPosts].sort((a, b) => {
      // Sponsored posts stay at top priority
      if (a.is_sponsored && !b.is_sponsored) return -1;
      if (!a.is_sponsored && b.is_sponsored) return 1;

      const ageHoursA = Math.max(0.1, (Date.now() - new Date(a.created_at).getTime()) / (1000 * 60 * 60));
      const ageHoursB = Math.max(0.1, (Date.now() - new Date(b.created_at).getTime()) / (1000 * 60 * 60));

      const likesA = a.likes_count || 0;
      const likesB = b.likes_count || 0;
      const commentsA = a.comments_count || 0;
      const commentsB = b.comments_count || 0;

      const followedBonusA = a.user_id && followedIds.has(a.user_id) ? 35 : 0;
      const followedBonusB = b.user_id && followedIds.has(b.user_id) ? 35 : 0;

      const verifiedBonusA = a.profiles?.is_verified ? 15 : 0;
      const verifiedBonusB = b.profiles?.is_verified ? 15 : 0;

      // Gravity formula: Score = (engagement + bonus) / (age + 2)^1.35
      const scoreA = (likesA * 3.5 + commentsA * 6.0 + followedBonusA + verifiedBonusA) / Math.pow(ageHoursA + 2, 1.35);
      const scoreB = (likesB * 3.5 + commentsB * 6.0 + followedBonusB + verifiedBonusB) / Math.pow(ageHoursB + 2, 1.35);

      return scoreB - scoreA;
    });
  }, []);

  // ── Load Feed Data ──────────────────────────────────────────────────────────
  const load = useCallback(async () => {
    const cached = queryClient.getQueryData<Post[]>(FEED_QUERY_KEY);
    if (cached && cached.length > 0) {
      setPosts(cached);
      setLoading(false);
    } else {
      setLoading(true);
    }

    try {
      // 1. Fetch followed users if authenticated
      let followedSet = new Set<string>();
      if (user) {
        const { data: followRows } = await supabase
          .from("follows")
          .select("following_id")
          .eq("follower_id", user.id);
        if (followRows) {
          followedSet = new Set(followRows.map((f) => f.following_id));
          setFollowingUserIds(followedSet);
        }
      }

      // 2. Fetch stories, posts, likes in parallel
      const [storiesRes, postsRes, likesRes] = await Promise.all([
        supabase
          .from("stories")
          .select("id,user_id,image_url,is_sponsored,profiles!stories_user_id_fkey(display_name,photo_url,username,is_verified,profile_theme)")
          .gt("expires_at", new Date().toISOString())
          .order("created_at", { ascending: false })
          .limit(30),
        supabase
          .from("posts")
          .select("*, profiles!posts_user_id_fkey(display_name,photo_url,username,is_verified,profile_theme)")
          .order("created_at", { ascending: false })
          .limit(60),
        user
          ? supabase.from("post_likes").select("post_id").eq("user_id", user.id)
          : Promise.resolve({ data: [] }),
      ]);

      if (storiesRes.data) setStories(storiesRes.data as any);

      if (postsRes.data) {
        const likedSet = new Set(((likesRes as any)?.data || []).map((l: any) => l.post_id));
        const enriched = (postsRes.data as any[]).map((x) => ({
          ...x,
          liked_by_me: likedSet.has(x.id),
        }));

        const ranked = rankPosts(enriched, followedSet);
        setPosts(ranked);
        queryClient.setQueryData(FEED_QUERY_KEY, ranked);

        if (enriched.length > 0) {
          lastFeedTimestampRef.current = enriched[0].created_at;
        }
      }
    } catch (err) {
      console.error("[Feed] Load error:", err);
    } finally {
      setDisplayCount(CHUNK_SIZE);
      setNewPostsCount(0);
      setLoading(false);
    }
  }, [user, queryClient, rankPosts]);

  useEffect(() => {
    load();
  }, [load]);

  // ── Realtime Postgres Changes ────────────────────────────────────────────────
  useEffect(() => {
    const channel = createRealtimeChannel(`feed-posts-${user?.id || "anon"}`);
    channel
      .on("postgres_changes", { event: "INSERT", schema: "public", table: "posts" }, () => {
        if (lastFeedTimestampRef.current) {
          setNewPostsCount((prev) => prev + 1);
        }
      })
      .on("postgres_changes", { event: "UPDATE", schema: "public", table: "posts" }, (payload) => {
        const { new: newRecord } = payload;
        setPosts((prev) =>
          prev.map((p) =>
            p.id === newRecord.id && newRecord.likes_count !== undefined
              ? { ...p, likes_count: newRecord.likes_count }
              : p
          )
        );
      })
      .subscribe();

    return () => {
      supabase.removeChannel(channel);
    };
  }, [user?.id]);

  // ── Scroll to Top Detection ──────────────────────────────────────────────────
  useEffect(() => {
    const handleScroll = () => {
      if (window.scrollY > 400) {
        setShowScrollTop(true);
      } else {
        setShowScrollTop(false);
      }
    };
    window.addEventListener("scroll", handleScroll, { passive: true });
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  const scrollToTop = () => {
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const loadNewPosts = useCallback(async () => {
    if (!lastFeedTimestampRef.current) return;
    const { data: newPosts } = await supabase
      .from("posts")
      .select("*, profiles!posts_user_id_fkey(display_name,photo_url,username,is_verified,profile_theme)")
      .gt("created_at", lastFeedTimestampRef.current)
      .order("created_at", { ascending: false });

    if (!newPosts?.length) return;
    if (user) {
      const { data: likes } = await supabase.from("post_likes").select("post_id").eq("user_id", user.id);
      const likedSet = new Set((likes || []).map((l) => l.post_id));
      const enriched = (newPosts as any[]).map((x) => ({ ...x, liked_by_me: likedSet.has(x.id) }));
      const ranked = rankPosts([...enriched, ...posts], followingUserIds);
      setPosts(ranked);
    } else {
      setPosts((prev) => [...(newPosts as any[]), ...prev]);
    }
    setDisplayCount(CHUNK_SIZE);
    setNewPostsCount(0);
    if (newPosts.length > 0) {
      lastFeedTimestampRef.current = newPosts[0].created_at;
    }
  }, [user, posts, rankPosts, followingUserIds]);

  const loadMore = useCallback(() => {
    if (loadingMore || displayCount >= posts.length) return;
    setLoadingMore(true);
    setTimeout(() => {
      setDisplayCount((prev) => Math.min(prev + CHUNK_SIZE, posts.length));
      setLoadingMore(false);
    }, 150);
  }, [loadingMore, displayCount, posts.length]);

  useEffect(() => {
    if (!sentinelRef.current || loading) return;
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) loadMore();
      },
      { rootMargin: "300px" }
    );
    observer.observe(sentinelRef.current);
    return () => observer.disconnect();
  }, [loading, loadMore]);

  const handleToggleLike = useCallback(
    (post: Post) => {
      if (!user) return;
      const wasLiked = !!post.liked_by_me;
      setPosts((prev) =>
        prev.map((x) =>
          x.id === post.id
            ? {
                ...x,
                liked_by_me: !wasLiked,
                likes_count: wasLiked ? Math.max(0, (x.likes_count || 0) - 1) : (x.likes_count || 0) + 1,
              }
            : x
        )
      );
      toggleLike(post.id, wasLiked);
    },
    [user, toggleLike]
  );

  // ── Filtered Posts by Active Tab ─────────────────────────────────────────────
  const displayedPosts = useMemo(() => {
    if (feedMode === "following") {
      return posts.filter((p) => p.user_id && followingUserIds.has(p.user_id));
    }
    return posts;
  }, [feedMode, posts, followingUserIds]);

  const storyGroups = Array.from(
    stories.reduce((map, s) => {
      if (!map.has(s.user_id)) map.set(s.user_id, s);
      return map;
    }, new Map<string, Story>()).values()
  );

  return (
    <AppLayout>
      <div className="w-full space-y-6 pb-8">

        {/* ── Feed Algorithm Tabs (Para Você / Seguindo) ────────────────── */}
        <div className="sticky top-0 z-20 bg-[#070C1A]/90 backdrop-blur-2xl border-b border-white/[0.06] -mx-4 px-4 sm:mx-0 sm:px-0 sm:rounded-2xl py-2 flex items-center justify-center gap-2">
          <button
            onClick={() => setFeedMode("for-you")}
            className={cn(
              "relative px-5 py-2 rounded-xl text-xs font-bold transition-all flex items-center gap-1.5",
              feedMode === "for-you"
                ? "bg-sky-600 text-white shadow-md shadow-sky-600/30"
                : "text-slate-400 hover:text-white hover:bg-white/[0.04]"
            )}
          >
            <Sparkles className="w-3.5 h-3.5" />
            Para Você
          </button>
          <button
            onClick={() => setFeedMode("following")}
            className={cn(
              "relative px-5 py-2 rounded-xl text-xs font-bold transition-all flex items-center gap-1.5",
              feedMode === "following"
                ? "bg-sky-600 text-white shadow-md shadow-sky-600/30"
                : "text-slate-400 hover:text-white hover:bg-white/[0.04]"
            )}
          >
            <Users className="w-3.5 h-3.5" />
            Seguindo
            {followingUserIds.size > 0 && (
              <span className="text-[10px] opacity-75 font-mono">({followingUserIds.size})</span>
            )}
          </button>
        </div>

        {/* ── Stories Horizontal Bar ───────────────────────────────────── */}
        <div className="space-y-2.5">
          <div className="flex items-center justify-between px-1">
            <h2 className="text-xs font-bold text-slate-400 tracking-wider uppercase flex items-center gap-2">
              <span className="w-1.5 h-4 rounded-full bg-sky-400" />
              Stories
            </h2>
            <button
              onClick={() => navigate("/create-story")}
              className="text-xs font-bold text-sky-400 hover:text-sky-300 transition-colors flex items-center gap-1"
            >
              Criar <ChevronRight className="w-3.5 h-3.5" />
            </button>
          </div>

          <div
            ref={storyScrollRef}
            className="flex gap-3 overflow-x-auto pb-2 -mx-4 px-4 sm:-mx-0 sm:px-0 scrollbar-hide select-none"
          >
            {/* Create Story Avatar */}
            <motion.button
              whileTap={{ scale: 0.94 }}
              onClick={() => navigate("/create-story")}
              className="flex flex-col items-center gap-1.5 shrink-0 group"
            >
              <div className="relative w-16 h-16 rounded-full p-0.5 bg-gradient-to-tr from-sky-500 to-blue-600 shadow-md">
                <div className="w-full h-full rounded-full bg-slate-950 flex items-center justify-center overflow-hidden">
                  {user?.user_metadata?.avatar_url ? (
                    <img
                      src={user.user_metadata.avatar_url}
                      alt="Seu avatar"
                      className="w-full h-full object-cover opacity-80 group-hover:opacity-100 transition-opacity"
                    />
                  ) : (
                    <BrandLogo size={28} />
                  )}
                </div>
                <span className="absolute bottom-0 right-0 w-5 h-5 rounded-full bg-sky-500 text-white flex items-center justify-center ring-2 ring-slate-950 shadow-sm">
                  <Plus className="w-3.5 h-3.5 stroke-[3px]" />
                </span>
              </div>
              <span className="text-[11px] text-slate-300 font-semibold truncate max-w-[64px]">
                Seu story
              </span>
            </motion.button>

            {/* Story cards from other users */}
            {storyGroups.map((s) => (
              <StoryCard
                key={s.user_id}
                user_id={s.user_id}
                profiles={s.profiles}
                is_sponsored={s.is_sponsored}
              />
            ))}
          </div>
        </div>

        {/* ── Realtime New Posts Floating Pill ─────────────────────────── */}
        <AnimatePresence>
          {newPostsCount > 0 && (
            <motion.div
              initial={{ opacity: 0, y: -20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              className="sticky top-14 z-30 flex justify-center pointer-events-none"
            >
              <button
                onClick={() => {
                  loadNewPosts();
                  scrollToTop();
                }}
                className="pointer-events-auto flex items-center gap-2 px-5 py-2.5 rounded-full bg-sky-600 hover:bg-sky-500 text-white text-xs font-bold shadow-xl shadow-sky-600/40 transition-all active:scale-95"
              >
                <RefreshCw className="w-3.5 h-3.5 animate-spin" />
                {newPostsCount} nova{newPostsCount > 1 ? "s" : ""} publicação{newPostsCount > 1 ? "ões" : ""}
                <ArrowUp className="w-3.5 h-3.5" />
              </button>
            </motion.div>
          )}
        </AnimatePresence>

        {/* ── Posts Feed List ──────────────────────────────────────────── */}
        {loading ? (
          <div className="space-y-6">
            {[1, 2, 3].map((i) => (
              <FeedPostSkeleton key={i} />
            ))}
          </div>
        ) : displayedPosts.length === 0 ? (
          <motion.div
            initial={{ opacity: 0, y: 16 }}
            animate={{ opacity: 1, y: 0 }}
            className="py-20 space-y-5 text-center"
          >
            <div className="w-16 h-16 mx-auto rounded-3xl bg-slate-900/80 border border-white/[0.08] flex items-center justify-center text-sky-400">
              <Sparkles className="w-8 h-8" />
            </div>
            <div>
              <p className="text-lg font-bold text-white">
                {feedMode === "following"
                  ? "Nenhuma publicação das pessoas que você segue"
                  : "Nenhuma publicação no momento"}
              </p>
              <p className="text-xs text-slate-400 mt-1 max-w-xs mx-auto">
                {feedMode === "following"
                  ? "Siga novos criadores na aba Comunidade para ver suas postagens aqui!"
                  : "Seja o primeiro a compartilhar uma foto ou vídeo com a comunidade!"}
              </p>
            </div>
            <div className="flex gap-2 justify-center">
              {feedMode === "following" ? (
                <button
                  onClick={() => navigate("/community")}
                  className="px-6 py-2.5 rounded-full bg-sky-600 hover:bg-sky-500 text-white text-xs font-bold transition-all shadow-md shadow-sky-600/30"
                >
                  Explorar Criadores
                </button>
              ) : (
                <button
                  onClick={() => navigate("/create-post")}
                  className="px-6 py-2.5 rounded-full bg-sky-600 hover:bg-sky-500 text-white text-xs font-bold transition-all shadow-md shadow-sky-600/30 flex items-center gap-1.5"
                >
                  <Plus className="w-4 h-4" /> Criar publicação
                </button>
              )}
            </div>
          </motion.div>
        ) : (
          <div className="space-y-7">
            <AnimatePresence mode="popLayout">
              {(() => {
                const visiblePosts = displayedPosts.slice(0, displayCount);
                const items: JSX.Element[] = [];
                const adPositions =
                  visiblePosts.length >= 10 ? [3, 7] : visiblePosts.length >= 5 ? [Math.floor(visiblePosts.length / 2)] : [];

                visiblePosts.forEach((post, i) => {
                  items.push(
                    <motion.div
                      key={post.id}
                      initial={{ opacity: 0, y: 14 }}
                      animate={{ opacity: 1, y: 0 }}
                      transition={{ delay: i * 0.02, type: "spring", stiffness: 320, damping: 26 }}
                      layout
                    >
                      <MemoPostCard {...post} onToggleLike={handleToggleLike} index={i} />
                    </motion.div>
                  );

                  if (adPositions.includes(i)) {
                    items.push(
                      <motion.div
                        key={`ad-${i}`}
                        initial={{ opacity: 0, y: 14 }}
                        animate={{ opacity: 1, y: 0 }}
                        transition={{ delay: (i + 0.5) * 0.02 }}
                      >
                        <AdInFeed />
                      </motion.div>
                    );
                  }
                });

                return items;
              })()}
            </AnimatePresence>

            {/* Sentinel for infinite scroll */}
            <div ref={sentinelRef} className="flex items-center justify-center py-6">
              {loadingMore ? (
                <Loader2 className="w-6 h-6 text-sky-400 animate-spin" />
              ) : displayCount < displayedPosts.length ? (
                <button
                  onClick={loadMore}
                  className="px-6 py-2.5 rounded-2xl bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-xs font-bold text-slate-400 hover:text-white transition-all"
                >
                  Carregar mais publicações
                </button>
              ) : null}
            </div>
          </div>
        )}

        {/* ── Scroll to Top Floating Action Button ─────────────────────── */}
        <AnimatePresence>
          {showScrollTop && (
            <motion.button
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.8 }}
              onClick={scrollToTop}
              className="fixed bottom-20 right-6 z-40 w-11 h-11 rounded-2xl bg-slate-900/90 border border-white/[0.1] text-sky-400 shadow-2xl flex items-center justify-center hover:bg-slate-800 transition-all active:scale-90"
              aria-label="Voltar ao topo"
            >
              <ArrowUp className="w-5 h-5 stroke-[2.5px]" />
            </motion.button>
          )}
        </AnimatePresence>
      </div>
    </AppLayout>
  );
}