"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 { useRouter } from "next/navigation";
import { Option } from "@/src/utils/types";
import { useGetInputData } from "@/src/utils/hooks/useGetInputData";
import NoMatchFound from "@/src/components/reusables/NoMatchFound";
import Popup from "@/src/components/admin/settings/popup";
import { toast } from "react-toastify";
import LoadingSpinner from "@/src/components/reusables/ui/LoadingSpinner";
import AuthGuard from "@/src/components/reusables/auth";
import axiosInstance from "@/lib/axios";
import { usePathname } from "next/navigation";
import { setAvaliableTry, setTryCount } from "@/src/redux/authSlice";
import Image from "next/image";
import { X } from "lucide-react";

export default function Home() {
  const dispatch = useAppDispatch();
  const searchValue = useAppSelector(
    (state: RootState) => state.counter.search
  );
  const filterValues = useAppSelector((state) => state.counter.filterValues);
  const { data: userProfileData, refetch: refetchProfile } =
    useGetUserProfile();

  const router = useRouter();

  // State
  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 [isAccountDeleted, setIsAccountDeleted] = useState<any>(null);
  const [showPopup, setShowPopup] = useState(false);
  const [loading, setLoading] = useState(false);
  const [dashboardCount, setDashboardCount] = useState<number>(() => {
    const stored = localStorage.getItem("dashboardCount");
    return stored ? Number(stored) : 0;
  });

  const isLoggedIn = useAppSelector(
    (state: RootState) => state.auth.isLoggedIn
  );

  const isBiodataSetup = useAppSelector((state) => state.auth.isBioDataSetup);
  const isPersonalSetup = useAppSelector((state) => state.auth.isPersonalSetup);
  const isContactSetup = useAppSelector((state) => state.auth.isContactSetup);
  const isHobbiesSetup = useAppSelector((state) => state.auth.isHobbiesSetup);

  useEffect(() => {
    if (
      !isBiodataSetup ||
      !isPersonalSetup ||
      !isContactSetup ||
      !isHobbiesSetup
    ) {
      router.push("/user/profile-setup");
    } else {
      router.push("/user/dashboard");
    }
  }, [isBiodataSetup, isPersonalSetup, isContactSetup, isHobbiesSetup]);

  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 [shouldRefresh, setShouldRefresh] = useState(false);

  // 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 } = useGetAllMatches(
    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));

      const isDeleted = userProfileData.payload.is_account_deleted;
      setIsAccountDeleted(isDeleted);

      if (isDeleted === false) {
        setShowPopup(false);
      } else {
        if (dashboardCount && dashboardCount === 1) {
          setShowPopup(true);
        } else {
          setShowPopup(false);
        }
      }
    }
  }, [userProfileData, dispatch, dashboardCount]);

  // 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]);

  const handleActivateAccount = async () => {
    try {
      if (typeof window === "undefined") return;

      const userId = localStorage.getItem("userId");

      if (!userId) {
        return;
      }

      setLoading(true);

      const response = await axiosInstance.post(`/account/cancel-deletion`, {});

      setLoading(false);
      toast.success("Account Activated Successfully");
      refetchProfile();
    } catch (error) {
      setLoading(false);
    }
  };

  const pathname = usePathname();
  useEffect(() => {
    if (
      pathname.startsWith("/user/dashboard") &&
      isLoggedIn &&
      dashboardCount !== null
    ) {
      const newCount = dashboardCount + 1;
      setDashboardCount(newCount);
      localStorage.setItem("dashboardCount", String(newCount));
    }
  }, [pathname, isLoggedIn]);

  const { data: profile } = useGetUserProfile();
  const tryCount = useAppSelector((state) => state.auth.tryCount);
  const avaliableTry = useAppSelector((state) => state.auth.avaliableTry);

  useEffect(() => {
    if (profile?.payload) {
      dispatch(setTryCount(profile.payload.available_retry));
    }
  }, [profile]);

  useEffect(() => {
    localStorage.setItem('relationshipType', relationshipType)
  }, [relationshipType]);

  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="md: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>

        {/* 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 && (
          <span className="text-center text-sm text-gray-500 mt-10">
            <NoMatchFound />
          </span>
        )}

        {/* 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>
        )}

        {showPopup && (
          <div className="fixed inset-0 flex items-center justify-center bg-black/50 z-50">
            <div
              className="bg-white rounded-lg border border-gray-200 shadow-lg w-full max-w-md p-6 relative"
              onClick={(e) => e.stopPropagation()}
            >
              <div className="border-b pb-2 mb-4">
                <h2 className="text-sm font-semibold text-gray-800">
                  REMINDER
                </h2>
              </div>

              <p className="text-red-600 font-bold text-lg mb-2">
                {isAccountDeleted} DAYS LEFT
              </p>

              <p className="text-sm text-gray-700 mb-6">
                You will not be able to login your account after the 2nd day of
                marking your account for deactivation
              </p>

              <div className="flex justify-end gap-3">
                <button
                  onClick={() => handleActivateAccount()}
                  className="bg-red-600 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-red-700"
                >
                  {loading ? <LoadingSpinner /> : "Reactivate"}
                </button>
                <button
                  onClick={() => setShowPopup(false)}
                  className="border border-red-600 text-red-600 px-4 py-2 rounded-full text-sm font-medium hover:bg-red-50"
                >
                  Close
                </button>
              </div>
            </div>
          </div>
        )}

        {avaliableTry && tryCount > 0 && (
          <div
            onClick={() => {
              dispatch(setAvaliableTry(false));
            }}
            className="fixed inset-0 bg-black/40 backdrop-blur-md flex items-center justify-center z-50"
          >
            {/* Modal Box */}
            <div
              onClick={(e) => e.stopPropagation()}
              className="bg-white rounded-lg p-6 w-[90%] max-w-md relative shadow-lg"
            >
              {/* Cancel Icon */}
              <button
                onClick={() => {
                  dispatch(setAvaliableTry(false));
                }}
                className="absolute top-4 right-4 text-gray-500 hover:text-gray-700 transition"
                aria-label="Close"
              >
                <X className="w-5 h-5" />
              </button>

              <div className="flex items-center justify-center flex-col gap-4">
                <Image
                  src="/images/Commercial.svg"
                  alt="commercial"
                  className="object-cover"
                  width={60}
                  height={60}
                />
                <h3 className="font-[600]">NOTICE</h3>
                <p className="text-center">
                  You now have <span className="font-bold"> {tryCount}</span>{" "}
                  free subscription to show interest in any user of your choice.
                  Please endeavour to use this subscription as soon as possible
                </p>
              </div>
            </div>
          </div>
        )}
      </section>
    </AuthGuard>
  );
}
