/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";
import ChevronDownIcon from "./icons/ChevronDownIcon";
import ChevronUpIcon from "./icons/ChevronUpIcon";
import clsx from "clsx";
import CloseIcon from "./icons/CloseIcon";
import Button from "./Button";
import CheckIcon from "./icons/CheckIcon";
import { useClickAway } from "@uidotdev/usehooks";
import { AnimatePresence, motion } from "motion/react";

function MultySelect<T extends { name: string; id: string }>({
  data,
  isGrid,
  placeholder,
  resetTitle,
  onSelect,
  reset,
}: {
  data: T[];
  isGrid: boolean;
  placeholder: string;
  resetTitle: string;
  onSelect: (values: T[]) => void;
  reset?: boolean;
}) {
  const [selectedValues, setSelectedValues] = useState<T[]>([]);
  const [isSelectVisible, setIsSelectVisible] = useState(false);

  const selectRef = useClickAway<HTMLDivElement>(() => {
    setIsSelectVisible(false);
  });

  useEffect(() => {
    if (reset) {
      setSelectedValues([]);
    }
  }, [reset]);

  useEffect(() => {
    onSelect(selectedValues);
  }, [selectedValues]);

  const handleSelectClick = (item: T) => {
    const isItemSelected = selectedValues.some((val) => val.id === item.id);

    if (isItemSelected) {
      setSelectedValues((prev) => prev.filter((value) => value.id !== item.id));
    } else {
      setSelectedValues((prev) => [...prev, item]);
    }
  };

  return (
    <div
      className="relative w-[19.583vw] bg-[#F6F6F6] rounded-[0.833vw] select-none"
      ref={selectRef}
    >
      <div
        className={clsx(
          "flex items-center justify-between px-[1.111vw] py-[1.285vw] hover:bg-[#F0F0F0] rounded-[0.833vw] cursor-pointer",
          isSelectVisible && "!bg-[#E1DEFC] !text-[#7B60F3] hover:bg-[#E1DEFC]"
        )}
        onClick={() => setIsSelectVisible(!isSelectVisible)}
      >
        <div className="button-m font-medium text-ellipsis line-clamp-1 flex-1">
          {selectedValues.length > 0
            ? selectedValues.map(({ name }) => name).join(", ")
            : placeholder}
        </div>
        <span
          className={clsx(
            "w-[1.389vw] h-[1.389vw] flex items-center justify-center",
            isSelectVisible ? "text-[#7B60F3]" : "text-[#7D7D7D]"
          )}
        >
          {isSelectVisible ? <ChevronUpIcon /> : <ChevronDownIcon />}
        </span>
      </div>
      <AnimatePresence>
        {isSelectVisible && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="absolute top-[calc(100%+0.278vw)] flex flex-col gap-[0.278vw] rounded-[0.833vw] w-full bg-white z-1"
          >
            <div
              className="flex flex-col gap-[0.278vw] px-[0.833vw] pb-[0.833vw] w-full bg-white rounded-[0.833vw] max-h-[13.889vw] overflow-auto"
              style={{
                boxShadow:
                  "0px 4px 40px 0px #0000000D, 0px 2px 2px 0px #0000000D",
              }}
            >
              <div className="bg-white sticky top-0 pt-[0.833vw] z-1">
                <Button
                  variant="secondary"
                  className="!justify-start w-full text-s font-medium p-[0.833vw] text-[#7D7D7D] flex items-center gap-[0.278vw] cursor-pointer rounded-[0.278vw] hover:bg-[#F6F6F6] bg-white"
                  onClick={() => setSelectedValues([])}
                >
                  <span className="size-[1.111vw] flex items-center justify-center">
                    <CloseIcon />
                  </span>
                  {resetTitle}
                </Button>
              </div>
              <div className="min-h-[1px] w-full bg-[#F6F6F6]" />
              {isGrid ? (
                <div className="grid grid-cols-3 gap-[0.139vw]">
                  {data.map((item) => (
                    <div
                      key={item.id}
                      className="p-[0.556vw] flex flex-col gap-[0.278vw] justify-center items-center cursor-pointer rounded-[0.278vw] hover:bg-[#F6F6F6]"
                      onClick={() => handleSelectClick(item)}
                    >
                      <div className="relative size-[2.222vw] rounded-full bg-[#d4d4d4]">
                        {selectedValues
                          .map((value) => value.id)
                          .includes(item.id) && (
                          <span className="absolute bottom-[1.389vw] left-[1.389vw] rounded-full size-[1.111vw] bg-[#7B60F3] text-white flex items-center justify-center">
                            <div className="size-[0.833vw]">
                              <CheckIcon />
                            </div>
                          </span>
                        )}
                      </div>
                      <p className="text-s font-medium">{item.name}</p>
                    </div>
                  ))}
                </div>
              ) : (
                <>
                  {data.map((item) => (
                    <div
                      key={item.id}
                      className="flex gap-[0.278vw] w-full p-[0.833vw] text-s rounded-[0.278vw] hover:bg-[#F6F6F6] cursor-pointer"
                      onClick={() => handleSelectClick(item)}
                    >
                      <div className="size-[1.111vw]">
                        {selectedValues
                          .map((value) => value.id)
                          .includes(item.id) && (
                          <span className="text-[#7B60F3]">
                            <CheckIcon />
                          </span>
                        )}
                      </div>
                      {item.name}
                    </div>
                  ))}
                </>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

export default MultySelect;
