import React, { useState, useEffect, useRef } from 'react';

type Option = {
  value: string;
  label: string;
  children?: Option[];
};

type CascaderProps = {
  options: Option[];
  defaultValue?: string[];
  onChange?: (value: string[]) => void;
  placeholder?: string;
};

const Cascader: React.FC<CascaderProps> = ({ options, defaultValue = [], onChange, placeholder = 'Select' }) => {
  const [visible, setVisible] = useState(false);
  const [selected, setSelected] = useState<string[]>(defaultValue);
  const [menus, setMenus] = useState<Option[][]>([options]);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setVisible(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const handleItemClick = (option: Option, level: number) => {
    const newSelected = selected.slice(0, level).concat(option.value);
    setSelected(newSelected);
    if (option.children) {
      setMenus(menus.slice(0, level + 1).concat([option.children]));
    } else {
      setMenus(menus.slice(0, level + 1));
      setVisible(false);
      onChange?.(newSelected);
    }
  };

  const getDisplayText = () => {
    if (selected.length === 0) return placeholder;
    let currentOptions = options;
    return selected.map(val => {
      const opt = currentOptions.find(o => o.value === val);
      currentOptions = opt?.children || [];
      return opt?.label || '';
    }).join(' / ');
  };

  return (
    <div ref={containerRef} className="relative inline-block">
      <div
        className="border border-gray-300 rounded px-3 py-1 cursor-pointer"
        onClick={() => setVisible(!visible)}
      >
        {getDisplayText()}
      </div>
      {visible && (
        <div className="absolute z-10 bg-white border border-gray-300 rounded shadow-lg mt-1 flex">
          {menus.map((menu, level) => (
            <ul key={level} className="list-none m-0 p-0 min-w-[150px] border-r border-gray-200 last:border-r-0">
              {menu.map(option => (
                <li
                  key={option.value}
                  className={`px-3 py-1 cursor-pointer hover:bg-gray-100 ${selected[level] === option.value ? 'bg-gray-200' : ''}`}
                  onClick={() => handleItemClick(option, level)}
                >
                  {option.label}
                </li>
              ))}
            </ul>
          ))}
        </div>
      )}
    </div>
  );
};

export default Cascader;