"use client";

import { useState, useEffect, useCallback, useMemo } from "react";
import { useGetAllMatches } from "@/src/utils/hooks/useGetMatches";
import MatchCard from "@/src/components/reusables/MatchCard";
import MatchCardSkeleton from "@/src/components/reusables/MatchCardSkeleton";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useGetUserProfile } from "@/src/utils/hooks/useGetUserProfile";
import { useAppDispatch, useAppSelector } from "@/src/redux/hook";
import { setAboutMe, setUserProfile } from "@/src/redux/profileSlice";
import { RootState } from "@/src/redux/store";
import { useGetFavorites } from "@/src/utils/hooks/useGetFavorites";
import { useRouter } from "next/navigation";
import { useGetInputData } from "@/src/utils/hooks/useGetInputData";
import { Option } from "@/src/utils/types";
import NoMatchFound from "@/src/components/reusables/NoMatchFound";
import { useGetIntrested } from "@/src/utils/hooks/useGetInterested";
import AuthGuard from "@/src/components/reusables/auth";

export default function FavoritesPage() {
  const [relationshipType, setRelationshipType] = useState("Marriage");
  const [currentPage, setCurrentPage] = useState(1);
  const [allMatches, setAllMatches] = useState<any[]>([]);
  const [hasMore, setHasMore] = useState(true);
  const [isLoadingMore, setIsLoadingMore] = useState(false);
  const [shouldRefresh, setShouldRefresh] = useState(false);

  const dispatch = useAppDispatch();
  const searchValue = useAppSelector(
    (state: RootState) => state.counter.search
  );
  const filterValues = useAppSelector((state) => state.counter.filterValues);
  const { data: userProfileData } = useGetUserProfile();

  const useInputOptions = (
    keys: string[]
  ): { key: string; options: Option[]; rawValue?: any }[] => {
    return keys.map((key) => {
      const { data } = useGetInputData(key);
      const options: Option[] = data?.payload?.value || [];
      return { key, options };
    });
  };

  const inputKeys: string[] = ["relationship_type"];
  const inputOptions = useInputOptions(inputKeys);
  const relationshipOptions: any =
    inputOptions.find((o) => o.key === "relationship_type")?.options || [];

  const router = useRouter();

  // Combine filters and search
  const filters = useMemo(
    () => ({
      ...Object.fromEntries(
        Object.entries(filterValues).filter(([_, v]) => v !== "")
      ),
      relationship_type: relationshipType,
      ...(searchValue ? { search: searchValue } : {}),
    }),
    [relationshipType, filterValues, searchValue]
  );

  // Fetch matches for current page
  const { data, isLoading, isFetching, refetch } = useGetIntrested(
    filters,
    currentPage
  );

  // Scroll-based infinite scroll
  const handleScroll = useCallback(() => {
    // Check if we're near the bottom of the page
    const scrollTop =
      document.documentElement.scrollTop || document.body.scrollTop;
    const scrollHeight =
      document.documentElement.scrollHeight || document.body.scrollHeight;
    const clientHeight =
      document.documentElement.clientHeight || window.innerHeight;

    const scrolledToBottom = scrollTop + clientHeight >= scrollHeight - 1000; // 1000px threshold

    if (
      scrolledToBottom &&
      hasMore &&
      !isLoading &&
      !isFetching &&
      !isLoadingMore
    ) {
      console.log("Loading more - current page:", currentPage);
      setIsLoadingMore(true);
      setCurrentPage((prev) => prev + 1);
    }
  }, [hasMore, isLoading, isFetching, isLoadingMore, currentPage]);

  // Add scroll listener with proper cleanup
  useEffect(() => {
    const throttledHandleScroll = throttle(handleScroll, 200);
    window.addEventListener("scroll", throttledHandleScroll, { passive: true });
    return () => window.removeEventListener("scroll", throttledHandleScroll);
  }, [handleScroll]);

  // Throttle function
  function throttle(func: Function, delay: number) {
    let timeoutId: NodeJS.Timeout;
    let lastExecTime = 0;
    return function (this: any, ...args: any[]) {
      const currentTime = Date.now();

      if (currentTime - lastExecTime > delay) {
        func.apply(this, args);
        lastExecTime = currentTime;
      } else {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(
          () => {
            func.apply(this, args);
            lastExecTime = Date.now();
          },
          delay - (currentTime - lastExecTime)
        );
      }
    };
  }

  // Reset function for filters/search changes
  const resetData = useCallback(() => {
    setAllMatches([]);
    setCurrentPage(1);
    setHasMore(true);
    setIsLoadingMore(false);
  }, []);

  // Detect when page becomes visible again
  useEffect(() => {
    const handleVisibility = () => {
      if (document.visibilityState === "visible") {
        setShouldRefresh(true);
      }
    };

    const handleFocus = () => {
      // When user navigates back to the page, ensure we have data
      if (allMatches.length === 0 && !isLoading) {
        refetch();
      }
    };

    document.addEventListener("visibilitychange", handleVisibility);
    window.addEventListener("focus", handleFocus);

    return () => {
      document.removeEventListener("visibilitychange", handleVisibility);
      window.removeEventListener("focus", handleFocus);
    };
  }, [allMatches.length, isLoading, refetch]);

  // Handle refresh when page becomes visible
  useEffect((): (() => void) | void => {
    if (shouldRefresh) {
      resetData();
      const timer = setTimeout(() => {
        refetch();
      }, 150);
      setShouldRefresh(false);
      return () => clearTimeout(timer);
    }
  }, [shouldRefresh, refetch, resetData]);

  // Handle initial load when returning to page
  useEffect(() => {
    // If we have no matches but data is available, initialize
    if (
      !isLoading &&
      !isFetching &&
      data?.payload?.matches &&
      allMatches.length === 0
    ) {
      setAllMatches(data.payload.matches);
      setHasMore(Boolean(data.payload.pagination?.has_more));
    }
  }, [data, allMatches.length, isLoading, isFetching]);

  // Update user profile redux state
  useEffect(() => {
    if (userProfileData?.payload) {
      dispatch(setUserProfile(userProfileData.payload));
      dispatch(setAboutMe(userProfileData.payload.about_me));
    }
  }, [userProfileData, dispatch]);

  // Reset when filters change
  useEffect(() => {
    resetData();
  }, [relationshipType, filterValues, searchValue, resetData]);

  // Handle new data
  useEffect(() => {
    console.log("Data effect triggered:", {
      hasData: !!data?.payload?.matches,
      matchesCount: data?.payload?.matches?.length,
      currentPage,
      existingMatches: allMatches.length,
    });

    if (data?.payload?.matches) {
      const newMatches = data.payload.matches;

      setAllMatches((prevMatches) => {
        if (currentPage === 1) {
          console.log("Setting first page matches:", newMatches.length);
          return newMatches;
        } else {
          // Subsequent pages - append only new unique matches
          const existingIds = new Set(prevMatches.map((m) => m.user.id));
          const uniqueMatches = newMatches.filter(
            (match: any) => !existingIds.has(match.user.id)
          );
          console.log(
            "Appending matches:",
            uniqueMatches.length,
            "to existing:",
            prevMatches.length
          );
          return [...prevMatches, ...uniqueMatches];
        }
      });

      // Update pagination state
      const hasMoreData = Boolean(data.payload.pagination?.has_more);
      console.log("Setting hasMore:", hasMoreData);
      setHasMore(hasMoreData);
      setIsLoadingMore(false);
    }
  }, [data, currentPage]);

  // Handle empty search
  useEffect(() => {
    if (searchValue === "") {
      resetData();
    }
  }, [searchValue, resetData]);

  return (
    <AuthGuard>
      <section className="container mx-auto px-4 py-6 max-w-[90%] md:-mt-[80px]">
        {/* Relationship Type Filter */}
        <div className="sticky top-0 z-10 bg-[#F6F6F6] py-4 mb-6 flex flex-row max-md:flex-col max-md:gap-y-2 max-md:items-start items-center">
          <label className="mr-2 font-medium">Relationship Type:</label>
          <Select value={relationshipType} onValueChange={setRelationshipType}>
            <SelectTrigger className="w-[180px] bg-white">
              <SelectValue placeholder="Select type" />
            </SelectTrigger>
            <SelectContent>
              {relationshipOptions.map((option: string) => (
                <SelectItem key={option} value={option}>
                  {option}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <h2 className="font-bold text-[16px] mb-4">Interested in me</h2>

        {/* Matches Grid */}
        <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
          {allMatches.map((match, index) => (
            <MatchCard key={`${match.user.id}-${index}`} match={match} />
          ))}

          {/* Loading skeletons for initial load */}
          {isLoading &&
            currentPage === 1 &&
            Array.from({ length: 10 }).map((_, i) => (
              <MatchCardSkeleton key={`skeleton-initial-${i}`} />
            ))}

          {/* Loading skeletons for infinite scroll */}
          {isLoadingMore &&
            Array.from({ length: 5 }).map((_, i) => (
              <MatchCardSkeleton key={`skeleton-more-${i}`} />
            ))}
        </div>

        {/* No matches message */}
        {allMatches.length === 0 && !isLoading && !isFetching && (
          <p className="text-center text-sm text-gray-500 mt-10">
            <NoMatchFound />
          </p>
        )}

        {/* Loading more indicator */}
        {isLoadingMore && (
          <div className="text-center text-sm text-gray-500 mt-8 py-4">
            Loading more matches...
          </div>
        )}

        {/* End of results indicator */}
        {allMatches.length > 0 && !hasMore && !isLoading && !isFetching && (
          <div className="text-center text-sm text-gray-500 mt-8 py-4">
            You've reached the end of the matches
          </div>
        )}
      </section>
    </AuthGuard>
  );
}
