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

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

type MultiCascaderProps = {
  options: Option[];
  defaultValue?: string[];
  value?: string[];
  onChange?: (value: string[]) => void;
  placeholder?: string;
  maxHeight?: number; // 下拉框最大高度，默认300px
  searchable?: boolean; // 是否显示搜索框，默认false
  searchPlaceholder?: string; // 搜索框占位符
};

// 获取所有叶子节点的值
const getAllLeafValues = (option: Option): string[] => {
  if (!option.children || option.children.length === 0) {
    return [option.value];
  }
  return option.children.flatMap(getAllLeafValues);
};

// 检查节点是否所有子节点都被选中
const isAllChildrenChecked = (option: Option, selected: string[]): boolean => {
  if (!option.children || option.children.length === 0) {
    return selected.includes(option.value);
  }
  // 对于有子节点的节点，检查其所有叶子节点是否都被选中
  const leafValues = getAllLeafValues(option);
  return leafValues.every(value => selected.includes(value));
};

// 检查节点是否有部分子节点被选中
const isSomeChildrenChecked = (option: Option, selected: string[]): boolean => {
  if (!option.children || option.children.length === 0) {
    return selected.includes(option.value);
  }
  // 对于有子节点的节点，检查其叶子节点是否有部分被选中
  const leafValues = getAllLeafValues(option);
  return leafValues.some(value => selected.includes(value));
};

// 递归过滤选项，保留匹配项及其父级
const filterOptions = (options: Option[], keyword: string): Option[] => {
  if (!keyword.trim()) return options;

  const lowerKeyword = keyword.toLowerCase();

  return options.reduce<Option[]>((acc, option) => {
    // 检查当前节点是否匹配
    const isCurrentMatch = option.label.toLowerCase().includes(lowerKeyword);

    // 递归检查子节点
    const filteredChildren = option.children ? filterOptions(option.children, keyword) : [];

    // 如果当前节点匹配，或者有匹配的子节点，则保留
    if (isCurrentMatch || filteredChildren.length > 0) {
      acc.push({
        ...option,
        children: isCurrentMatch
          ? option.children // 如果父节点匹配，保留所有子节点
          : filteredChildren.length > 0
            ? filteredChildren // 如果只是子节点匹配，只保留匹配的子节点
            : option.children
      });
    }

    return acc;
  }, []);
};

// 获取过滤后需要展开的所有父节点
const getExpandedKeysForFilter = (options: Option[], keyword: string): Set<string> => {
  const keys = new Set<string>();
  if (!keyword.trim()) return keys;

  const lowerKeyword = keyword.toLowerCase();

  const traverse = (opts: Option[], parentKeys: string[]) => {
    for (const opt of opts) {
      const isMatch = opt.label.toLowerCase().includes(lowerKeyword);
      const hasChildren = opt.children && opt.children.length > 0;

      if (hasChildren) {
        // 递归检查子节点
        const childMatches = traverse(opt.children!, [...parentKeys, opt.value]);

        // 如果子节点有匹配，展开当前节点
        if (childMatches) {
          keys.add(opt.value);
          parentKeys.forEach(k => keys.add(k));
        }
      }

      // 如果当前节点匹配且有父节点，展开父节点
      if (isMatch && parentKeys.length > 0) {
        parentKeys.forEach(k => keys.add(k));
        return true;
      }
    }
    return false;
  };

  traverse(options, []);
  return keys;
};

const MultiCascader: React.FC<MultiCascaderProps> = ({
  options,
  defaultValue = [],
  value,
  onChange,
  placeholder = '请选择',
  maxHeight = 300,
  searchable = false,
  searchPlaceholder = '搜索...'
}) => {
  const [visible, setVisible] = useState(false);
  const [selected, setSelected] = useState<string[]>(value ?? defaultValue);
  const [expandedKeys, setExpandedKeys] = useState<Set<string>>(new Set());
  const [searchKeyword, setSearchKeyword] = useState('');
  const containerRef = useRef<HTMLDivElement>(null);
  const searchInputRef = useRef<HTMLInputElement>(null);

  // 当外部 value 变化时，同步内部状态
  useEffect(() => {
    if (value !== undefined) {
      setSelected(value);
    }
  }, [value]);

  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);
  }, []);

  // 搜索关键词变化时自动展开匹配项
  useEffect(() => {
    if (searchKeyword.trim()) {
      const keysToExpand = getExpandedKeysForFilter(options, searchKeyword);
      setExpandedKeys(keysToExpand);
    }
  }, [searchKeyword, options]);

  // 下拉框打开时聚焦搜索框
  useEffect(() => {
    if (visible && searchable && searchInputRef.current) {
      setTimeout(() => searchInputRef.current?.focus(), 100);
    }
    if (!visible) {
      setSearchKeyword(''); // 关闭时清空搜索
    }
  }, [visible, searchable]);

  // 过滤后的选项
  const filteredOptions = searchable ? filterOptions(options, searchKeyword) : options;

  const handleItemCheck = (option: Option, checked: boolean) => {
    const leafValues = getAllLeafValues(option);
    let newSelected: string[];
    
    if (checked) {
      newSelected = Array.from(new Set([...selected, ...leafValues]));
    } else {
      newSelected = selected.filter(v => !leafValues.includes(v));
    }
    
    setSelected(newSelected);
    onChange?.(newSelected);
  };

  const getDisplayText = () => {
    if (selected.length === 0) return placeholder;
    return `已选择 ${selected.length} 项`;
  };

  const toggleExpand = (key: string) => {
    setExpandedKeys(prev => {
      const newSet = new Set(prev);
      if (newSet.has(key)) {
        newSet.delete(key);
      } else {
        newSet.add(key);
      }
      return newSet;
    });
  };

  const renderOption = (option: Option, level: number = 0) => {
    const allChecked = isAllChildrenChecked(option, selected);
    const someChecked = isSomeChildrenChecked(option, selected);
    const hasChildren = option.children && option.children.length > 0;
    const isExpanded = expandedKeys.has(option.value);
    
    return (
      <div key={option.value} className={level > 0 ? "pl-4" : ""}>
        <div className="flex items-center py-1">
          <input
            type="checkbox"
            className="h-4 w-4 rounded border-gray-300"
            style={{
              accentColor: '#00684a', // 固定为绿色（烟草企业绿）
              cursor: 'pointer'
            }}
            checked={allChecked}
            ref={el => { if (el) el.indeterminate = !allChecked && someChecked; }}
            onChange={e => handleItemCheck(option, e.target.checked)}
            id={`cascader-${option.value}`}
          />
          <label htmlFor={`cascader-${option.value}`} className="ml-2 text-sm flex-1 cursor-pointer">
            {option.label}
          </label>
          {hasChildren && (
            <button
              type="button"
              className="ml-2"
              style={{ color: 'gray' }} // 展开图标固定为绿色
              onClick={(e) => {
                e.stopPropagation();
                toggleExpand(option.value);
              }}
            >
              <i className={isExpanded ? "ri-arrow-down-s-line" : "ri-arrow-right-s-line"}></i>
            </button>
          )}
        </div>
        {hasChildren && isExpanded && (
          <div className="ml-4 border-l border-gray-200 pl-2">
            {option.children?.map(child => (
              <React.Fragment key={child.value}>
                {renderOption(child, level + 1)}
              </React.Fragment>
            ))}
          </div>
        )}
      </div>
    );
  };

  return (
    <div ref={containerRef} className="relative inline-block w-full">
      <div
        className="border border-gray-300 rounded px-3 py-2 cursor-pointer bg-white flex justify-between items-center focus:outline-none focus:ring-2 focus:ring-[var(--color-primary,#00684a)] focus:border-[var(--color-primary,#00684a)]"
        role="button"
        tabIndex={0}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            setVisible(!visible);
          }
        }}
        onClick={() => setVisible(!visible)}
      >
        <span className={selected.length === 0 ? 'text-gray-400' : ''}>
          {getDisplayText()}
        </span>
        <span className="text-gray-400">
          <i className={visible ? "ri-arrow-up-s-line" : "ri-arrow-down-s-line"}></i>
        </span>
      </div>
      {visible && (
        <div className="absolute z-10 bg-white border border-gray-300 rounded shadow-lg mt-1 w-full">
          {/* 搜索框 */}
          {searchable && (
            <div className="p-2 border-b border-gray-200">
              <div className="relative">
                <i className="ri-search-line absolute left-2 top-1/2 -translate-y-1/2 text-gray-400"></i>
                <input
                  ref={searchInputRef}
                  type="text"
                  className="w-full pl-8 pr-3 py-1.5 text-sm border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-[var(--color-primary,#00684a)] focus:border-[var(--color-primary,#00684a)]"
                  placeholder={searchPlaceholder}
                  value={searchKeyword}
                  onChange={(e) => setSearchKeyword(e.target.value)}
                  onClick={(e) => e.stopPropagation()}
                />
                {searchKeyword && (
                  <button
                    type="button"
                    className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
                    onClick={(e) => {
                      e.stopPropagation();
                      setSearchKeyword('');
                    }}
                  >
                    <i className="ri-close-line"></i>
                  </button>
                )}
              </div>
            </div>
          )}
          {/* 选项列表 */}
          <div className="p-2 overflow-y-auto" style={{ maxHeight: `${maxHeight}px` }}>
            {filteredOptions.length > 0 ? (
              filteredOptions.map(option => renderOption(option))
            ) : (
              <div className="text-center text-gray-400 py-4 text-sm">
                <i className="ri-search-line text-lg block mb-1"></i>
                无匹配结果
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
};

export default MultiCascader;