import React, { useEffect, useState, useRef } from "react";
//icons
import ArrowLight from "../../assets/icons/arrowLight.svg";
import ArrowDark from "../../assets/icons/arrowDark.svg";
import CloseIconLight from "../../assets/icons/xCircleLight.svg";
import CloseIconDark from "../../assets/icons/xCircleDark.svg";
import CleanIconLight from "../../assets/icons/xCircleOutlinedLight.svg";
import CleanIconDark from "../../assets/icons/xCircleOutlinedDark.svg";

import Image from "next/image";

import styles from "./Dropdown.module.scss";

type DropdownT = {
  id: string;
  handleSelect: (e: any) => void;
  handleCleanValues?: () => void;
  theme?: "light" | "dark";
  placeholder?: string;
  title: string;
  options: Array<string | number>;
  devalultValues?: Array<string | number>;
  errorText?: string;
  showCleanButton?: boolean;
  useSingleValue?: boolean;
  disabled?: boolean;
};

const Dropdown = (props: DropdownT) => {
  const {
    id,
    handleSelect,
    handleCleanValues,
    theme = "light",
    placeholder = "Choose the option",
    title,
    options,
    devalultValues = [],
    errorText,
    showCleanButton,
    useSingleValue,
    disabled,
  } = props;

  const [isOpen, setIsOpen] = useState<boolean>(false);
  const [selectedOptions, setSelectedOptions] = useState({});
  const [isIncludesSelectedOptions, setIncludesSelectedOptions] =
    useState<boolean>(false);

  const ref = useRef(null);

  const handleClickOutside = (event: { target: any; }) => {
    //@ts-ignore
    if (ref.current && !ref.current.contains(event.target)) {
      setIsOpen(false);
    }
  };

  useEffect(() => {
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);

  useEffect(() => {
    if (devalultValues) {
      let defaultSelectedOptions = {};
      devalultValues?.map((val, index) => {
        defaultSelectedOptions = {
          ...defaultSelectedOptions,
          [val]: { value: true },
        };
      });
      setSelectedOptions(defaultSelectedOptions);
    }
  }, []);

  useEffect(() => {
    let isIncludesANyActiveOptiins = Object.keys(selectedOptions).find(
      //@ts-ignore
      (key) => selectedOptions[key].value === true
    );

    setIncludesSelectedOptions(!!isIncludesANyActiveOptiins);
  }, [selectedOptions]);

  useEffect(() => {
    if (errorText) {
      setSelectedOptions([]);
    }
  }, [errorText]);

  const handleClick = () => {
    if (!disabled) {
      setIsOpen((open) => !open);
    }
  };

  const findMaxIndexInObject = (selectedOptions: any) => {
    const array = Object.keys(selectedOptions).map((key) => {
      return selectedOptions[key];
    });

    if (!array?.length) {
      return 0;
    }
    let result = array?.sort((opt1, opt2) => opt1.index - opt2.index)[
      array?.length - 1
    ];
    return result?.index ? result?.index + 1 : 1;
  };

  const onOptionClick = (option: number | string) => {
    let result = {};
    let maxIndex = findMaxIndexInObject(selectedOptions);

    if (!useSingleValue) {
      //@ts-ignore
      if (selectedOptions[`${option}`]?.value) {
        result = {
          ...selectedOptions,
          [option]: { value: false, index: maxIndex },
        };
      } else {
        result = {
          ...selectedOptions,
          [option]: { value: true, index: maxIndex },
        };
      }
    } else {
      //@ts-ignore
      if (selectedOptions[`${option}`]?.value) {
        result = {
          [option]: { value: false, index: maxIndex },
        };
      } else {
        result = {
          [option]: { value: true, index: maxIndex },
        };
      }
    }

    setSelectedOptions(result);
    let selectedOptionsToRender = Object.keys(result).filter(
      //@ts-ignore
      (key) => result[key].value === true
    );
    handleSelect(selectedOptionsToRender);
  };

  //@ts-ignore
  const onRemoveHandler = (event: any, value: string) => {
    event.stopPropagation();
    onOptionClick(value); //was +value before
  };

  const renderSelectedOptions = () => {
    let selectedOptionsToRender = Object.keys(selectedOptions).map((key) => {
      //@ts-ignore
      if (selectedOptions[key].value === true) {
        //@ts-ignore
        return { label: key, ...selectedOptions[key] };
      }
    });
    // console.log("selectedOptionsToRender", selectedOptionsToRender);

    return selectedOptionsToRender
      ?.filter((opt) => !!opt)
      ?.sort((opt1, opt2) => opt1.index - opt2.index)
      ?.map((opt, index) => {
        return (
          <div
            key={`id_${index}`}
            className={styles.option}
            onClick={(e) => onRemoveHandler(e, opt?.label)}
          >
            <p>{opt?.label}</p>
            <div style={{ display: "flex" }}>
              <Image
                src={theme === "light" ? CloseIconLight : CloseIconDark}
                alt={"Close icon"}
              />
            </div>
          </div>
        );
      });
  };

  const onCleanHandler = () => {
    setSelectedOptions([]);
    handleCleanValues && handleCleanValues();
  };

  const renderOption = (option: number | string) => {
    const isOptionSelected = Object.keys(selectedOptions).find((key) => {
      //@ts-ignore
      return key === `${option}` && selectedOptions[key].value === true;
    });

    return (
      <div
        key={option}
        onClick={() => onOptionClick(option)}
        className={
          isOptionSelected ? styles.active_option : styles.disactive_option
        }
      >
        <div>{option}</div>
      </div>
    );
  };

  return (
    <div
      className={
        theme === "light"
          ? styles.light_dropdown_wrapper
          : styles.dark_dropdown_wrapper
      }
      ref={ref}
    >
      <p
        className={
          theme === "light"
            ? styles.light_dropdown_title
            : styles.dark_dropdown_title
        }
        onClick={handleClick}
      >
        {title}
      </p>
      <div
        style={{ opacity: disabled ? 0.7 : 1 }}
        className={
          theme === "light"
            ? errorText
              ? `${styles.light_dropdown} ${styles.error_dropdown_light}`
              : styles.light_dropdown
            : errorText
            ? `${styles.dark_dropdown} ${styles.error_dropdown_dark}`
            : styles.dark_dropdown
        }
        onClick={handleClick}
        data-id={id}
      >
        {isIncludesSelectedOptions ? (
          <div className={styles.optionsWrapper}>{renderSelectedOptions()}</div>
        ) : (
          <p className={styles.placeholder}>{placeholder}</p>
        )}
        <Image
          className={
            isOpen ? styles.open_dropdown_icon : styles.close_dropdown_icon
          }
          src={theme === "light" ? ArrowLight : ArrowDark}
          alt="Arrow-icon"
        />
      </div>
      {errorText ? <p className={styles.error_text}>{errorText}</p> : null}
      {isOpen && (
        <div
          className={
            options.length > 8
              ? `${styles.dropdown_modal} ${styles.dropdown_modal_scroll}`
              : styles.dropdown_modal
          }
        >
          {options?.map((option: number | string) => {
            return renderOption(option);
          })}
        </div>
      )}
      {showCleanButton && (
        <div className={styles.clean_button} onClick={onCleanHandler}>
          <Image
            src={theme === "dark" ? CleanIconDark : CleanIconLight}
            alt="Clean icon"
          />
        </div>
      )}
    </div>
  );
};

export default Dropdown;
