import { memo, useRef, useState } from "react";
import styles from "@/components/administrator/form/form.module.css";

import { SlArrowDown } from "react-icons/sl";
import { useOutsideClick } from "@/hooks/useOutsideClick";

/**
 * A generic input component with a label and a visible password toggle.
 * @type {React.FC<React.InputHTMLAttributes<HTMLInputElement> & {
 *   label: string;
 *   labelclassname?: string;
 *   className?: string;
 *   icon?: React.ReactNode;
 *   value?: string | number | readonly string[];
 *   data: any[];
 *   display: string;
 *   onChange: React.MouseEventHandler<HTMLButtonElement>;
 *   format: {
 *       label: string;
 *       action: Function;
 *       changeValue: boolean
 *   };
 * }>}
 */
const DropdownComponent = (props) => {
  const ref = useRef(null);
  const inputref = useRef(null);
  const iconRef = useRef(null);
  const [value, setValue] = useState(props.value || "");
  const [isOpen, setIsOpen] = useState(false);

  useOutsideClick(ref, () => setIsOpen(false), [iconRef, inputref]);

  return (
    <div className={styles.input_container}>
      <div className={styles.input_header}>
        <p className={`${styles.label} ${props.labelclassname}`}>
          {props.label}
        </p>
        {props.format && (
          <div
            className={`${styles.format} ${props.labelclassname}`}
            onClick={(e) => {
              if (
                props.format.action &&
                typeof props.format.action === "function"
              ) {
                if (props.format.changeValue)
                  props.format.action(value, setValue);
              }
            }}>
            {props.format?.label}
          </div>
        )}
      </div>
      <div
        ref={inputref}
        className={`${styles.wrapper} ${props.className} ${
          isOpen ? styles.active : ""
        }`}
        style={{ cursor: "pointer" }}
        onClick={() => setIsOpen(!isOpen)}>
        {props.icon && <>{props.icon}</>}
        <div
          className={styles.dropdown}
          suppressHydrationWarning>
          {value[props.display]}
        </div>
        <SlArrowDown
          ref={iconRef}
          size={10}
          className={`${styles.toggle_icon} ${isOpen ? styles.open : ""}`}
          onClick={() => setIsOpen(!isOpen)}
        />
      </div>
      {isOpen && (
        <div
          className={styles.dropdown_items}
          ref={ref}>
          <DropdownItem
            data={props.data}
            display={props.display}
            level={1}
            onChange={(item, e) => {
              setValue(item);
              setIsOpen(!isOpen);

              if (props.onChange && typeof props.onChange === "function")
                props.onChange(item, e);
            }}
          />
        </div>
      )}
    </div>
  );
};

/**
 * @type {React.FC<React.InputHTMLAttributes<HTMLInputElement> & {
 *   data: any[];
 *   display: string;
 *   level: number;
 *   onChange?: React.MouseEventHandler<HTMLButtonElement>;
 * }>}
 */
const DropdownItem = (props) => {
  return (
    <>
      {props.data.map((item, index) => {
        return (
          <div key={index}>
            <div
              style={{ paddingLeft: `${props.level * 20}px` }}
              onClick={(e) => {
                if (props.onChange && typeof props.onChange === "function")
                  props.onChange(item, e);
              }}
              className={`${styles.dropdown_item}`}>
              {item[props.display]}
            </div>
            {item.children && item.children.length > 0 && (
              <DropdownItem
                data={item.children}
                display={props.display}
                level={props.level + 1}
                onChange={props.onChange}
              />
            )}
          </div>
        );
      })}
    </>
  );
};

const Dropdown = memo(DropdownComponent);
export default Dropdown;
