import { useEffect, useMemo, useRef, useState } from "react";
import {
  MultipleDropdownInput,
  MultipleDropdownOptions,
  SelectedValueContainer,
} from "./MultipleDropdown.styled";
import {
  DropdownButtonContainer,
  OptionContainer,
} from "../SingleDropdown/SingleDropdown.styled";
import X from "../../../assets/svgs/x.svg";
import ChevronDown from "../../../assets/svgs/chevron-down.svg";
import { gray, primary } from "../../../core/colors/colors";
import { DropdownStatus } from "../SingleDropdown/SingleDropdown";
import Checkbox from "../../Checkbox";
import { CommonDropdownTypes } from "../DropdownTypes";
import DropdownSearch from "../DropdownSearch";

export type MultipleDropdownProps<T> = CommonDropdownTypes<T> & {
  selectedValues?: T[];
};

const MultipleDropdown = <T extends {}>({
  selectedValues,
  options,
  optionKey,
  optionLabel,
  onClick,
  enableClearButton = true,
  enableSearch = true,
  optionElement,
  disable = false,
  placeholder,
}: MultipleDropdownProps<T>) => {
  const [isFocus, setIsFocus] = useState<boolean>(false);
  const [filterValue, setFilterValue] = useState<string>("");
  const [filteredOptions, setFilteredOptions] = useState<T[]>([...options]);
  const status: DropdownStatus = useMemo(() => {
    if (isFocus) return "FOCUS";
    return "DEFAULT";
  }, [isFocus]);
  const dropdownRef = useRef<HTMLDivElement>(null);

  const style: {
    [key in DropdownStatus]: { [style in "borderColor"]: string };
  } = {
    DEFAULT: {
      borderColor: gray[300],
    },
    FOCUS: {
      borderColor: primary[500],
    },
  };

  const renderDropdownOptions = () => {
    const valueToShow =
      filteredOptions?.length !== 0 ? filteredOptions : options;
    const selectedClassName = (option: T) => {
      return selectedValues &&
        selectedValues.some((data) => optionKey(option) === optionKey(data))
        ? "selected"
        : "";
    };
    return (
      <OptionContainer className={optionElement && "jsx_element"}>
        {valueToShow.map((option, idx) => (
          <button
            key={`${optionKey(option)}_${idx}`}
            className={selectedClassName(option)}
            onClick={(e) => {
              onClick(option);
              e.preventDefault();
            }}
          >
            <button
              className="checkbox_button"
              onClick={(e) => {
                onClick(option);
                e.preventDefault();
              }}
            >
              <Checkbox
                checked={selectedClassName(option) === "selected"}
                onChange={() => {}}
              />
            </button>
            {optionElement ? (
              optionElement({ option })
            ) : (
              <p>{optionLabel(option)}</p>
            )}
          </button>
        ))}
      </OptionContainer>
    );
  };

  useEffect(() => {
    const outsideClick = (e: MouseEvent) => {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(e.target as Node)
      ) {
        setIsFocus(false);
        setFilterValue("");
      }
    };
    window.addEventListener("mousedown", outsideClick);
    return () => window.removeEventListener("mousedown", outsideClick);
  }, [dropdownRef]);

  return (
    <div ref={dropdownRef}>
      <MultipleDropdownInput
        onClick={() => {
          !disable && setIsFocus(!isFocus);
          setFilteredOptions([...options]);
          setFilterValue("");
        }}
        style={{
          ...style[status],
          height: selectedValues?.length !== 0 ? "max-content" : "",
          paddingRight: enableClearButton ? "64px" : "40px",
          backgroundColor: disable ? gray[50] : "",
          cursor: disable ? "inherit" : "pointer",
        }}
      >
        <SelectedValueContainer
          placeholder={selectedValues?.length === 0 ? placeholder : ""}
          disable={disable}
        >
          {selectedValues?.map((data) => (
            <article>
              <p>{optionLabel(data)}</p>
              {/* selectedValues 개별 삭제 */}
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  onClick(data);
                  isFocus ? setIsFocus(true) : setIsFocus(false);
                }}
                disabled={disable}
              >
                <X />
              </button>
            </article>
          ))}
        </SelectedValueContainer>
        <DropdownButtonContainer>
          {selectedValues?.length !== 0 && enableClearButton ? (
            // selectedValues 전체 삭제
            <button
              onClick={(e) => {
                e.stopPropagation();
                onClick(undefined);
                setIsFocus(false);
              }}
              disabled={disable}
            >
              <X />
            </button>
          ) : null}
          <button onClick={() => setIsFocus(!isFocus)} disabled={disable}>
            <ChevronDown
            // style={{
            //   stroke: isFocus ? gray[600] : "",
            //   transform: isFocus ? "rotate(180deg)" : "",
            // }}
            />
          </button>
        </DropdownButtonContainer>
      </MultipleDropdownInput>
      {isFocus && (
        <>
          {enableSearch && (
            <DropdownSearch<T>
              value={filterValue}
              options={options}
              optionLabel={(value) => optionLabel(value)}
              onChange={(e) => {
                !e.target.value && setFilteredOptions([...options]);
                setFilterValue(e.target.value);
              }}
              onSearch={(filteredOptions) =>
                setFilteredOptions(filteredOptions)
              }
              filterValueClear={() => {
                setFilterValue("");
                setFilteredOptions([...options]);
              }}
              placeholder="검색 후 Enter 키를 눌러주세요"
            />
          )}
          <MultipleDropdownOptions
            style={
              enableSearch
                ? {
                    maxHeight: "343px",
                    marginTop: 0,
                    paddingTop: 0,
                    borderTop: 0,
                    borderTopLeftRadius: 0,
                    borderTopRightRadius: 0,
                  }
                : {}
            }
          >
            {options.length === 0 ||
            (enableSearch && filteredOptions.length === 0) ? (
              <div className="empty">데이터가 없습니다</div>
            ) : (
              renderDropdownOptions()
            )}
          </MultipleDropdownOptions>
        </>
      )}
    </div>
  );
};

export default MultipleDropdown;
