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

/**
 * Kole UI Tree（React）
 * 对齐 组件2.txt Tree 规范：节点高32px、缩进16px/级、箭头12px、选中 #F0F5FF/#2F54EB、复选框级联
 * nodes: [{ key, title, children, disabled }]
 * 受控：selectedKeys / checkedKeys（均为数组），通过 onSelect / onCheck 回调更新
 */
function findNode(key, nodes) {
  for (const n of nodes) {
    if (n.key === key) return n;
    if (n.children) { const f = findNode(key, n.children); if (f) return f; }
  }
  return null;
}
function descendantKeys(node) {
  let out = [];
  (node.children || []).forEach((c) => { out.push(c.key); out = out.concat(descendantKeys(c)); });
  return out;
}
function allChildrenChecked(node, set) {
  if (!node.children || !node.children.length) return set.has(node.key);
  return node.children.every((c) => allChildrenChecked(c, set));
}

export default function Tree({
  data = [],
  checkable = false,
  defaultExpandedKeys = [],
  selectedKeys = [],
  checkedKeys = [],
  onSelect,
  onCheck
}) {
  const [expanded, setExpanded] = useState(() => new Set(defaultExpandedKeys));
  const [selected, setSelected] = useState(() => new Set(selectedKeys));
  const [checked, setChecked] = useState(() => new Set(checkedKeys));

  const visibleList = useMemo(() => {
    const out = [];
    const walk = (nodes, depth) => {
      nodes.forEach((n) => {
        out.push({ node: n, depth });
        if (n.children && n.children.length && expanded.has(n.key)) walk(n.children, depth + 1);
      });
    };
    walk(data, 0);
    return out;
  }, [data, expanded]);

  const hasChildren = (n) => !!(n.children && n.children.length);
  const isIndeterminate = (key) => {
    const node = findNode(key, data);
    if (!node || !hasChildren(node)) return false;
    const desc = descendantKeys(node);
    return desc.some((d) => checked.has(d)) && !allChildrenChecked(node, checked);
  };

  const toggleExpand = (key) =>
    setExpanded((prev) => { const n = new Set(prev); n.has(key) ? n.delete(key) : n.add(key); return n; });

  const onRowClick = (node) => {
    setSelected(new Set([node.key]));
    onSelect && onSelect(node.key);
  };

  const toggleCheck = (key) => {
    const node = findNode(key, data);
    const willCheck = !checked.has(key);
    const keys = [key, ...descendantKeys(node)];
    const next = new Set(checked);
    keys.forEach((k) => (willCheck ? next.add(k) : next.delete(k)));
    const propagate = (nodes) => {
      nodes.forEach((n) => {
        if (hasChildren(n)) {
          if (allChildrenChecked(n, next)) next.add(n.key); else next.delete(n.key);
          propagate(n.children);
        }
      });
    };
    propagate(data);
    setChecked(next);
    onCheck && onCheck([...next]);
  };

  return (
    <div className="kole-tree">
      {visibleList.map(({ node, depth }) => {
        const open = expanded.has(node.key);
        const arrow = hasChildren(node) ? (
          <span className={`kole-tree-arrow${open ? ' is-open' : ''}`} onClick={(e) => { e.stopPropagation(); toggleExpand(node.key); }}>▸</span>
        ) : <span className="kole-tree-arrow-placeholder" />;
        const check = checkable ? (
          <input
            type="checkbox" className="kole-tree-check"
            checked={checked.has(node.key)}
            ref={(el) => el && (el.indeterminate = isIndeterminate(node.key))}
            onClick={(e) => e.stopPropagation()}
            onChange={() => toggleCheck(node.key)}
          />
        ) : null;
        return (
          <div
            key={node.key}
            className={`kole-tree-node${selected.has(node.key) ? ' is-selected' : ''}`}
            style={{ paddingLeft: depth * 16 + 4 }}
            onClick={() => onRowClick(node)}
          >
            {arrow}
            {check}
            <span className="kole-tree-label">{node.title}</span>
          </div>
        );
      })}
    </div>
  );
}

/*
用法示例：
import Tree from './Tree';
const data = [
  { key: 'org', title: '某某科技', children: [
    { key: 'tech', title: '技术中心', children: [{ key: 'fe', title: '前端组' }] }
  ]}
];
<Tree data={data} checkable defaultExpandedKeys={['org']} onSelect={setSel} onCheck={setChecked} />
*/
