import { Grid } from "../components/Grid/Grid";
import Typography from "../components/Typography/Typography";
import { motion, AnimatePresence } from "framer-motion";
import { ChevronDownIcon } from "@heroicons/react/24/solid";
import { useState } from "react";
import { useUserProfileStore } from "../context/zustand-store/userStore";
import { getUserPermissions } from "../utils/getUserAvalableItems";
import { ItemWithSubItems } from "../types/userPermissions";
import { useNavigate } from "@tanstack/react-router";
import {
  Bars3Icon,
  QueueListIcon,
  Squares2X2Icon,
} from "@heroicons/react/24/outline";
import { getFaPermissions } from "../utils/getFaPermissions";
import SVGImage from "../components/SvgImage/SvgImage";

const containerVariants = {
  hidden: {},
  visible: {
    transition: {
      staggerChildren: 0.08,
    },
  },
};

const itemVariants = {
  hidden: { opacity: 0, scale: 0.95, y: 20 },
  visible: {
    opacity: 1,
    scale: 1,
    y: 0,
    transition: {
      type: "spring",
      stiffness: 400,
      damping: 20,
    },
  },
};

const submenuVariants = {
  hidden: { height: 0, opacity: 0 },
  visible: {
    height: "auto",
    opacity: 1,
    transition: {
      type: "tween",
      ease: "easeOut",
      duration: 0.1,
    },
  },
  exit: {
    height: 0,
    opacity: 0,
    transition: {
      duration: 0.1,
    },
  },
};

export const Menu = () => {
  const { profile } = useUserProfileStore();

  const menuItems: ItemWithSubItems[] = getUserPermissions(
    profile?.permissions,
  );

  const getOpenedItem = () => {
    if (window.location.pathname !== "/") {
      const matchedIndex = menuItems.findIndex((item) =>
        item.subItems.some((sub) => sub.path === window.location.pathname),
      );
      return matchedIndex;
    } else {
      return null;
    }
  };

  const [openIndex, setOpenIndex] = useState<number | null>(getOpenedItem());
  const [openDomains, setOpenDomains] = useState<Record<string, boolean>>({});
  const navigate = useNavigate();

  const adminItems = menuItems
    .map((item, index) => ({ ...item, originalIndex: index }))
    .filter((item) => item.en === "admin");
  const indexedNonAdminItems = menuItems
    .map((item, index) => ({ ...item, originalIndex: index }))
    .filter((item) => item.en !== "admin");

  const permissionDomainMap = new Map<string, string>();
  (profile?.permissions || []).forEach((permission: any) => {
    if (permission?.page_name) {
      permissionDomainMap.set(
        permission.page_name,
        permission?.domain_fa_name || "سایر حوزه ها",
      );
    }
  });

  const groupedItems = indexedNonAdminItems.reduce(
    (acc, item) => {
      const firstSubItem = item.subItems?.find((sub) =>
        permissionDomainMap.has(sub.name),
      );
      const domainTitle = firstSubItem
        ? permissionDomainMap.get(firstSubItem.name) || "سایر حوزه ها"
        : "سایر حوزه ها";

      if (!acc[domainTitle]) {
        acc[domainTitle] = [];
      }
      acc[domainTitle].push(item);
      return acc;
    },
    {} as Record<
      string,
      (ItemWithSubItems & { originalIndex: number })[]
    >,
  );
  const showDomainGrouping = Object.keys(groupedItems).length > 1;

  const toggleSubmenu = (index: number) => {
    setOpenIndex((prev) => (prev === index ? null : index));
  };

  const isDomainOpen = (domainTitle: string) =>
    openDomains[domainTitle] ?? true;

  const toggleDomain = (domainTitle: string) => {
    setOpenDomains((prev) => ({
      ...prev,
      [domainTitle]: !(prev[domainTitle] ?? true),
    }));
  };

  return (
    <Grid
      container
      column
      className="block md:hidden px-4 pt-6 pb-12 bg-gradient-to-b select-none items-start from-white to-dark-100 dark:from-dark-900 dark:to-dark-800 min-h-screen"
    >
      <Typography
        variant="h6"
        className="text-center gap-2 flex justify-center items-center text-dark-800 dark:text-dark-100 font-semibold text-xl mb-6"
      >
        <Bars3Icon className="w-4" />
        داشبورد
      </Typography>

      <motion.div
        variants={containerVariants}
        initial="hidden"
        animate="visible"
        className="flex flex-col items-center gap-4 w-full"
      >
        {adminItems.map(({ fa, icon: Icon, subItems, originalIndex }) => (
          <motion.div
            key={`admin-${originalIndex}`}
            variants={itemVariants}
            className="w-full max-w-sm"
          >
            <motion.button
              onClick={() => toggleSubmenu(originalIndex)}
              whileTap={{ scale: 0.97 }}
              className="w-full  flex justify-between items-center gap-3 px-4 py-3 rounded-lg shadow-xs dark:shadow-sm shadow-dark-300 dark:shadow-dark-500  backdrop-blur-md bg-gradient-to-r from-transparent to-transparent dark:via-gray-800 via-gray-100 border border-dark-200 dark:border-dark-700 text-dark-800 dark:text-dark-100 transition-all duration-200"
            >
              <div className="flex items-center gap-3">
                <SVGImage
                  src={Icon}
                  className={` text-primary-800 dark:text-primary-100`}
                />

                <span className="text-base font-medium">{fa}</span>
              </div>
              <ChevronDownIcon
                className={`w-5 h-5 text-dark-500 dark:text-dark-300 transition-transform duration-300 ${
                  openIndex === originalIndex ? "rotate-180" : ""
                }`}
              />
            </motion.button>

            <AnimatePresence>
              {openIndex === originalIndex && (
                <motion.div
                  key="submenu"
                  variants={submenuVariants}
                  initial="hidden"
                  animate="visible"
                  exit="exit"
                  className="mt-2 mr-4 border-r-2 border-primary-500 dark:border-primary-400 pr-4 flex flex-col gap-2"
                >
                  {subItems
                    .filter((item) => !item?.path.includes("$"))
                    ?.map((sub, subIndex) => (
                      <motion.button
                        onClick={() => {
                          navigate({ to: sub.path });
                        }}
                        key={subIndex}
                        whileTap={{ scale: 0.97 }}
                        className="text-sm flex items-center gap-2 text-dark-700 dark:text-dark-200 bg-white dark:bg-dark-700 shadow-sm px-3 py-2 rounded-lg w-full text-right"
                      >
                        {" "}
                        <QueueListIcon className="w-3" />
                        {getFaPermissions(sub.name)}
                      </motion.button>
                    ))}
                </motion.div>
              )}
            </AnimatePresence>
          </motion.div>
        ))}

        {showDomainGrouping
          ? Object.entries(groupedItems).map(([domainTitle, domainItems]) => (
              <div key={domainTitle} className="w-full max-w-sm">
                <button
                  onClick={() => toggleDomain(domainTitle)}
                  className="w-full px-1 py-1 text-primary-700 dark:text-primary-200 text-sm font-bold flex items-center justify-between cursor-pointer"
                >
                  <div className="flex items-center gap-2">
                    <Squares2X2Icon className="w-4 h-4 text-primary-600 dark:text-primary-300" />
                    <span>{domainTitle}</span>
                  </div>
                  <ChevronDownIcon
                    className={`w-4 h-4 transition-transform duration-300 ${
                      isDomainOpen(domainTitle) ? "rotate-180" : ""
                    }`}
                  />
                </button>

                {(isDomainOpen(domainTitle) || !domainTitle) && (
                  <div className="mt-1 mr-2 border-r-2 border-primary-200 dark:border-primary-500/40 pr-2 flex flex-col gap-3">
                    {domainItems.map(
                      ({ fa, icon: Icon, subItems, originalIndex }) => (
                        <motion.div
                          key={`group-${domainTitle}-${originalIndex}`}
                          variants={itemVariants}
                          className="w-full"
                        >
                          <motion.button
                            onClick={() => toggleSubmenu(originalIndex)}
                            whileTap={{ scale: 0.97 }}
                            className="w-full  flex justify-between items-center gap-3 px-4 py-3 rounded-lg shadow-xs dark:shadow-sm shadow-dark-300 dark:shadow-dark-500  backdrop-blur-md bg-gradient-to-r from-transparent to-transparent dark:via-gray-800 via-gray-100 border border-dark-200 dark:border-dark-700 text-dark-800 dark:text-dark-100 transition-all duration-200"
                          >
                            <div className="flex items-center gap-3">
                              <SVGImage
                                src={Icon}
                                className={` text-primary-800 dark:text-primary-100`}
                              />
                              <span className="text-base font-medium">{fa}</span>
                            </div>
                            <ChevronDownIcon
                              className={`w-5 h-5 text-dark-500 dark:text-dark-300 transition-transform duration-300 ${
                                openIndex === originalIndex ? "rotate-180" : ""
                              }`}
                            />
                          </motion.button>

                          <AnimatePresence>
                            {openIndex === originalIndex && (
                              <motion.div
                                key="submenu"
                                variants={submenuVariants}
                                initial="hidden"
                                animate="visible"
                                exit="exit"
                                className="mt-2 mr-4 border-r-2 border-primary-500 dark:border-primary-400 pr-4 flex flex-col gap-2"
                              >
                                {subItems
                                  .filter((item) => !item?.path.includes("$"))
                                  ?.map((sub, subIndex) => (
                                    <motion.button
                                      onClick={() => {
                                        navigate({ to: sub.path });
                                      }}
                                      key={subIndex}
                                      whileTap={{ scale: 0.97 }}
                                      className="text-sm flex items-center gap-2 text-dark-700 dark:text-dark-200 bg-white dark:bg-dark-700 shadow-sm px-3 py-2 rounded-lg w-full text-right"
                                    >
                                      <QueueListIcon className="w-3" />
                                      {getFaPermissions(sub.name)}
                                    </motion.button>
                                  ))}
                              </motion.div>
                            )}
                          </AnimatePresence>
                        </motion.div>
                      ),
                    )}
                  </div>
                )}
              </div>
            ))
          : indexedNonAdminItems.map(
              ({ fa, icon: Icon, subItems, originalIndex }) => (
                <motion.div
                  key={`plain-${originalIndex}`}
                  variants={itemVariants}
                  className="w-full max-w-sm"
                >
                  <motion.button
                    onClick={() => toggleSubmenu(originalIndex)}
                    whileTap={{ scale: 0.97 }}
                    className="w-full  flex justify-between items-center gap-3 px-4 py-3 rounded-lg shadow-xs dark:shadow-sm shadow-dark-300 dark:shadow-dark-500  backdrop-blur-md bg-gradient-to-r from-transparent to-transparent dark:via-gray-800 via-gray-100 border border-dark-200 dark:border-dark-700 text-dark-800 dark:text-dark-100 transition-all duration-200"
                  >
                    <div className="flex items-center gap-3">
                      <SVGImage
                        src={Icon}
                        className={` text-primary-800 dark:text-primary-100`}
                      />

                      <span className="text-base font-medium">{fa}</span>
                    </div>
                    <ChevronDownIcon
                      className={`w-5 h-5 text-dark-500 dark:text-dark-300 transition-transform duration-300 ${
                        openIndex === originalIndex ? "rotate-180" : ""
                      }`}
                    />
                  </motion.button>

                  <AnimatePresence>
                    {openIndex === originalIndex && (
                      <motion.div
                        key="submenu"
                        variants={submenuVariants}
                        initial="hidden"
                        animate="visible"
                        exit="exit"
                        className="mt-2 mr-4 border-r-2 border-primary-500 dark:border-primary-400 pr-4 flex flex-col gap-2"
                      >
                        {subItems
                          .filter((item) => !item?.path.includes("$"))
                          ?.map((sub, subIndex) => (
                            <motion.button
                              onClick={() => {
                                navigate({ to: sub.path });
                              }}
                              key={subIndex}
                              whileTap={{ scale: 0.97 }}
                              className="text-sm flex items-center gap-2 text-dark-700 dark:text-dark-200 bg-white dark:bg-dark-700 shadow-sm px-3 py-2 rounded-lg w-full text-right"
                            >
                              <QueueListIcon className="w-3" />
                              {getFaPermissions(sub.name)}
                            </motion.button>
                          ))}
                      </motion.div>
                    )}
                  </AnimatePresence>
                </motion.div>
              ),
            )}
      </motion.div>
    </Grid>
  );
};
