/**
 * Select — 从预定义 options 中选择（触发器与 Input 同构）
 *
 * **何时用**：选项较多、需省纵向空间、或枚举会扩展；多选且以标签回显用 `mode="tag"`。
 * **不用**：≤5 项且需并排通览比较 → `RadioGroup`；多选且要一眼看到全部选项 → `CheckboxGroup`。
 *
 * @prop {'default'|'error'} [status='default'] — 状态
 * @prop {boolean} [disabled=false] — 是否禁用
 * @prop {boolean} [allowClear=false] — 可清除
 * @prop {'default'|'tag'} [mode='default'] — 选择器形态，tag 为标签选择
 * @prop {string} [aiSuggestion] — Select 下方单条 AI 推荐，点击后映射为既有 option（仅 mode="default"）
 * @prop {Array<string|{label:string,value:string|number}>} [aiSuggestions] — Select 下方多条 AI 推荐（仅 mode="default"）
 * @prop {string} [placeholder='请选择'] — 占位
 * @prop {Array<{value:string|number,label:string,disabled?:boolean,variant?:string}>|null} [options=null] — 选项
 * @prop {string|number|Array} value — 当前值（受控）
 * @prop {string|number|Array|null} [defaultValue=null] — 非受控初值
 * @prop {(value: string|number|undefined, option?: object) => void} [onChange=null] — 变更回调
 * @prop {() => void} [onClear=null] — 清除回调
 * @prop {(value: string|number, option?: object) => void} [onAdoptSuggestion=null] — 采纳 AI 推荐回调（仅 mode="default"）
 * @prop {() => void} [onRefreshAiSuggestions=null] — 刷新 AI 推荐回调（仅 mode="default"）
 * @prop {boolean} [aiSuggestionsLoading=false] — AI 推荐区加载中（仅 mode="default"）
 * @prop {number} [aiSuggestionsLoadingCount=1] — 加载骨架推荐条数（1–5）
 * @prop {import('react').ReactNode} [prefix=null] — 前置内容
 * @prop {import('react').ReactNode} [indicator=null] — 自定义右侧指示器
 * @prop {string} [className=''] — 类名
 */

import {
  useState,
  useRef,
  useCallback,
  useEffect,
  useLayoutEffect,
  useMemo,
  useId,
} from 'react';
import Dropdown from './Dropdown';
import Tag from './Tag';
import { DEFAULT_TAG_RADIUS, DEFAULT_TAG_SIZE, DEFAULT_TAG_VARIANT } from './tagShared';
import Tooltip from './Tooltip';
import AiSuggestionPanel, { AiRefreshButton, rotateList } from './AiSuggestionShared';
import { AiSuggestionPanelSkeleton } from './Skeleton';

/* ── 面板布局 ── */
const DEFAULT_PANEL_GAP = 4;
const PANEL_MAX = 240;

/* ── 触发器容器 ── */
const BASE = [
  'tfds-select',
  /* 默认随父级撑满宽；需固定 300px 时在业务侧包一层 w-[300px]（如 Select 详情预览） */
  'group relative flex w-full min-w-0 max-w-full items-center',
  'border border-solid rounded-md',
  'transition-colors tfds-motion-ui-fast',
  'outline-none',
  '[font-family:inherit]',
].join(' ');

const WRAPPER_CLASS = 'group/select inline-flex w-full max-w-full flex-col items-start gap-1 [font-family:inherit]';

/* ── 触发器状态 ── */
const STATUS_CLASS = {
  default: [
    'bg-surface border-border-default',
    'hover:border-border-strong',
    'data-[open=true]:border-primary',
    'data-[open=true]:hover:border-primary',
  ].join(' '),
  error: [
    'bg-red-50 border-border-default',
    'hover:bg-red-100',
    'data-[open=true]:border-red-500',
    'data-[open=true]:hover:border-red-500 data-[open=true]:hover:bg-red-50',
  ].join(' '),
};

/* ── 触发器尺寸 ── */
const SIZE_CLASS = 'min-h-[36px] pl-3 pr-3 text-sm gap-2';

/* ── 触发器禁用 ── */
const DISABLED_CLASS = 'bg-disabled border-border-default cursor-not-allowed opacity-60';

/* ── 展示文字 ── */
const LABEL_CLASS = [
  'flex-1 min-w-0 text-left leading-[20px] truncate',
  'text-foreground',
].join(' ');

const TAG_CONTENT_ROW = 'flex min-w-0 flex-1 items-center gap-1 overflow-hidden';
const MEASURE_ROW = 'pointer-events-none invisible absolute left-0 top-0 flex items-center gap-1 whitespace-nowrap';

/* ── 占位样式 ── */
const PLACEHOLDER_CLASS = 'text-foreground-muted';
const PREFIX_CLASS = 'inline-flex shrink-0 items-center';

/* ── 下拉箭头 ── */
const CHEVRON_CLASS = [
  'inline-flex size-[16px] shrink-0 items-center justify-center text-foreground-muted transition-transform tfds-motion-ui-fast [&>svg]:size-[16px]',
  'group-data-[open=true]:rotate-180',
].join(' ');

/* ── 清除按钮 ── */
const CLEAR_CLASS = [
  'inline-flex items-center justify-center shrink-0 size-[16px]',
  'rounded-full cursor-pointer',
  'text-foreground-disabled hover:text-foreground-secondary',
  'opacity-0 group-hover/select:opacity-100 transition-opacity tfds-motion-ui-fast',
  'bg-transparent border-none p-0 mr-1',
].join(' ');

const SELECT_AI_REFRESH_CLASS = [
  'inline-flex items-center justify-center shrink-0 size-[var(--spacing-4)]',
  'rounded-full cursor-pointer',
  'text-foreground-muted hover:text-foreground-secondary',
  'opacity-0 group-hover/select:opacity-100 transition-opacity tfds-motion-ui-fast',
  'bg-transparent border-none p-0',
  'transition-colors tfds-motion-ui-fast',
].join(' ');

function getValueKey(value) {
  return String(value);
}

function normalizeSelectedValues(raw) {
  if (Array.isArray(raw)) return raw.map(getValueKey);
  if (raw === null || raw === undefined || raw === '') return [];
  return [getValueKey(raw)];
}

function valuesFromKeys(keys, options) {
  return keys
    .map((key) => options.find((opt) => getValueKey(opt.value) === key)?.value)
    .filter((item) => item !== undefined);
}

function getVisibleCount(tagWidths, moreWidth, availableWidth) {
  if (tagWidths.length === 0) return 0;
  const gap = 4;
  let used = 0;
  for (let i = 0; i < tagWidths.length; i += 1) {
    const remaining = tagWidths.length - i - 1;
    const reserveMore = remaining > 0 ? moreWidth + gap : 0;
    const nextUsed = used + tagWidths[i] + (i > 0 ? gap : 0);
    if (nextUsed + reserveMore <= availableWidth) {
      used = nextUsed;
      continue;
    }
    return Math.max(0, i);
  }
  return tagWidths.length;
}

function normalizeSelectAiSuggestions(aiSuggestion, aiSuggestions, options) {
  const source = Array.isArray(aiSuggestions) && aiSuggestions.length > 0
    ? aiSuggestions
    : (typeof aiSuggestion === 'string' && aiSuggestion.trim().length > 0 ? [aiSuggestion] : []);

  return source
    .map((item, index) => {
      if (typeof item === 'string') {
        const label = item.trim();
        if (!label) return null;
        const option = options.find((opt) => String(opt.label) === label);
        if (!option) return null;
        return {
          id: `select-ai-suggestion-${index}-${getValueKey(option.value)}`,
          label,
          value: option.value,
          option,
        };
      }

      if (!item || typeof item !== 'object') return null;

      const hasValue = item.value !== undefined && item.value !== null && item.value !== '';
      const hasLabel = typeof item.label === 'string' && item.label.trim().length > 0;
      const option = hasValue
        ? options.find((opt) => getValueKey(opt.value) === getValueKey(item.value))
        : options.find((opt) => String(opt.label) === item.label.trim());

      if (!option) return null;

      return {
        id: `select-ai-suggestion-${index}-${getValueKey(option.value)}`,
        label: hasLabel ? item.label.trim() : String(option.label),
        value: option.value,
        option,
      };
    })
    .filter(Boolean);
}

function buildSelectSuggestionGroups(aiSuggestion, aiSuggestions, options) {
  const hasSource = (typeof aiSuggestion === 'string' && aiSuggestion.trim().length > 0)
    || (Array.isArray(aiSuggestions) && aiSuggestions.length > 0);
  if (!hasSource) return [];

  const baseGroup = normalizeSelectAiSuggestions(aiSuggestion, aiSuggestions, options);
  const groups = [];
  const serialized = new Set();

  const pushGroup = (group) => {
    if (!Array.isArray(group) || group.length === 0) return;
    const key = JSON.stringify(group.map((item) => getValueKey(item.value)));
    if (serialized.has(key)) return;
    serialized.add(key);
    groups.push(group);
  };

  pushGroup(baseGroup);

  if (baseGroup.length > 1) {
    for (let offset = 1; offset < baseGroup.length; offset += 1) {
      pushGroup(rotateList(baseGroup, offset));
    }
  }

  const optionSuggestions = options
    .filter((opt) => !opt.disabled)
    .map((option, index) => ({
      id: `select-ai-option-${index}-${getValueKey(option.value)}`,
      label: String(option.label),
      value: option.value,
      option,
    }));
  const groupSize = Math.max(1, Math.min(baseGroup.length || 1, optionSuggestions.length));

  if (optionSuggestions.length > 0) {
    for (let offset = 0; offset < optionSuggestions.length; offset += 1) {
      pushGroup(rotateList(optionSuggestions, offset).slice(0, groupSize));
    }
  }

  return groups;
}

export default function Select({
  options = null,
  value,
  defaultValue = null,
  onChange = null,
  onClear = null,
  aiSuggestion,
  aiSuggestions,
  placeholder = '请选择',
  mode = 'default',
  size: _size = 'md',
  status = 'default',
  disabled = false,
  allowClear = false,
  onAdoptSuggestion = null,
  onRefreshAiSuggestions = null,
  aiSuggestionsLoading = false,
  aiSuggestionsLoadingCount = 1,
  panelGap = DEFAULT_PANEL_GAP,
  tagVariant: _legacyTagVariant = DEFAULT_TAG_VARIANT,
  tagSize: _legacyTagSize = DEFAULT_TAG_SIZE,
  prefix = null,
  indicator = null,
  className = '',
  ...rest
}) {
  const optionList = options ?? [];
  const isTagMode = mode === 'tag';
  const uid = useId();
  const listboxId = `${uid}-listbox`;
  const isControlled = value !== undefined;
  const [innerValue, setInnerValue] = useState(defaultValue);
  const [isSuggestionDismissed, setIsSuggestionDismissed] = useState(false);
  const [suggestionIndex, setSuggestionIndex] = useState(0);
  const currentValue = isControlled ? value : innerValue;
  const selectedValueKeys = useMemo(() => normalizeSelectedValues(currentValue), [currentValue]);

  const [open, setOpen] = useState(false);
  const [highlight, setHighlight] = useState(-1);
  const [visibleCount, setVisibleCount] = useState(null);

  const triggerRef = useRef(null);
  const measureRef = useRef(null);
  const moreMeasureRef = useRef(null);

  const selected = useMemo(
    () => optionList.find((o) => getValueKey(o.value) === getValueKey(currentValue)),
    [optionList, currentValue],
  );
  const selectedTagOptions = useMemo(
    () => selectedValueKeys
      .map((key) => optionList.find((o) => getValueKey(o.value) === key))
      .filter(Boolean),
    [optionList, selectedValueKeys],
  );
  const hasValue = isTagMode ? selectedTagOptions.length > 0 : selected != null;
  const showClear = allowClear && !disabled && hasValue;
  const hasAiSuggestionSource = !isTagMode && (
    (typeof aiSuggestion === 'string' && aiSuggestion.trim().length > 0)
    || (Array.isArray(aiSuggestions) && aiSuggestions.length > 0)
  );
  const suggestionGroups = useMemo(
    () => (isTagMode ? [] : buildSelectSuggestionGroups(aiSuggestion, aiSuggestions, optionList)),
    [aiSuggestion, aiSuggestions, isTagMode, optionList],
  );
  const normalizedAiSuggestions = suggestionGroups[suggestionIndex] || suggestionGroups[0] || [];
  const canRefreshLocally = suggestionGroups.length > 1;
  const showSuggestion = !disabled && !isTagMode && !isSuggestionDismissed && normalizedAiSuggestions.length > 0;
  const showAiRefresh = !disabled && !isTagMode && hasAiSuggestionSource
    && (canRefreshLocally || typeof onRefreshAiSuggestions === 'function');

  const commit = useCallback((nextVal, opt) => {
    if (!isControlled) setInnerValue(nextVal);
    onChange?.(nextVal, opt);
  }, [isControlled, onChange]);

  const measureTags = useCallback(() => {
    if (!isTagMode) return;
    const root = triggerRef.current;
    const row = measureRef.current;
    if (!root || !row) return;
    const reservedRight = 36 + (showClear ? 20 : 0) + (showAiRefresh ? 20 : 0);
    const availableWidth = Math.max(0, root.clientWidth - reservedRight - 24);
    const tagWidths = Array.from(row.querySelectorAll('[data-measure-tag]'))
      .map((node) => Math.ceil(node.getBoundingClientRect().width));
    const moreWidth = Math.ceil(moreMeasureRef.current?.getBoundingClientRect().width || 34);
    setVisibleCount(getVisibleCount(tagWidths, moreWidth, availableWidth));
  }, [isTagMode, showAiRefresh, showClear]);

  useEffect(() => {
    setIsSuggestionDismissed(false);
    setSuggestionIndex(0);
  }, [aiSuggestion, aiSuggestions]);

  useLayoutEffect(() => {
    measureTags();
  }, [measureTags, selectedTagOptions, status]);

  useEffect(() => {
    if (!isTagMode || !triggerRef.current || typeof ResizeObserver === 'undefined') return undefined;
    const observer = new ResizeObserver(() => measureTags());
    observer.observe(triggerRef.current);
    return () => observer.disconnect();
  }, [isTagMode, measureTags]);

  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      const t = e.target;
      if (triggerRef.current?.contains(t)) return;
      const panelEl = document.getElementById(listboxId);
      if (panelEl?.contains(t)) return;
      setOpen(false);
      setHighlight(-1);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open, listboxId]);

  useEffect(() => {
    if (!open || highlight < 0) return;
    const panelEl = document.getElementById(listboxId);
    const el = panelEl?.querySelector(`[data-option-index="${highlight}"]`);
    el?.scrollIntoView({ block: 'nearest' });
  }, [highlight, open, listboxId]);

  const toggleOpen = useCallback(() => {
    if (disabled) return;
    setOpen((o) => {
      const next = !o;
      if (next) {
        const activeKey = isTagMode ? selectedValueKeys[0] : getValueKey(currentValue);
        const si = optionList.findIndex((x) => getValueKey(x.value) === activeKey);
        setHighlight(si >= 0 ? si : 0);
      } else {
        setHighlight(-1);
      }
      return next;
    });
  }, [disabled, optionList, currentValue, isTagMode, selectedValueKeys]);

  const pick = useCallback((opt) => {
    if (opt.disabled) return;
    if (isTagMode) {
      const key = getValueKey(opt.value);
      const nextKeys = selectedValueKeys.includes(key)
        ? selectedValueKeys.filter((item) => item !== key)
        : [...selectedValueKeys, key];
      commit(valuesFromKeys(nextKeys, optionList), opt);
      return;
    }
    commit(opt.value, opt);
    setOpen(false);
    setHighlight(-1);
  }, [commit, isTagMode, selectedValueKeys]);

  const removeTag = useCallback((opt, event) => {
    event?.stopPropagation();
    if (disabled || !isTagMode) return;
    const key = getValueKey(opt.value);
    commit(valuesFromKeys(selectedValueKeys.filter((item) => item !== key), optionList), opt);
  }, [commit, disabled, isTagMode, optionList, selectedValueKeys]);

  const handleClear = useCallback((e) => {
    e.stopPropagation();
    if (disabled) return;
    commit(isTagMode ? [] : undefined, undefined);
    onClear?.();
    setOpen(false);
    setHighlight(-1);
  }, [disabled, commit, isTagMode, onClear]);

  const handleAdoptSuggestion = useCallback((suggestion) => {
    if (!suggestion?.option || disabled || isTagMode) return;
    commit(suggestion.value, suggestion.option);
    onAdoptSuggestion?.(suggestion.value, suggestion.option);
    setIsSuggestionDismissed(true);
    setOpen(false);
    setHighlight(-1);
    triggerRef.current?.focus();
  }, [commit, disabled, isTagMode, onAdoptSuggestion]);

  const handleRefreshAiSuggestions = useCallback((event) => {
    event?.stopPropagation();
    if (disabled || isTagMode) return;
    setOpen(false);
    setHighlight(-1);
    if (canRefreshLocally) {
      setSuggestionIndex((prev) => (prev + 1) % suggestionGroups.length);
    }
    setIsSuggestionDismissed(false);
    onRefreshAiSuggestions?.();
    triggerRef.current?.focus();
  }, [canRefreshLocally, disabled, isTagMode, onRefreshAiSuggestions, suggestionGroups.length]);

  const onTriggerKeyDown = useCallback((e) => {
    if (disabled) return;
    if (e.key === 'Escape') {
      if (open) {
        e.preventDefault();
        setOpen(false);
        setHighlight(-1);
      }
      return;
    }
    if (e.key === 'Enter' || e.key === ' ') {
      if (!open) {
        e.preventDefault();
        setOpen(true);
        const activeKey = isTagMode ? selectedValueKeys[0] : getValueKey(currentValue);
        const si = optionList.findIndex((x) => getValueKey(x.value) === activeKey);
        setHighlight(si >= 0 ? si : 0);
      } else if (highlight >= 0 && optionList[highlight] && !optionList[highlight].disabled) {
        e.preventDefault();
        pick(optionList[highlight]);
      }
      return;
    }
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (!open) {
        setOpen(true);
        setHighlight(0);
        return;
      }
      setHighlight((h) => {
        let i = h < 0 ? 0 : h;
        for (let step = 0; step < optionList.length; step += 1) {
          i = (i + 1) % optionList.length;
          if (!optionList[i]?.disabled) return i;
        }
        return h;
      });
    }
    if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (!open) {
        setOpen(true);
        setHighlight(optionList.length - 1);
        return;
      }
      setHighlight((h) => {
        let i = h < 0 ? optionList.length - 1 : h;
        for (let step = 0; step < optionList.length; step += 1) {
          i = (i - 1 + optionList.length) % optionList.length;
          if (!optionList[i]?.disabled) return i;
        }
        return h;
      });
    }
    if (e.key === 'Tab' && open) {
      setOpen(false);
      setHighlight(-1);
    }
  }, [disabled, open, optionList, highlight, currentValue, isTagMode, selectedValueKeys, pick]);

  const containerCls = [
    BASE,
    disabled ? DISABLED_CLASS : STATUS_CLASS[status],
    SIZE_CLASS,
    className,
  ].filter(Boolean).join(' ');

  const safeVisibleCount = visibleCount == null
    ? selectedTagOptions.length
    : Math.min(visibleCount, selectedTagOptions.length);
  const visibleTagOptions = selectedTagOptions.slice(0, safeVisibleCount);
  const hiddenTagOptions = selectedTagOptions.slice(safeVisibleCount);

  const renderTag = (opt, tagProps = {}) => (
    <Tag
      key={getValueKey(opt.value)}
      variant={opt.variant || DEFAULT_TAG_VARIANT}
      size={DEFAULT_TAG_SIZE}
      radius={DEFAULT_TAG_RADIUS}
      {...tagProps}
    >
      {opt.label}
    </Tag>
  );

  const hiddenContent = hiddenTagOptions.length > 0 ? (
    <div className="flex max-w-[248px] flex-wrap gap-1">
      {hiddenTagOptions.map((opt) => renderTag(opt))}
    </div>
  ) : null;

  const listPanel = (
    <Dropdown.Panel
      open={open && !disabled}
      triggerRef={triggerRef}
      gap={panelGap}
      maxHeight={PANEL_MAX}
      matchTriggerWidth
      id={listboxId}
      role="listbox"
    >
      <Dropdown.List
        mode="select"
        selectionIndicator={isTagMode ? 'leading-check' : 'row-highlight'}
        multiple={isTagMode}
      >
        {optionList.length === 0 ? (
          <Dropdown.Empty>暂无数据</Dropdown.Empty>
        ) : (
          optionList.map((opt, i) => {
            const selectedOpt = isTagMode
              ? selectedValueKeys.includes(getValueKey(opt.value))
              : getValueKey(opt.value) === getValueKey(currentValue);
            return (
              <Dropdown.Item
                key={`${String(opt.value)}-${i}`}
                value={opt.value}
                label={opt.label}
                selected={selectedOpt}
                disabled={opt.disabled}
                highlighted={isTagMode && highlight === i && !selectedOpt && !opt.disabled}
                data-option-index={i}
                onMouseEnter={() => !opt.disabled && setHighlight(i)}
                onMouseDown={(event) => event.preventDefault()}
                onClick={() => pick(opt)}
              />
            );
          })
        )}
      </Dropdown.List>
    </Dropdown.Panel>
  );

  return (
    <div className={WRAPPER_CLASS}>
      <div
        ref={triggerRef}
        {...rest}
        role="combobox"
        aria-expanded={open}
        aria-controls={listboxId}
        aria-haspopup="listbox"
        aria-disabled={disabled || undefined}
        data-open={open}
        data-tfds-component="Select"
        tabIndex={disabled ? -1 : 0}
        className={containerCls}
        onClick={toggleOpen}
        onKeyDown={onTriggerKeyDown}
      >
        {prefix ? <span className={PREFIX_CLASS}>{prefix}</span> : null}
        {isTagMode ? (
          <span className={TAG_CONTENT_ROW}>
            {hasValue ? (
              <>
                {visibleTagOptions.map((opt) => (
                  renderTag(opt, {
                    closable: !disabled,
                    onClose: !disabled ? (event) => removeTag(opt, event) : undefined,
                  })
                ))}
                {hiddenTagOptions.length > 0 ? (
                  <Tooltip
                    content={hiddenContent}
                    tone="light"
                    placement="top"
                    triggerClassName="inline-flex shrink-0"
                    className="!max-w-[280px]"
                  >
                    <Tag variant={DEFAULT_TAG_VARIANT} size={DEFAULT_TAG_SIZE} radius={DEFAULT_TAG_RADIUS}>+{hiddenTagOptions.length}</Tag>
                  </Tooltip>
                ) : null}
              </>
            ) : (
              <span className={PLACEHOLDER_CLASS}>{placeholder}</span>
            )}
          </span>
        ) : (
          <span className={hasValue ? LABEL_CLASS : `${LABEL_CLASS} ${PLACEHOLDER_CLASS}`}>
            {hasValue ? selected.label : placeholder}
          </span>
        )}
        {showClear ? (
          <button
            type="button"
            className={CLEAR_CLASS}
            onClick={handleClear}
            aria-label="清除"
            tabIndex={-1}
          >
            <svg viewBox="0 0 16 16" fill="none" className="size-[16px]">
              <circle cx="8" cy="8" r="7" fill="currentColor" fillOpacity="0.15" />
              <path d="M5.5 5.5L10.5 10.5M10.5 5.5L5.5 10.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
            </svg>
          </button>
        ) : null}
        {showAiRefresh ? (
          <AiRefreshButton onClick={handleRefreshAiSuggestions} className={SELECT_AI_REFRESH_CLASS} />
        ) : null}
        {indicator ? (
          <span className="inline-flex size-[16px] shrink-0 items-center justify-center [&>svg]:size-[16px]" aria-hidden>
            {indicator}
          </span>
        ) : (
          <span className={CHEVRON_CLASS} aria-hidden>
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" className="shrink-0">
              <path d="M4 6L8 10L12 6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </span>
        )}
        {isTagMode ? (
          <span ref={measureRef} className={MEASURE_ROW} aria-hidden>
            {selectedTagOptions.map((opt) => (
              <span key={getValueKey(opt.value)} data-measure-tag>
                {renderTag(opt, { closable: !disabled })}
              </span>
            ))}
            <span ref={moreMeasureRef}>
              <Tag variant={DEFAULT_TAG_VARIANT} size={DEFAULT_TAG_SIZE} radius={DEFAULT_TAG_RADIUS}>+99</Tag>
            </span>
          </span>
        ) : null}
      </div>
      {aiSuggestionsLoading && !isTagMode ? (
        <AiSuggestionPanelSkeleton count={aiSuggestionsLoadingCount} />
      ) : null}
      {!aiSuggestionsLoading && showSuggestion ? (
        <AiSuggestionPanel
          suggestions={normalizedAiSuggestions}
          onSelect={handleAdoptSuggestion}
          getSuggestionKey={(suggestion) => suggestion.id}
          getSuggestionLabel={(suggestion) => suggestion.label}
          getSuggestionAriaLabel={(suggestion, index) => `采纳 AI 推荐选项 ${index + 1}：${suggestion.label}`}
        />
      ) : null}
      {listPanel}
    </div>
  );
}
