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

/**
 * Kole UI Select（React）
 * 对齐 select.json 契约：
 *  - mode:    single | multiple（multiple 属性）
 *  - feature: searchable | grouped（groups 属性）
 *  - state:   default | open | disabled
 * 触发器样式同 Input；面板圆角4px / 阴影中 / 最大高度256px；选中项品牌色 + 勾选图标
 * 受控：<Select value={v} onChange={setV} options={...} />
 * 非受控：<Select defaultValue="bj" options={...} />
 */
function flatten(groups) {
  return (groups || []).flatMap((g) => g.options);
}

export default function Select({
  value,
  defaultValue = null,
  options = [],
  groups = null,
  multiple = false,
  searchable = false,
  disabled = false,
  placeholder = '请选择',
  className = '',
  onChange,
  ...rest
}) {
  const isControlled = value !== undefined;
  const [inner, setInner] = useState(defaultValue);
  const [open, setOpen] = useState(false);
  const [keyword, setKeyword] = useState('');
  const rootRef = useRef(null);

  const current = isControlled ? value : inner;
  const selectedArr = Array.isArray(current) ? current : [];
  const selectedVal = Array.isArray(current) ? null : current;

  const filteredOptions = useMemo(() => {
    if (!searchable || !keyword) return options;
    const q = keyword.trim().toLowerCase();
    return options.filter((o) => String(o.label).toLowerCase().includes(q));
  }, [options, searchable, keyword]);

  const filteredGroups = useMemo(() => {
    if (!groups) return [];
    if (!searchable || !keyword) return groups;
    const q = keyword.trim().toLowerCase();
    return groups
      .map((g) => ({ label: g.label, options: g.options.filter((o) => String(o.label).toLowerCase().includes(q)) }))
      .filter((g) => g.options.length);
  }, [groups, searchable, keyword]);

  const isEmpty = groups ? filteredGroups.length === 0 : filteredOptions.length === 0;

  const flat = options.length ? options : flatten(groups);

  function labelOf(v) {
    const found = flat.find((o) => o.value === v);
    return found ? found.label : v;
  }
  function isSelected(v) {
    return multiple ? selectedArr.includes(v) : selectedVal === v;
  }
  function emit(next) {
    if (!isControlled) setInner(next);
    onChange && onChange(next);
  }
  function choose(o) {
    if (o.disabled) return;
    if (multiple) {
      const next = selectedArr.includes(o.value)
        ? selectedArr.filter((x) => x !== o.value)
        : [...selectedArr, o.value];
      emit(next);
    } else {
      emit(o.value);
      setOpen(false);
    }
  }
  function remove(v) {
    emit(selectedArr.filter((x) => x !== v));
  }

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

  const classes = ['kole-select', open ? 'is-open' : '', disabled ? 'is-disabled' : '', className]
    .filter(Boolean)
    .join(' ');

  return (
    <div className={classes} ref={rootRef} {...rest}>
      <div className="kole-select-trigger" onClick={() => !disabled && setOpen((o) => !o)} tabIndex={0}>
        {multiple ? (
          selectedArr.length ? (
            selectedArr.map((v) => (
              <span className="tag" key={v}>
                {labelOf(v)}
                <span className="x" onClick={(e) => { e.stopPropagation(); remove(v); }}>✕</span>
              </span>
            ))
          ) : (
            <span className="placeholder">{placeholder}</span>
          )
        ) : selectedVal == null ? (
          <span className="placeholder">{placeholder}</span>
        ) : (
          <span>{labelOf(selectedVal)}</span>
        )}
        <span className="caret">▾</span>
      </div>

      {open && (
        <div className="kole-select-panel">
          {searchable && (
            <div className="kole-select-search">
              <input
                placeholder="输入关键字"
                value={keyword}
                onChange={(e) => setKeyword(e.target.value)}
                onClick={(e) => e.stopPropagation()}
              />
            </div>
          )}

          {groups ? (
            filteredGroups.map((g) => (
              <React.Fragment key={g.label}>
                <div className="kole-select-group-label">{g.label}</div>
                {g.options.map((o) => (
                  <div
                    key={o.value}
                    className={`kole-select-option${isSelected(o.value) ? ' is-selected' : ''}${o.disabled ? ' is-disabled' : ''}`}
                    onClick={() => choose(o)}
                  >
                    {o.label}<span className="check">✓</span>
                  </div>
                ))}
              </React.Fragment>
            ))
          ) : (
            filteredOptions.map((o) => (
              <div
                key={o.value}
                className={`kole-select-option${isSelected(o.value) ? ' is-selected' : ''}${o.disabled ? ' is-disabled' : ''}`}
                onClick={() => choose(o)}
              >
                {o.label}<span className="check">✓</span>
              </div>
            ))
          )}

          {isEmpty && <div className="kole-select-empty">无匹配选项</div>}
        </div>
      )}
    </div>
  );
}

/*
用法示例：
import Select from './Select';

const cities = [{ value: 'bj', label: '北京' }, { value: 'sh', label: '上海' }];
<Select options={cities} placeholder="请选择城市" />
<Select multiple options={cities} defaultValue={['bj']} />
<Select searchable options={cities} />
<Select groups={[{ label: '技术中心', options: cities }]} />
*/
