/**
 * InfoDisplayPanel — 信息展示面板框架
 *
 * 用于客服工作台 / 在线 Agent / 工单详情右侧信息区，将多个可切换的信息面板
 * 组织为“主栏 + 拆分栏”结构。组件只负责框架、拆分/合并和 Tabs，不规定 tabs 内容。
 * tabs 来自业务数据动态配置：1 个分类单栏展示，2 个分类最多双栏，3 个及以上分类且宽度足够时最多三栏。
 * 嵌入客服工作台框架时，必须保留整体信息栏拖拽、内部栏间拖拽、拆分/合并和最小宽度保护。
 */

import { useEffect, useMemo, useRef, useState } from 'react';
import Button from './Button';
import FormTitle from './FormTitle';
import Icon from './Icon';
import Tabs from './Tabs';
import { tfdsResizeHandleLineClass } from '../shared/resize-handle';

const DEFAULT_PANELS = [
  {
    id: 'assistant',
    tabs: [
      { id: 'assistant', label: '托管助手' },
    ],
  },
  {
    id: 'tickets',
    tabs: [
      { id: 'history', label: '历史工单' },
      { id: 'logs', label: '工单日志' },
      { id: 'tools', label: '信息工具' },
    ],
  },
  {
    id: 'info',
    tabs: [
      { id: 'video', label: '视频信息' },
      { id: 'user', label: '用户命中实验' },
      { id: 'records', label: '沟通记录' },
    ],
  },
];

const MIN_PANEL_WIDTH = 200;
const DIVIDER_WIDTH = 1;
const MAX_COLUMNS = 3;
const MAIN_PANEL_ID = 'main';
const SPLIT_ACTION_ICON = 'layout-right-stroked';
const MERGE_ACTION_ICON = 'layout-left-stroked';
const RESIZE_HANDLE_WIDTH = 8;

const ROOT_SHELL = [
  'tfds-info-display-panel',
  'relative flex h-full min-h-0 w-full min-w-[200px] overflow-hidden rounded-xl bg-surface text-foreground',
  '[font-family:inherit]',
].join(' ');
const ROOT_BORDERED = 'border border-border-default';
const ROOT_BORDERLESS = 'border-0';
const PANEL = 'flex min-w-0 flex-col bg-surface';
const PANEL_DIVIDER = 'border-l border-border-default';
const HEADER = 'relative flex h-[56px] shrink-0 items-center justify-between gap-3 px-4';
const TABS_WRAP = 'flex h-full min-w-0 flex-1 items-center overflow-hidden';
const ACTIONS = 'flex shrink-0 items-center gap-1';
const HEADER_LINE = 'pointer-events-none absolute inset-x-0 bottom-0 h-px bg-border-default';
const CONTENT = 'flex min-h-0 flex-1 flex-col gap-4 overflow-auto p-4 [&>*]:min-w-0 [&>*]:w-full';
const RESIZE_HANDLE = [
  'group/info-resize absolute inset-y-0 z-20 flex w-2 cursor-col-resize items-stretch justify-center border-0 bg-transparent p-0',
  'touch-none select-none',
  'focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-blueGrey-400',
].join(' ');
const RESIZE_HANDLE_LINE = tfdsResizeHandleLineClass('info-resize', { sizeClass: 'h-full' });

function clamp(value, min, max) {
  return Math.min(max, Math.max(min, value));
}

function normalizePanels(panels) {
  return Array.isArray(panels) && panels.length > 0 ? panels : DEFAULT_PANELS;
}

function getMinWidthForColumns(columnCount, minPanelWidth = MIN_PANEL_WIDTH) {
  if (columnCount <= 0) return 0;
  return (columnCount * minPanelWidth) + ((columnCount - 1) * DIVIDER_WIDTH);
}

function getMaxColumns(width, minPanelWidth = MIN_PANEL_WIDTH) {
  if (!Number.isFinite(width) || width <= 0) return 1;
  if (width >= getMinWidthForColumns(3, minPanelWidth)) return 3;
  if (width >= getMinWidthForColumns(2, minPanelWidth)) return 2;
  return 1;
}

function normalizeTabs(panel) {
  const tabs = Array.isArray(panel.tabs) && panel.tabs.length > 0
    ? panel.tabs
    : [{ id: panel.id, label: panel.title || '信息' }];

  return tabs.map((tab, index) => ({
    ...tab,
    id: typeof tab.id === 'string' && tab.id ? tab.id : `${panel.id}-${index}`,
    sourcePanelId: panel.id,
    sourcePanel: panel,
  }));
}

function buildTabDescriptors(panels) {
  return panels.flatMap((panel) => normalizeTabs(panel));
}

function buildEvenWidths(count, totalWidth, minWidth) {
  if (count <= 0) return [];
  if (!Number.isFinite(totalWidth) || totalWidth <= 0) {
    return Array.from({ length: count }, () => minWidth);
  }
  const evenWidth = totalWidth / count;
  return normalizeColumnWidths(
    Array.from({ length: count }, () => evenWidth),
    totalWidth,
    minWidth,
  );
}

function normalizeColumnWidths(rawWidths, totalWidth, minWidth) {
  const count = Array.isArray(rawWidths) ? rawWidths.length : 0;
  if (count === 0) return [];
  if (!Number.isFinite(totalWidth) || totalWidth <= 0) {
    return Array.from({ length: count }, () => minWidth);
  }

  const minTotalWidth = count * minWidth;
  if (totalWidth <= minTotalWidth) {
    return Array.from({ length: count }, (_, index) => (
      index === count - 1
        ? Math.max(minWidth, totalWidth - minWidth * (count - 1))
        : minWidth
    ));
  }

  let widths = rawWidths.map((width) => (
    Number.isFinite(width) && width > 0 ? width : minWidth
  ));

  while (widths.length < count) widths.push(minWidth);
  widths = widths.slice(0, count).map((width) => Math.max(minWidth, width));

  let total = widths.reduce((sum, width) => sum + width, 0);
  if (total < totalWidth) {
    const extra = (totalWidth - total) / count;
    widths = widths.map((width) => width + extra);
    total = widths.reduce((sum, width) => sum + width, 0);
  }

  if (total > totalWidth) {
    let overflow = total - totalWidth;
    while (overflow > 0.5) {
      const flexibleIndexes = widths
        .map((width, index) => ({ width, index }))
        .filter((item) => item.width > minWidth + 0.5);
      if (flexibleIndexes.length === 0) break;
      const share = overflow / flexibleIndexes.length;
      flexibleIndexes.forEach(({ index }) => {
        const reducible = widths[index] - minWidth;
        const delta = Math.min(share, reducible, overflow);
        widths[index] -= delta;
        overflow -= delta;
      });
    }
  }

  const normalizedTotal = widths.reduce((sum, width) => sum + width, 0);
  widths[count - 1] += totalWidth - normalizedTotal;
  return widths;
}

function reconcileColumnWidths(previousWidths, count, totalWidth, minWidth) {
  if (count <= 0) return [];
  if (!Array.isArray(previousWidths) || previousWidths.length !== count) {
    return buildEvenWidths(count, totalWidth, minWidth);
  }
  return normalizeColumnWidths(previousWidths, totalWidth, minWidth);
}

function resizeAdjacentColumns(widths, leftIndex, delta, minWidth) {
  if (leftIndex < 0 || leftIndex >= widths.length - 1) return widths;
  const nextWidths = [...widths];
  const pairTotal = nextWidths[leftIndex] + nextWidths[leftIndex + 1];
  const nextLeftWidth = clamp(nextWidths[leftIndex] + delta, minWidth, pairTotal - minWidth);
  nextWidths[leftIndex] = nextLeftWidth;
  nextWidths[leftIndex + 1] = pairTotal - nextLeftWidth;
  return nextWidths;
}

function resolveInitialMainActiveTab(tabDescriptors, defaultActiveTabs) {
  if (!Array.isArray(tabDescriptors) || tabDescriptors.length === 0) return '';
  if (defaultActiveTabs && typeof defaultActiveTabs === 'object') {
    const preferredIds = [
      defaultActiveTabs[MAIN_PANEL_ID],
      ...tabDescriptors.map((tab) => defaultActiveTabs[tab.sourcePanelId]),
    ].filter((value) => typeof value === 'string' && value);

    const matched = preferredIds.find((value) => tabDescriptors.some((tab) => tab.id === value));
    if (matched) return matched;
  }
  return tabDescriptors[0]?.id ?? '';
}

function resolveControlledMainActiveTab(tabDescriptors, activeTabs, fallbackTabId) {
  if (!Array.isArray(tabDescriptors) || tabDescriptors.length === 0) return '';
  if (activeTabs && typeof activeTabs === 'object') {
    const preferredIds = [
      activeTabs[MAIN_PANEL_ID],
      ...tabDescriptors.map((tab) => activeTabs[tab.sourcePanelId]),
    ].filter((value) => typeof value === 'string' && value);

    const matched = preferredIds.find((value) => tabDescriptors.some((tab) => tab.id === value));
    if (matched) return matched;
  }
  return fallbackTabId && tabDescriptors.some((tab) => tab.id === fallbackTabId)
    ? fallbackTabId
    : (tabDescriptors[0]?.id ?? '');
}

function buildVisiblePanels(tabDescriptors, splitTabIds, mainActiveTabId) {
  const tabMap = new Map(tabDescriptors.map((tab) => [tab.id, tab]));
  const normalizedSplitTabIds = splitTabIds.filter((tabId) => tabMap.has(tabId));
  const splitTabIdSet = new Set(normalizedSplitTabIds);
  const mainTabs = tabDescriptors.filter((tab) => !splitTabIdSet.has(tab.id));
  const resolvedMainActiveTabId = mainTabs.some((tab) => tab.id === mainActiveTabId)
    ? mainActiveTabId
    : (mainTabs[0]?.id ?? '');

  const splitPanels = normalizedSplitTabIds.map((tabId, index) => {
    const tab = tabMap.get(tabId);
    return {
      id: `split:${tab.id}`,
      kind: 'split',
      order: index,
      tabs: [tab],
      activeTabId: tab.id,
      tab,
      sourcePanel: tab.sourcePanel,
      sourcePanelId: tab.sourcePanelId,
    };
  });

  const activeMainTab = mainTabs.find((tab) => tab.id === resolvedMainActiveTabId) ?? mainTabs[0] ?? null;
  const mainPanel = {
    id: MAIN_PANEL_ID,
    kind: 'main',
    tabs: mainTabs,
    activeTabId: resolvedMainActiveTabId,
    tab: activeMainTab,
    sourcePanel: activeMainTab?.sourcePanel ?? null,
    sourcePanelId: activeMainTab?.sourcePanelId ?? '',
  };

  return {
    splitPanels,
    mainPanel,
    visiblePanels: [...splitPanels, mainPanel],
    normalizedSplitTabIds,
    mainTabs,
    resolvedMainActiveTabId,
  };
}

function PanelHeader({
  panel,
  activeTabId,
  onTabChange,
  onSplitAction,
  splitActionLabel,
  splitActionTitle,
  splitActionIcon,
  splitActionDisabled,
  useTitleFallback,
  onClose,
  closeActionLabel,
  showFrameBorder = true,
}) {
  const tabs = Array.isArray(panel.tabs) && panel.tabs.length > 0
    ? panel.tabs
    : [{ id: panel.id, label: panel.title || '信息' }];
  const activeIndex = Math.max(0, tabs.findIndex((tab) => tab.id === activeTabId));
  const splitActionTooltip = splitActionDisabled
    ? '空间不够，暂不支持拆分'
    : splitActionTitle;
  /**
   * 关闭按钮显示策略：
   *   仅当外部显式传入 `onClose` 回调时渲染，且必须满足：
   *     ① panel.kind === 'main'（最右侧主 tab 栏）；
   *     ② !useTitleFallback（即当前是多 tab 模式，单标题降级态不显示）。
   *   该能力专为「工单 Agent 工作台框架」模板设计：用户点击底部 AgentStatusBar 的"查看
   *   详情"按钮展开右侧 InfoDisplayPanel 后，可以通过这个关闭按钮把信息栏整体关掉。
   *   其它模板（如客服工作台框架）不传 `onClose`，按钮不出现，能力天然隔离。
   */
  const showCloseAction = typeof onClose === 'function' && panel.kind === 'main' && !useTitleFallback;

  return (
    <div className={HEADER} data-tfds-component="InfoDisplayPanel.Header">
      <div className={TABS_WRAP}>
        {useTitleFallback ? (
          <FormTitle
            variant="card"
            title={panel.title || tabs[activeIndex]?.label || tabs[0]?.label || '信息'}
            className="min-w-0"
          />
        ) : (
          <Tabs
            variant="line"
            size="lg"
            items={tabs.map((tab) => ({ label: tab.label, icon: tab.icon }))}
            activeIndex={activeIndex}
            onChange={(nextIndex) => {
              const nextTab = tabs[nextIndex];
              if (nextTab) onTabChange(panel.id, nextTab.id);
            }}
            aria-label={`${panel.title || tabs[0]?.label || '信息'} tabs`}
            className="flex w-full max-w-full !border-b-0"
          />
        )}
      </div>

      {!useTitleFallback ? (
        <div className={ACTIONS}>
          <Button
            type="button"
            variant="ghost-black"
            size="md"
            icon={<Icon name={splitActionIcon} size={16} />}
            iconOnly
            tooltip={splitActionTooltip}
            disabled={splitActionDisabled}
            aria-label={splitActionLabel}
            onClick={onSplitAction}
          />
          {showCloseAction ? (
            <Button
              type="button"
              variant="ghost-black"
              size="md"
              icon={<Icon name="x-close-stroked" size={16} />}
              iconOnly
              tooltip={closeActionLabel || '关闭信息栏'}
              aria-label={closeActionLabel || '关闭信息栏'}
              onClick={onClose}
            />
          ) : null}
        </div>
      ) : null}
      {showFrameBorder ? <span className={HEADER_LINE} aria-hidden="true" /> : null}
    </div>
  );
}

export default function InfoDisplayPanel({
  panels = DEFAULT_PANELS,
  columnCount,
  defaultColumnCount = MAX_COLUMNS,
  onColumnCountChange,
  minPanelWidth = MIN_PANEL_WIDTH,
  activeTabs,
  defaultActiveTabs,
  onTabChange,
  onSplitChange,
  renderPanelContent,
  onClose,
  closeActionLabel,
  showFrameBorder = true,
  className = '',
  style = null,
}) {
  const rootRef = useRef(null);
  const panelItems = useMemo(() => normalizePanels(panels), [panels]);
  const tabDescriptors = useMemo(() => buildTabDescriptors(panelItems), [panelItems]);
  const isTabsControlled = activeTabs && typeof activeTabs === 'object';
  const [rootWidth, setRootWidth] = useState(0);
  const [splitTabIds, setSplitTabIds] = useState([]);
  const [columnWidths, setColumnWidths] = useState([]);
  const [innerMainActiveTabId, setInnerMainActiveTabId] = useState(() => (
    resolveInitialMainActiveTab(tabDescriptors, defaultActiveTabs)
  ));

  const useTitleFallback = tabDescriptors.length <= 1;
  const maxColumnCount = getMaxColumns(rootWidth, minPanelWidth);
  const legacyColumnLimit = clamp(
    typeof columnCount === 'number' ? columnCount : defaultColumnCount,
    1,
    MAX_COLUMNS,
  );
  const allowedColumnCount = Math.min(maxColumnCount, legacyColumnLimit, MAX_COLUMNS, Math.max(1, tabDescriptors.length));
  const resolvedMainActiveTabId = isTabsControlled
    ? resolveControlledMainActiveTab(tabDescriptors, activeTabs, innerMainActiveTabId)
    : innerMainActiveTabId;
  const {
    visiblePanels,
    normalizedSplitTabIds,
    mainTabs,
    resolvedMainActiveTabId: sanitizedMainActiveTabId,
  } = useMemo(
    () => buildVisiblePanels(tabDescriptors, splitTabIds, resolvedMainActiveTabId),
    [tabDescriptors, splitTabIds, resolvedMainActiveTabId],
  );
  const visibleColumnCount = visiblePanels.length;

  useEffect(() => {
    const node = rootRef.current;
    if (!node) return undefined;

    function updateWidth() {
      setRootWidth(node.getBoundingClientRect().width);
    }

    updateWidth();
    const observer = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(updateWidth) : null;
    observer?.observe(node);
    window.addEventListener('resize', updateWidth);

    return () => {
      observer?.disconnect();
      window.removeEventListener('resize', updateWidth);
    };
  }, []);

  useEffect(() => {
    const nextMainActiveTabId = resolveInitialMainActiveTab(tabDescriptors, defaultActiveTabs);
    setInnerMainActiveTabId((current) => {
      if (current && tabDescriptors.some((tab) => tab.id === current)) return current;
      return nextMainActiveTabId;
    });
  }, [defaultActiveTabs, tabDescriptors]);

  useEffect(() => {
    setSplitTabIds((prev) => {
      const sanitized = prev.filter((tabId) => tabDescriptors.some((tab) => tab.id === tabId));
      if (sanitized.length === prev.length) return prev;
      return sanitized;
    });
  }, [tabDescriptors]);

  useEffect(() => {
    const maxSplitCount = Math.max(0, allowedColumnCount - 1);
    setSplitTabIds((prev) => {
      if (prev.length <= maxSplitCount) return prev;
      return prev.slice(0, maxSplitCount);
    });
  }, [allowedColumnCount]);

  useEffect(() => {
    if (isTabsControlled) return;
    if (sanitizedMainActiveTabId && sanitizedMainActiveTabId !== innerMainActiveTabId) {
      setInnerMainActiveTabId(sanitizedMainActiveTabId);
    }
  }, [innerMainActiveTabId, isTabsControlled, sanitizedMainActiveTabId]);

  useEffect(() => {
    setColumnWidths((prev) => reconcileColumnWidths(prev, visibleColumnCount, rootWidth, minPanelWidth));
  }, [minPanelWidth, rootWidth, visibleColumnCount]);

  function emitSplitChange(nextSplitTabIds) {
    const nextState = buildVisiblePanels(tabDescriptors, nextSplitTabIds, resolvedMainActiveTabId);
    onSplitChange?.({
      splitTabIds: nextState.normalizedSplitTabIds,
      visibleColumns: nextState.visiblePanels.length,
      panels: nextState.visiblePanels,
    });
    onColumnCountChange?.(nextState.visiblePanels.length);
  }

  function handleTabChange(columnId, tabId) {
    if (columnId === MAIN_PANEL_ID && !isTabsControlled) {
      setInnerMainActiveTabId(tabId);
    }
    const activeDescriptor = tabDescriptors.find((tab) => tab.id === tabId);
    onTabChange?.({
      panelId: activeDescriptor?.sourcePanelId ?? columnId,
      tabId,
      columnId,
      isSplit: columnId !== MAIN_PANEL_ID,
    });
  }

  function handleSplitTab() {
    if (!sanitizedMainActiveTabId) return;
    if (normalizedSplitTabIds.length + 1 >= allowedColumnCount) return;
    if (mainTabs.length <= 1) return;
    const nextSplitTabIds = [...normalizedSplitTabIds, sanitizedMainActiveTabId];
    const nextMainTabs = tabDescriptors.filter((tab) => !nextSplitTabIds.includes(tab.id));
    const nextMainActiveTabId = nextMainTabs[0]?.id ?? '';
    if (!isTabsControlled) setInnerMainActiveTabId(nextMainActiveTabId);
    setSplitTabIds(nextSplitTabIds);
    emitSplitChange(nextSplitTabIds);
  }

  function handleMergeTab(tabId) {
    const nextSplitTabIds = normalizedSplitTabIds.filter((currentId) => currentId !== tabId);
    setSplitTabIds(nextSplitTabIds);
    emitSplitChange(nextSplitTabIds);
  }

  function updateColumnWidths(nextWidths) {
    setColumnWidths(normalizeColumnWidths(nextWidths, rootWidth, minPanelWidth));
  }

  function resizeColumnsByHandle(handleIndex, delta) {
    if (!Array.isArray(columnWidths) || columnWidths.length !== visibleColumnCount) return;
    updateColumnWidths(resizeAdjacentColumns(columnWidths, handleIndex, delta, minPanelWidth));
  }

  function handleResizePointerDown(handleIndex, event) {
    if (visibleColumnCount <= 1) return;
    event.preventDefault();
    const startX = event.clientX;
    const startWidths = [...columnWidths];
    const previousCursor = document.body.style.cursor;
    const previousUserSelect = document.body.style.userSelect;
    document.body.style.cursor = 'col-resize';
    document.body.style.userSelect = 'none';

    function handlePointerMove(moveEvent) {
      const delta = moveEvent.clientX - startX;
      setColumnWidths(resizeAdjacentColumns(startWidths, handleIndex, delta, minPanelWidth));
    }

    function handlePointerUp() {
      document.body.style.cursor = previousCursor;
      document.body.style.userSelect = previousUserSelect;
      window.removeEventListener('pointermove', handlePointerMove);
      window.removeEventListener('pointerup', handlePointerUp);
    }

    window.addEventListener('pointermove', handlePointerMove);
    window.addEventListener('pointerup', handlePointerUp);
  }

  function handleResizeKeyDown(handleIndex, event) {
    if (visibleColumnCount <= 1) return;
    if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
    event.preventDefault();
    const delta = event.shiftKey ? 32 : 16;
    resizeColumnsByHandle(handleIndex, event.key === 'ArrowRight' ? delta : -delta);
  }

  function getMainSplitActionState() {
    if (normalizedSplitTabIds.length + 1 >= allowedColumnCount) {
      return {
        disabled: true,
        title: allowedColumnCount >= MAX_COLUMNS ? '当前最多支持拆分为 3 栏' : '当前容器宽度不足以继续拆分',
      };
    }
    if (mainTabs.length <= 1) {
      return {
        disabled: true,
        title: '主栏至少保留 1 个标签',
      };
    }
    return {
      disabled: false,
      title: '将当前选中的标签拆分到主栏左侧',
    };
  }

  const mainSplitActionState = getMainSplitActionState();
  const resolvedColumnWidths = useMemo(
    () => reconcileColumnWidths(columnWidths, visibleColumnCount, rootWidth, minPanelWidth),
    [columnWidths, minPanelWidth, rootWidth, visibleColumnCount],
  );
  const resizeHandlePositions = useMemo(() => {
    if (visibleColumnCount <= 1) return [];
    const positions = [];
    let offset = 0;
    for (let index = 0; index < resolvedColumnWidths.length - 1; index += 1) {
      offset += resolvedColumnWidths[index];
      positions.push(offset);
    }
    return positions;
  }, [resolvedColumnWidths, visibleColumnCount]);

  return (
    <section
      ref={rootRef}
      className={[
        ROOT_SHELL,
        showFrameBorder ? ROOT_BORDERED : ROOT_BORDERLESS,
        className,
      ].filter(Boolean).join(' ')}
      data-frame-border={showFrameBorder ? 'visible' : 'hidden'}
      style={{
        ...style,
        '--tfds-info-panel-min-width': `${minPanelWidth}px`,
      }}
      data-tfds-component="InfoDisplayPanel"
      data-column-count={visibleColumnCount}
      aria-label="信息展示面板"
    >
      {resizeHandlePositions.map((position, handleIndex) => (
        <button
          key={`resize-handle-${handleIndex}`}
          type="button"
          className={RESIZE_HANDLE}
          style={{ left: `${position}px`, width: `${RESIZE_HANDLE_WIDTH}px`, transform: 'translateX(-50%)' }}
          aria-label="调整相邻栏宽度"
          aria-orientation="vertical"
          onPointerDown={(event) => handleResizePointerDown(handleIndex, event)}
          onKeyDown={(event) => handleResizeKeyDown(handleIndex, event)}
        >
          <span className={RESIZE_HANDLE_LINE} aria-hidden="true" />
        </button>
      ))}
      {visiblePanels.map((panel, index) => {
        const activeTabId = panel.activeTabId || panel.tabs?.[0]?.id || '';
        const activeTabDescriptor = panel.tab ?? tabDescriptors.find((tab) => tab.id === activeTabId) ?? null;
        const sourcePanel = activeTabDescriptor?.sourcePanel ?? panelItems[0] ?? null;

        return (
        <section
          key={panel.id || index}
          className={[PANEL, index > 0 && showFrameBorder ? PANEL_DIVIDER : ''].filter(Boolean).join(' ')}
          style={{ width: `${resolvedColumnWidths[index] ?? 0}px`, minWidth: `${minPanelWidth}px`, flex: '0 0 auto' }}
          data-tfds-component="InfoDisplayPanel.Panel"
        >
          <PanelHeader
            panel={panel}
            activeTabId={activeTabId}
            onTabChange={handleTabChange}
            onSplitAction={panel.kind === 'main' ? handleSplitTab : () => handleMergeTab(activeTabId)}
            splitActionLabel={panel.kind === 'main' ? '拆分' : '合并'}
            splitActionTitle={panel.kind === 'main' ? '拆分' : '合并'}
            splitActionIcon={panel.kind === 'main' ? SPLIT_ACTION_ICON : MERGE_ACTION_ICON}
            splitActionDisabled={panel.kind === 'main' ? mainSplitActionState.disabled : false}
            useTitleFallback={useTitleFallback}
            onClose={onClose}
            closeActionLabel={closeActionLabel}
            showFrameBorder={showFrameBorder}
          />
          <div className={CONTENT} data-tfds-component="InfoDisplayPanel.Content">
            {sourcePanel?.content ?? renderPanelContent?.({
              panel: sourcePanel,
              index,
              activeTabId,
              columnId: panel.id,
              isSplit: panel.kind === 'split',
              splitTabIds: normalizedSplitTabIds,
            }) ?? null}
          </div>
        </section>
      );
      })}
    </section>
  );
}

export {
  DEFAULT_PANELS as INFO_DISPLAY_PANEL_DEFAULT_PANELS,
  MIN_PANEL_WIDTH as INFO_DISPLAY_PANEL_MIN_PANEL_WIDTH,
};
