import React, { useState, useEffect } from "react";
import Image from "next/image";
import { BellRing, CheckCheck, ThumbsUp, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { motion, AnimatePresence } from "framer-motion";
import Overlay from "../overlay/overlay";
import { useScreenSizeContext } from "@/src/utils/providers/screenSizesContext";
import { useAppDispatch, useAppSelector } from "@/src/redux/hook";
import { setPreviewSrc, setProfilePicture } from "@/src/redux/profileSlice";
import {
  useGetLatestNotifications,
  useMarkNotificationRead,
  useClearNotifications,
  useClearNotification,
} from "@/src/utils/hooks/useGetNotifications";
import LoadingSpinner from "../ui/LoadingSpinner";
import SectionSkeleton from "../ui/Loading";

interface Notification {
  id: string;
  message: string;
  read_at: string | null;
}

export default function Notification() {
  const [notificationModal, setNotificationModal] = useState<boolean>(false);
  const { isMobile, isDesktop, isTablet } = useScreenSizeContext();
  const [allUnread, setAllUnread] = useState<Notification[]>([]);
  const [allNotifications, setAllNotifications] = useState<Notification[]>([]);
  const [showAll, setShowAll] = useState<boolean>(false);
  const [showButton, setShowButon] = useState<boolean>(false);

  const handleBellIconClick = () => {
    setNotificationModal(!notificationModal);
  };

  const dispatch = useAppDispatch();

  const {
    data: latestNotifications,
    isLoading,
    refetch,
  } = useGetLatestNotifications();

  const { mutate: markAsRead, isPending: markReadLoading } =
    useMarkNotificationRead();

  const { mutate: clearAllNotifications, isPending: clearLoading } =
    useClearNotifications();

  const { mutate: clearAllNotification, isPending: clearSingleLoading } =
    useClearNotification();

  useEffect(() => {
    const notificationPayloads = latestNotifications?.payload;

    if (notificationPayloads) {
      const unread = notificationPayloads.filter(
        (item: any) => item.read_at === null
      );

      const unreadNotifications = unread.map((item: any) => ({
        id: item.id,
        message: item.data?.message || "",
        read_at: item.read_at,
      }));

      setAllUnread(unreadNotifications);

      const all = notificationPayloads.map((item: any) => ({
        id: item.id,
        message: item.data?.message || "",
        read_at: item.read_at,
      }));

      setAllNotifications(all);
    }

    const containsRead = notificationPayloads?.find(
      (item: any) => item.read_at !== null
    );

    if (containsRead) {
      setShowButon(true);
    }
  }, [latestNotifications]);

  useEffect(() => {
    const handleOutsideClick = (e: MouseEvent) => {
      const notification_modal = document.getElementById("notification_modal");
      const notification_icon = document.getElementById("notification_icon");
      if (
        notification_modal &&
        !notification_modal.contains(e.target as Node) &&
        notification_icon &&
        !notification_icon.contains(e.target as Node)
      ) {
        setNotificationModal(false);
      }
    };

    document.addEventListener("mousedown", handleOutsideClick);

    if (notificationModal) {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "auto";
    }

    return () => {
      document.removeEventListener("mousedown", handleOutsideClick);
      document.body.style.overflow = "auto";
    };
  }, [notificationModal]);

  const handleMarkAsRead = (id: string) => {
    markAsRead(id);
  };

  const handleClearNotification = (id: string[]) => {
    console.log("Clearing notification:", id);
    clearAllNotification(id);
  };

  const handleClearAllNotifications = () => {
    const notificationsToShow = showAll ? allNotifications : allUnread;
    const ids = notificationsToShow.map((notification) => notification.id);
    clearAllNotifications(ids);
  };

  const notificationVariants = {
    hidden: {
      x: 300,
      opacity: 0,
    },
    visible: {
      x: 0,
      opacity: 1,
      transition: {
        type: "spring" as const,
        stiffness: 100,
        damping: 20,
        duration: 0.6,
      },
    },
    exit: {
      x: 300,
      opacity: 0,
      transition: {
        duration: 0.5,
        ease: "easeInOut" as const,
      },
    },
  };

  const listVariants = {
    hidden: { opacity: 0 },
    visible: {
      opacity: 1,
      transition: {
        staggerChildren: 0.08,
        delayChildren: 0.2,
      },
    },
  };

  const profilePicture = useAppSelector(
    (state) => state.profile.profilePicture
  );
  const userProfile = useAppSelector((state) => state.profile.userProfile);

  const previewSrc = useAppSelector((state) => state.profile.previewSrc);

  useEffect(() => {
    let objectUrl: string | undefined;

    if (profilePicture instanceof File) {
      objectUrl = URL.createObjectURL(profilePicture);
      dispatch(setPreviewSrc(objectUrl));
    } else if (
      typeof profilePicture === "string" &&
      profilePicture.trim() !== ""
    ) {
      dispatch(setPreviewSrc(profilePicture));
    } else if (
      typeof userProfile?.photo === "string" &&
      userProfile.photo.trim() !== ""
    ) {
      dispatch(setPreviewSrc(userProfile.photo));
    } else {
      dispatch(setPreviewSrc(undefined));
    }

    return () => {
      if (objectUrl) {
        URL.revokeObjectURL(objectUrl);
      }
    };
  }, [profilePicture, userProfile]);

  const renderNotificationItem = (item: Notification) => (
    <div
      className="w-full p-2 hover:bg-[#D9D9D9C4] bg-white text-black overflow-hidden break-words cursor-pointer rounded-sm relative group"
      key={item.id}
    >
      <div className="pr-10">{item.message}</div>

      {/* notification action buttons */}
      <div className="absolute bottom-1 right-1 flex gap-1 lg:opacity-0 lg:group-hover:opacity-100 transition-opacity duration-200">
        {item.read_at === null && (
          <div className="relative group/tooltip">
            <button
              onClick={(e) => {
                e.stopPropagation();
                handleMarkAsRead(item.id);
              }}
              className="p-1 hover:bg-green-100 rounded transition-colors duration-200 cursor-pointer"
              title="Mark as read"
            >
              {markReadLoading ? (
                <LoadingSpinner />
              ) : (
                <CheckCheck className="w-5 h-4 text-green-600" />
              )}
            </button>
            <div className="absolute bottom-full right-0 mb-1 px-2 py-1 text-xs bg-gray-800 text-white rounded opacity-0 group-hover/tooltip:opacity-100 transition-opacity duration-200 whitespace-nowrap pointer-events-none z-50">
              Mark as read
            </div>
          </div>
        )}

        <div className="relative group/tooltip">
          <button
            onClick={(e) => {
              e.stopPropagation();
              handleClearNotification(Array(item.id));
            }}
            className="p-1 hover:bg-red-100 rounded transition-colors duration-200 cursor-pointer"
            title="Clear notification"
          >
            {clearSingleLoading ? (
              <LoadingSpinner />
            ) : (
              <Trash2 className="w-5 h-4 text-[#EF2424]" />
            )}
          </button>
          <div className="absolute bottom-full right-0 mb-1 px-2 py-1 text-xs bg-gray-800 text-white rounded opacity-0 group-hover/tooltip:opacity-100 transition-opacity duration-200 whitespace-nowrap pointer-events-none z-50">
            Clear notification
          </div>
        </div>
      </div>
    </div>
  );

  return (
    <div className="flex gap-x-4 items-center max-sm:px-0 font-[600] text-[10px] md:mr-4 mr-8">
      {(isMobile || isDesktop || isTablet) && (
        <motion.div
          animate={
            allUnread.length > 0
              ? { rotate: [0, -20, 20, -10, 10, -5, 5, 0] }
              : {}
          }
          transition={{ duration: 0.8, repeat: Infinity, repeatDelay: 4 }}
          onClick={handleBellIconClick}
          className="relative cursor-pointer"
        >
          <BellRing className="text-[#EF2424]" fill="#EF2424" />
          {allUnread.length > 0 && (
            <span className="absolute top-0 right-1 bg-red-600 text-white text-[10px] rounded-full px-1">
              {allUnread.length}
            </span>
          )}
        </motion.div>
      )}

      {isDesktop && previewSrc && (
        <div className="w-[3.5rem] h-[3.5rem] rounded-full relative flex items-center">
          <Image
            src={previewSrc}
            alt="profile"
            className="rounded-full object-cover"
            fill
          />
        </div>
      )}

      <AnimatePresence>
        {notificationModal && (
          <>
            <Overlay func={handleBellIconClick} />

            {isLoading ? (
              <SectionSkeleton />
            ) : (
              <motion.div
                id="notification_modal"
                className="flex flex-col lg:w-[280px] w-[280px] fixed right-[5%] lg:top-[12%] md:top-[8%] top-[5%] bg-white text-black max-h-[500px] max-w-[194px] px-2 overflow-y-auto z-30 border border-[#E2E2E2] shadow-md"
                initial="hidden"
                animate="visible"
                exit="exit"
                variants={notificationVariants}
              >
                <div className="w-full flex flex-col gap-y-4 justify-center">
                  {/* Clear All button */}
                  {(showAll ? allNotifications : allUnread).length > 0 && (
                    <motion.div
                      initial={{ opacity: 0 }}
                      animate={{ opacity: 1 }}
                      transition={{ delay: 0.2, duration: 0.3 }}
                      className="pt-2"
                    >
                      <Button
                        onClick={handleClearAllNotifications}
                        className="w-full bg-[#EF2424] hover:bg-[#EF2424]/85 text-white text-xs py-1 h-8 cursor-pointer"
                      >
                        Clear All {showAll ? "Notifications" : "Unread"}{" "}
                        {clearLoading && (
                          <span className="ml-2">
                            <LoadingSpinner />
                          </span>
                        )}
                      </Button>
                    </motion.div>
                  )}

                  {(showAll ? allNotifications : allUnread).length > 0 ? (
                    <motion.div
                      className="w-full gap-y-2 flex flex-col my-2"
                      role="button"
                      variants={listVariants}
                      initial="hidden"
                      animate="visible"
                    >
                      {showAll
                        ? allNotifications?.map((item) =>
                            renderNotificationItem(item)
                          )
                        : allUnread?.map((item) =>
                            renderNotificationItem(item)
                          )}
                    </motion.div>
                  ) : (
                    <div className="w-full gap-y-2 flex flex-col my-2 justify-center items-center py-10">
                      <span>
                        <ThumbsUp size={40} className="text-green-600" />
                      </span>
                      <p className="mt-2 font-semibold">All Good Here</p>
                      <p className="text-xs text-[#E2E2E2]">
                        No new notifications available
                      </p>
                    </div>
                  )}
                </div>

                {showButton && (
                  <motion.div
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    transition={{ delay: 0.5, duration: 0.5 }}
                    className="px-0 mx-0"
                  >
                    <Button
                      onClick={() => setShowAll(!showAll)}
                      className="w-full bg-[#E2E2E2] hover:bg-[#E2E2E2]/85 text-black hover:text-black/85 cursor-pointer text-ellipsis overflow-hidden whitespace-nowrap rounded-none mb-2"
                    >
                      {showAll
                        ? "See Unread Notifications"
                        : "See All Notifications"}
                    </Button>
                  </motion.div>
                )}
              </motion.div>
            )}
          </>
        )}
      </AnimatePresence>
    </div>
  );
}
