import React, { useRef, useState, useEffect, useMemo } from 'react';
import './Cascader.css';

/**
 * Kole UI Cascader（React）
 * 对齐 组件7.txt Cascader 规范：多级下拉、搜索、路径显示、多选
 *
 * props:
 *  - value / defaultValue : 单选为路径数组(或 null)，多选为路径数组的数组
 *  - options : [{ value, label, children? }]
 *  - multiple
 *  - filterable
 *  - placeholder
 *  - onChange(value)
 */
export default function Cascader({
  value,
  defaultValue = [],
  options = [],
  multiple = false,
  filterable = true,
  placeholder = '请选择',
  onChange
}) {
  const rootRef = useRef(null);
  const [inner, setInner] = useState(defaultValue);
  const current = value !== undefined ? value : inner;
  const [open, setOpen] = useState(false);
  const [activePath, setActivePath] = useState([]);
  const [query, setQuery] = useState('');

  const pathLabels = (values) => {
    let nodes = options, labels = [];
    for (const v of (values || [])) {
      const n = nodes.find(x => x.value === v);
      if (!n) break;
      labels.push(n.label); nodes = n.children || [];
    }
    return labels;
  };
  const columns = useMemo(() => {
    const cols = [];
    let nodes = options;
    for (let lv = 0; lv <= activePath.length; lv++) {
      cols.push(nodes);
      if (lv < activePath.length) {
        const next = nodes.find(x => x.value === activePath[lv]);
        nodes = next.children || [];
      } else break;
    }
    return cols;
  }, [options, activePath]);

  const allLeaves = useMemo(() => {
    const out = [];
    (function walk(list, acc) {
      list.forEach(n => {
        const p = [...acc, n.value];
        if (n.children && n.children.length) walk(n.children, p);
        else out.push(p);
      });
    })(options, []);
    return out;
  }, [options]);
  const results = query ? allLeaves.filter(p => pathLabels(p).join('/').includes(query)) : [];

  const commit = (next) => {
    if (value === undefined) setInner(next);
    onChange && onChange(next);
  };
  const choose = (n, lv) => {
    const full = [...activePath.slice(0, lv), n.value];
    if (n.children && n.children.length) setActivePath(full);
    else if (multiple) {
      const k = JSON.stringify(full);
      const arr = Array.isArray(current) ? current : [];
      commit(arr.some(p => JSON.stringify(p) === k) ? arr.filter(p => JSON.stringify(p) !== k) : [...arr, full]);
    } else { commit(full); setOpen(false); }
  };
  const pickResult = (p) => {
    if (multiple) {
      const k = JSON.stringify(p);
      const arr = Array.isArray(current) ? current : [];
      commit(arr.some(x => JSON.stringify(x) === k) ? arr.filter(x => JSON.stringify(x) !== k) : [...arr, p]);
    } else { commit(p); setOpen(false); }
  };
  const isChecked = (p) => Array.isArray(current) && current.some(x => JSON.stringify(x) === JSON.stringify(p));

  useEffect(() => {
    const onDoc = (e) => { if (rootRef.current && !rootRef.current.contains(e.target)) { setOpen(false); setQuery(''); } };
    document.addEventListener('click', onDoc, true);
    return () => document.removeEventListener('click', onDoc, true);
  }, []);

  return (
    <div className="kole-cascader" ref={rootRef}>
      <div className={`kole-cascader-trigger${open ? ' is-open' : ''}`} onClick={() => { setOpen(!open); if (open) setQuery(''); }}>
        {multiple ? (
          current.length ? (
            <span className="kole-cascader-tags">
              {current.map((p, i) => <span key={i} className="kole-cascader-tag">{pathLabels(p).join(' / ')}</span>)}
            </span>
          ) : <span className="placeholder">{placeholder}</span>
        ) : (
          <span>{current && current.length ? pathLabels(current).join(' / ') : placeholder}</span>
        )}
        <span className="caret">▾</span>
      </div>

      {open && filterable && (
        <div className="kole-cascader-search">
          <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="搜索" />
        </div>
      )}

      {open && (
        <div className="kole-cascader-panel">
          {query ? (
            <div className="kole-cascader-results">
              {results.length ? results.map((p, i) => (
                <div key={i} className="kole-cascader-result" onClick={() => pickResult(p)}>{pathLabels(p).join(' / ')}</div>
              )) : <div className="kole-cascader-empty">无匹配结果</div>}
            </div>
          ) : (
            columns.map((col, ci) => (
              <div key={ci} className="kole-cascader-col">
                {col.map(n => (
                  <div
                    key={n.value}
                    className={`kole-cascader-opt${activePath[ci] === n.value ? ' is-active' : ''}${multiple && !n.children && isChecked([...activePath.slice(0, ci), n.value]) ? ' is-checked' : ''}`}
                    onClick={() => choose(n, ci)}
                  >
                    {multiple && !n.children && <span className="box">{isChecked([...activePath.slice(0, ci), n.value]) ? '✓' : ''}</span>}
                    <span>{n.label}</span>
                    {n.children && n.children.length && <span className="arrow">›</span>}
                  </div>
                ))}
              </div>
            ))
          )}
        </div>
      )}
    </div>
  );
}

/*
用法示例：
import Cascader from './Cascader';
const options = [{ value: 'zj', label: '浙江', children: [{ value: 'hz', label: '杭州', children: [{ value: 'xh', label: '西湖区' }] }] }];
<Cascader options={options} defaultValue={['zj', 'hz', 'xh']} onChange={setPath} />
*/
