/**
 * CustomerServiceWorkspaceFrame — 客服工作台框架
 *
 * 像素对齐 Figma「在线Agent」框架：浅灰底、顶部在线状态/指标/工具/模式切换、
 * 下方半透明工作区与右侧主白卡。组件只负责框架承载，不内置具体会话业务。
 */

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

const DEFAULT_STATS = [
  { id: 'online-users', iconName: 'users-01-stroked', value: '12', label: '在线接待数' },
  { id: 'completed', iconName: 'annotation-check-stroked', value: '36', label: '已处理数' },
  { id: 'progress', iconName: 'bar-chart-10-stroked', value: '7/23', label: '目标进度' },
];

const DEFAULT_TOOLS = [
  { id: 'insight', iconName: 'bar-chart-square-02-stroked', label: '数据看板' },
  { id: 'announcement', iconName: 'announcement-01-stroked', label: '公告' },
  { id: 'settings', iconName: 'settings-02-stroked', label: '设置' },
];

const DEFAULT_MODES = [
  { id: 'basic', label: '基础模式' },
  { id: 'managed', label: '托管模式' },
];

const MAX_STATS = 4;
const MAX_TOOLS = 3;

// 覆盖深度必须大于 16px 圆角半径，避免主面板圆角切角处露出左板块右边界。
const PANEL_OVERLAP = 32;

const ROOT = [
  'tfds-customer-service-workspace-frame',
  'flex size-full min-h-[560px] items-start overflow-hidden rounded-xl bg-blueGrey-200',
  '[font-family:inherit] text-foreground',
].join(' ');
const SHELL = 'flex h-full min-w-0 flex-1 flex-col gap-4 overflow-hidden p-4';
const TOP_BAR = 'grid min-h-[24px] w-full shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3 overflow-hidden pl-3';
const AGENT_GROUP = 'flex min-w-0 shrink-0 items-center gap-3 rounded-xl';
const AGENT_NAME = 'm-0 whitespace-nowrap text-sm [font-weight:var(--font-semibold)] leading-5 text-foreground';
const STATUS_DOT_WRAP = 'flex size-4 shrink-0 items-center justify-center py-1';
const STATUS_DOT = 'size-[10px] rounded-full bg-green-500';
const STATUS_BUTTON = 'shrink-0';
const STATUS_TEXT = 'whitespace-nowrap text-sm [font-weight:var(--font-semibold)] leading-5';
const METRICS_SLOT = 'flex min-w-0 items-center justify-center';
const MODE_SLOT = 'flex min-w-0 items-center justify-end';
const METRICS_CARD = 'flex shrink-0 items-center gap-4 rounded-md border border-white bg-white/60 px-4 py-1';
const METRIC_ITEM = 'flex shrink-0 items-center gap-1';
const METRIC_TEXT = 'm-0 max-w-[44px] truncate text-xs [font-weight:var(--font-semibold)] leading-4 text-foreground';
const METRIC_DIVIDER = 'h-3 w-px bg-border-default';
const TOOL_GROUP = 'flex shrink-0 items-center gap-3';
const MODE_TABS = 'shrink-0';
const WORKSPACE = [
  'relative flex min-h-0 w-full flex-1 items-stretch',
  'overflow-visible',
].join(' ');
const SIDE_PLACEHOLDER = 'relative z-0 h-full shrink-0 overflow-hidden rounded-xl border border-white bg-white/50 transition-[width] tfds-motion-ui-normal';
const SIDE_CONTENT = 'absolute inset-y-0 left-0 min-w-0 overflow-hidden';
const RESIZE_HANDLE = [
  'group/resize absolute top-0 bottom-0 z-20 flex w-2 -translate-x-1/2 cursor-col-resize items-stretch justify-center',
  'border-0 bg-transparent p-0',
  'focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-blueGrey-400',
].join(' ');
const RESIZE_HANDLE_LINE = tfdsResizeHandleLineClass('resize');
const MAIN_PANEL = [
  'relative z-10 flex h-full min-w-0 flex-1 flex-col items-center justify-center overflow-hidden rounded-xl border border-white bg-surface',
  'shadow-[0px_0px_16px_0px_rgba(101,115,137,0.06)]',
].join(' ');

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

function normalizeItems(items, fallback) {
  return Array.isArray(items) && items.length > 0 ? items : fallback;
}

function getStatTooltip(item) {
  return item.tooltip || item.description || item.label || item.value;
}

function getStatAriaLabel(item) {
  return [item.label, item.value].filter(Boolean).join(' ');
}

function resolveMaxSideWidth(workspaceWidth, maxSideWidth, minSideWidth, mainMinWidth) {
  const finiteMaxSideWidth = Number.isFinite(maxSideWidth) ? maxSideWidth : Number.POSITIVE_INFINITY;
  if (workspaceWidth <= 0) {
    return Math.max(minSideWidth, Number.isFinite(finiteMaxSideWidth) ? finiteMaxSideWidth : 9999);
  }
  const maxByMainPanel = workspaceWidth > 0
    ? workspaceWidth + PANEL_OVERLAP - mainMinWidth
    : finiteMaxSideWidth;
  const nextMax = Math.min(finiteMaxSideWidth, maxByMainPanel);
  return Math.max(minSideWidth, Number.isFinite(nextMax) ? nextMax : minSideWidth);
}

export default function CustomerServiceWorkspaceFrame({
  agentName = '客服名称',
  onlineDuration = '02:27:58',
  onlineLabel = '在线',
  stats = DEFAULT_STATS,
  tools = DEFAULT_TOOLS,
  modes = DEFAULT_MODES,
  mode,
  defaultMode = 'basic',
  onModeChange,
  leftPanel = null,
  mainPanel = null,
  children = null,
  sideWidth = 432,
  minSideWidth = 100,
  leftContentMinWidth = 0,
  maxSideWidth = Number.POSITIVE_INFINITY,
  mainMinWidth = 380,
  resizable = true,
  onSideWidthChange,
  className = '',
  style = null,
}) {
  const workspaceRef = useRef(null);
  const modeItems = useMemo(() => normalizeItems(modes, DEFAULT_MODES), [modes]);
  const statItems = useMemo(() => normalizeItems(stats, DEFAULT_STATS).slice(0, MAX_STATS), [stats]);
  const toolItems = useMemo(() => normalizeItems(tools, DEFAULT_TOOLS).slice(0, MAX_TOOLS), [tools]);
  const isControlled = typeof mode === 'string';
  const [innerMode, setInnerMode] = useState(defaultMode);
  const [workspaceWidth, setWorkspaceWidth] = useState(0);
  const resolvedLeftContentMinWidth = Math.max(0, Number.isFinite(leftContentMinWidth) ? leftContentMinWidth : 0);
  const resolvedMinSideWidth = Math.max(minSideWidth, resolvedLeftContentMinWidth + PANEL_OVERLAP);
  const resolvedMaxSideWidth = resolveMaxSideWidth(workspaceWidth, maxSideWidth, resolvedMinSideWidth, mainMinWidth);
  const [currentSideWidth, setCurrentSideWidth] = useState(() => clamp(sideWidth, resolvedMinSideWidth, maxSideWidth));
  const activeMode = isControlled ? mode : innerMode;
  const activeModeIndex = useMemo(() => {
    const matchedIndex = modeItems.findIndex((item) => item.id === activeMode);
    return matchedIndex >= 0 ? matchedIndex : 0;
  }, [activeMode, modeItems]);
  const resolvedMain = mainPanel ?? children;

  useEffect(() => {
    const workspaceNode = workspaceRef.current;
    if (!workspaceNode) return undefined;

    function updateWorkspaceWidth() {
      setWorkspaceWidth(workspaceNode.getBoundingClientRect().width);
    }

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

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

  useEffect(() => {
    setCurrentSideWidth(clamp(sideWidth, resolvedMinSideWidth, resolvedMaxSideWidth));
  }, [resolvedMinSideWidth, resolvedMaxSideWidth, sideWidth]);

  function handleModeChange(nextMode) {
    if (!isControlled) setInnerMode(nextMode);
    onModeChange?.(nextMode);
  }

  function handleModeTabChange(nextIndex) {
    const nextMode = modeItems[nextIndex]?.id;
    if (!nextMode) return;
    handleModeChange(nextMode);
  }

  function updateSideWidth(nextWidth) {
    const resolvedWidth = clamp(nextWidth, resolvedMinSideWidth, resolvedMaxSideWidth);
    setCurrentSideWidth(resolvedWidth);
    onSideWidthChange?.(resolvedWidth);
  }

  function handleResizePointerDown(event) {
    if (!resizable) return;
    event.preventDefault();
    const startX = event.clientX;
    const startWidth = currentSideWidth;
    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) {
      updateSideWidth(startWidth + moveEvent.clientX - startX);
    }

    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(event) {
    if (!resizable) return;
    if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
    event.preventDefault();
    const delta = event.shiftKey ? 32 : 16;
    updateSideWidth(currentSideWidth + (event.key === 'ArrowRight' ? delta : -delta));
  }

  return (
    <section
      className={[ROOT, className].filter(Boolean).join(' ')}
      style={style}
      data-tfds-component="CustomerServiceWorkspaceFrame"
      aria-label="客服工作台框架"
    >
      <div className={SHELL}>
        <header className={TOP_BAR} data-tfds-component="CustomerServiceWorkspaceFrame.Header">
          <div className={AGENT_GROUP}>
            <p className={AGENT_NAME}>{agentName}</p>
            <Button
              type="button"
              variant="text-black"
              size="md"
              className={STATUS_BUTTON}
              icon={(
                <span className={STATUS_DOT_WRAP} aria-hidden="true">
                  <span className={STATUS_DOT} />
                </span>
              )}
              aria-label={`${onlineLabel} ${onlineDuration}`}
            >
              <span className={STATUS_TEXT}>{onlineLabel} {onlineDuration}</span>
            </Button>
          </div>

          <div className={METRICS_SLOT}>
            <div className={METRICS_CARD} data-tfds-component="CustomerServiceWorkspaceFrame.Metrics">
              {statItems.map((item, index) => (
                <Tooltip
                  key={item.id || `${item.iconName}-${index}`}
                  content={getStatTooltip(item)}
                  placement="top"
                  triggerClassName="inline-flex shrink-0"
                >
                  <div
                    className={METRIC_ITEM}
                    title={item.label}
                    aria-label={getStatAriaLabel(item)}
                  >
                    <Icon name={item.iconName} size={14} className="text-foreground" aria-hidden="true" />
                    <p className={METRIC_TEXT}>{item.value}</p>
                  </div>
                </Tooltip>
              ))}
              {toolItems.length > 0 ? <span className={METRIC_DIVIDER} aria-hidden="true" /> : null}
              {toolItems.length > 0 ? (
                <div className={TOOL_GROUP}>
                  {toolItems.map((item) => (
                    <Button
                      key={item.id || item.iconName}
                      type="button"
                      variant="ghost-black"
                      size="sm"
                      icon={<Icon name={item.iconName} size={16} />}
                      iconOnly
                      tooltip={item.label}
                      aria-label={item.label}
                      title={item.label}
                    />
                  ))}
                </div>
              ) : null}
            </div>
          </div>

          <div className={MODE_SLOT}>
            <Tabs
              variant="segment"
              size="sm"
              className={MODE_TABS}
              aria-label="工作台模式"
              items={modeItems.map((item) => ({ label: item.label }))}
              activeIndex={activeModeIndex}
              onChange={handleModeTabChange}
            />
          </div>
        </header>

        <div ref={workspaceRef} className={WORKSPACE} data-tfds-component="CustomerServiceWorkspaceFrame.Workspace">
          <aside
            className={SIDE_PLACEHOLDER}
            style={{ width: `${currentSideWidth}px` }}
            data-tfds-component="CustomerServiceWorkspaceFrame.LeftPanel"
          >
            <div
              className={SIDE_CONTENT}
              style={{ right: `${PANEL_OVERLAP}px` }}
              data-tfds-component="CustomerServiceWorkspaceFrame.LeftPanelContent"
            >
              {leftPanel}
            </div>
          </aside>
          <main
            className={MAIN_PANEL}
            style={{ marginLeft: `-${PANEL_OVERLAP}px`, minWidth: `${mainMinWidth}px` }}
            data-tfds-component="CustomerServiceWorkspaceFrame.MainPanel"
          >
            {resolvedMain}
          </main>
          {resizable ? (
            <button
              type="button"
              className={RESIZE_HANDLE}
              style={{ left: `${currentSideWidth - PANEL_OVERLAP}px` }}
              aria-label="调整客服工作台左右面板宽度"
              aria-orientation="vertical"
              aria-valuemin={Math.round(resolvedMinSideWidth)}
              aria-valuemax={Math.round(resolvedMaxSideWidth)}
              aria-valuenow={currentSideWidth}
              data-tfds-component="CustomerServiceWorkspaceFrame.ResizeHandle"
              onPointerDown={handleResizePointerDown}
              onKeyDown={handleResizeKeyDown}
            >
              <span className={RESIZE_HANDLE_LINE} aria-hidden="true" />
            </button>
          ) : null}
        </div>
      </div>
    </section>
  );
}

export {
  DEFAULT_STATS as CUSTOMER_SERVICE_WORKSPACE_FRAME_STATS,
  DEFAULT_TOOLS as CUSTOMER_SERVICE_WORKSPACE_FRAME_TOOLS,
  DEFAULT_MODES as CUSTOMER_SERVICE_WORKSPACE_FRAME_MODES,
};
