<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kole UI · Cascader (H5)</title>
<link rel="stylesheet" href="../.design_library/kole-ui/colors_and_type.css">
<link rel="stylesheet" href="./Cascader.css">
<style>
  .demo { padding: 24px; background: var(--kole-color-page-bg); font-family: var(--font-family); }
  h1 { font-size: 20px; margin: 0 0 4px; color: var(--kole-color-text-title); }
  .sub { color: var(--kole-color-text-secondary); margin: 0 0 24px; font-size: 12px; }
  .demo-block { background: var(--kole-color-card-bg); border-radius: 8px; padding: 24px; margin-bottom: 20px; }
  .demo-block > .hint { color: var(--kole-color-text-secondary); font-size: 12px; margin: 0 0 12px; }
</style>
</head>
<body>
<div class="demo">
  <h1>Kole UI · Cascader 组件（纯 H5）</h1>
  <p class="sub">对齐 Cascader 规范：多级下拉、搜索、路径显示、多选</p>

  <div class="demo-block">
    <p class="hint">单选 + 搜索</p>
    <div class="kole-cascader" data-cascader data-multiple="false"></div>
  </div>

  <div class="demo-block">
    <p class="hint">多选</p>
    <div class="kole-cascader" data-cascader data-multiple="true"></div>
  </div>
</div>

<script>
const OPTIONS = [
  { value: 'zj', label: '浙江', children: [
    { value: 'hz', label: '杭州', children: [ { value: 'xh', label: '西湖区' }, { value: 'bj', label: '滨江区' } ] },
    { value: 'wz', label: '温州', children: [ { value: 'lc', label: '鹿城区' } ] }
  ] },
  { value: 'js', label: '江苏', children: [
    { value: 'nj', label: '南京', children: [ { value: 'xk', label: '玄武区' } ] }
  ] }
];

function 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;
}
function findNode(values) {
  let nodes = OPTIONS, node = null;
  for (const v of values) {
    node = nodes.find(x => x.value === v);
    if (!node) return null;
    nodes = node.children || [];
  }
  return node;
}
function flatten() {
  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;
}

function initCascader(root) {
  const multiple = root.dataset.multiple === 'true';
  let open = false;
  let activePath = [];
  let query = '';
  // single: value = 数组路径或 null ; multiple: value = 路径数组的数组
  let value = multiple ? [] : null;

  const trigger = document.createElement('div');
  trigger.className = 'kole-cascader-trigger'; trigger.setAttribute('role','button'); trigger.setAttribute('tabindex','0'); trigger.setAttribute('aria-haspopup','listbox'); trigger.setAttribute('aria-expanded','false');

  function renderTrigger() {
    if (multiple) {
      if (!value.length) { trigger.innerHTML = '<span class="placeholder">请选择</span><span class="caret">▾</span>'; }
      else {
        trigger.innerHTML = '<span class="kole-cascader-tags">' +
          value.map(p => `<span class="kole-cascader-tag">${pathLabels(p).join(' / ')}</span>`).join('') +
          '</span><span class="caret">▾</span>';
      }
    } else {
      trigger.innerHTML = (value ? `<span>${pathLabels(value).join(' / ')}</span>` : '<span class="placeholder">请选择</span>') + '<span class="caret">▾</span>';
    }
    trigger.classList.toggle('is-open', open);
  }

  function renderPanel() {
    let panel = root.querySelector('.kole-cascader-panel');
    if (!panel) { panel = document.createElement('div'); panel.className = 'kole-cascader-panel'; root.appendChild(panel); }
    if (query) {
      const results = flatten().filter(p => pathLabels(p).join('/').includes(query));
      panel.innerHTML = `<div class="kole-cascader-results">` +
        (results.length ? results.map(p => `<div class="kole-cascader-result" data-path='${JSON.stringify(p)}'>${pathLabels(p).join(' / ')}</div>`).join('') : '<div class="kole-cascader-empty">无匹配结果</div>') +
        `</div>`;
      panel.querySelectorAll('.kole-cascader-result').forEach(r => {
        r.addEventListener('click', () => {
          const p = JSON.parse(r.dataset.path);
          if (multiple) {
            const s = value.map(x => JSON.stringify(x));
            const k = JSON.stringify(p);
            if (s.includes(k)) value = value.filter(x => JSON.stringify(x) !== k);
            else value = [...value, p];
            renderTrigger();
          } else { value = p; open = false; renderTrigger(); renderPanel(); }
        });
      });
      return;
    }
    // 列视图
    let html = '';
    let levelNodes = OPTIONS, path = [];
    for (let lv = 0; lv <= activePath.length; lv++) {
      const col = levelNodes;
      html += '<div class="kole-cascader-col">';
      col.forEach(n => {
        const isActive = activePath[lv] === n.value;
        const hasChild = n.children && n.children.length;
        let box = '';
        if (multiple && !hasChild) {
          const sel = value.some(p => JSON.stringify(p) === JSON.stringify([...path, n.value].slice(0, [...path, n.value].length)));
          const checked = value.some(p => JSON.stringify(p) === JSON.stringify([...path, n.value]));
          box = `<span class="box">${checked ? '✓' : ''}</span>`;
        }
        html += `<div class="kole-cascader-opt ${isActive ? 'is-active' : ''}${multiple && !hasChild && checked ? ' is-checked' : ''}" data-lv="${lv}" data-val="${n.value}">${box}<span>${n.label}</span>${hasChild ? '<span class="arrow">›</span>' : ''}</div>`;
      });
      html += '</div>';
      if (lv < activePath.length) {
        const next = levelNodes.find(x => x.value === activePath[lv]);
        path = [...path, activePath[lv]];
        levelNodes = next.children || [];
      } else break;
    }
    panel.innerHTML = html;
    panel.querySelectorAll('.kole-cascader-opt').forEach(opt => {
      opt.addEventListener('click', () => {
        const lv = +opt.dataset.lv, val = opt.dataset.val;
        const node = findNode([...activePath.slice(0, lv), val]);
        const full = [...activePath.slice(0, lv), val];
        if (node && node.children && node.children.length) {
          activePath = full; renderPanel();
        } else {
          if (multiple) {
            const k = JSON.stringify(full);
            value = value.some(p => JSON.stringify(p) === k) ? value.filter(p => JSON.stringify(p) !== k) : [...value, full];
            renderTrigger();
          } else { value = full; open = false; renderTrigger(); renderPanel(); }
        }
      });
    });
  }

  trigger.addEventListener('click', (e) => {
    e.stopPropagation();
    open = !open; renderTrigger(); renderPanel();
  });
  root.appendChild(trigger);

  root.addEventListener('click', (e) => {
    const q = e.target.closest('.kole-cascader-search input');
    if (q) return;
  });
  // 搜索框（filterable）
  const search = document.createElement('div');
  search.className = 'kole-cascader-search';
  search.style.display = 'none';
  search.innerHTML = '<input placeholder="搜索"><div class="kole-cascader-results"></div>';
  search.querySelector('input').addEventListener('input', (e) => { query = e.target.value; renderPanel(); });
  root.appendChild(search);

  trigger.addEventListener('click', () => {
    search.style.display = open ? 'block' : 'none';
    if (open) search.querySelector('input').focus();
  });

  document.addEventListener('click', (e) => {
    if (!root.contains(e.target)) { open = false; query = ''; renderTrigger(); renderPanel(); search.style.display = 'none'; }
  });

  renderTrigger();
}
document.querySelectorAll('[data-cascader]').forEach(initCascader);
</script>
</body>
</html>
