import { useCallback, useEffect, useRef, useState } from 'react';
import {
  TFDS_RESIZE_HANDLE_LINE_TRANSITION,
  TFDS_RESIZE_LINE_WIDTH_CLASS,
} from '../../shared/resize-handle';

export const CHAT_ARTIFACT_SPLIT_MIN_PANEL_WIDTH = 300;
export const CHAT_ARTIFACT_SPLIT_DEFAULT_ARTIFACT_RATIO = 0.7;
/** 对话区与产物详情区之间的固定间距 */
export const CHAT_ARTIFACT_SPLIT_COLUMN_GAP = 24;
/** 分栏容器左右页面边距（由 `ChatConversationPattern` 外层内容区 16px 承担，此处为 0） */
export const CHAT_ARTIFACT_SPLIT_PAGE_PADDING_X = 0;

const SPLIT_OUTER = 'flex min-h-0 min-w-0 flex-1 overflow-x-hidden';
const CONVERSATION_COLUMN = 'flex min-h-0 min-w-0 flex-1 flex-col';
const ARTIFACT_FRAME = 'relative flex h-full min-h-0 min-w-0 shrink-0 flex-col';
/** 正文内滚放在内层，避免 overflow-hidden 裁切左缘 -translate-x-1/2 的拖拽把手 */
const ARTIFACT_BODY = 'flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden';
const RESIZE_HANDLE = [
  'group/chat-artifact-resize absolute inset-y-0 left-0 z-20 flex w-2 -translate-x-1/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 = [
  TFDS_RESIZE_LINE_WIDTH_CLASS,
  TFDS_RESIZE_HANDLE_LINE_TRANSITION,
  'my-4 bg-blueGrey-300',
  'group-hover/chat-artifact-resize:bg-brand-400',
  'group-focus-visible/chat-artifact-resize:bg-brand-500',
  'group-active/chat-artifact-resize:bg-brand-500',
].join(' ');

function readContentMetrics(node) {
  if (!node) {
    return { contentWidth: 0, paddingRight: 0 };
  }
  const rect = node.getBoundingClientRect();
  const styles = getComputedStyle(node);
  const paddingLeft = parseFloat(styles.paddingLeft) || 0;
  const paddingRight = parseFloat(styles.paddingRight) || 0;
  return {
    contentWidth: Math.max(0, rect.width - paddingLeft - paddingRight),
    paddingRight,
    contentRight: rect.right - paddingRight,
  };
}

function getSplitRowWidth(contentWidth, columnGap) {
  return Math.max(0, contentWidth - columnGap);
}

function clampArtifactWidth(width, contentWidth, minPanelWidth, columnGap) {
  const rowWidth = getSplitRowWidth(contentWidth, columnGap);
  if (!Number.isFinite(rowWidth) || rowWidth <= 0) {
    return Math.max(minPanelWidth, width);
  }
  const maxArtifactWidth = Math.max(minPanelWidth, rowWidth - minPanelWidth);
  return Math.min(Math.max(width, minPanelWidth), maxArtifactWidth);
}

/**
 * AI 对话页 · 对话区 + 产物详情可拖拽分栏。
 * 拖拽把手位于产物容器左缘；拖动调整的是右侧产物区宽度，左侧对话区 flex-1 自适应撑满剩余空间。
 * 页面四周边距由外层内容区统一 16px；两栏间距 24px（gap-6）。
 */
export default function ChatArtifactSplitLayout({
  conversation,
  artifactPanel,
  minPanelWidth = CHAT_ARTIFACT_SPLIT_MIN_PANEL_WIDTH,
  defaultArtifactRatio = CHAT_ARTIFACT_SPLIT_DEFAULT_ARTIFACT_RATIO,
  columnGap = CHAT_ARTIFACT_SPLIT_COLUMN_GAP,
  pagePaddingX = CHAT_ARTIFACT_SPLIT_PAGE_PADDING_X,
  className = '',
}) {
  const containerRef = useRef(null);
  const contentMetricsRef = useRef({ contentWidth: 0, paddingRight: 0, contentRight: 0 });
  const [contentWidth, setContentWidth] = useState(0);
  const [artifactWidth, setArtifactWidth] = useState(null);

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

    function updateWidth() {
      const metrics = readContentMetrics(node);
      contentMetricsRef.current = metrics;
      setContentWidth(metrics.contentWidth);
    }

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

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

  const splitRowWidth = getSplitRowWidth(contentWidth, columnGap);

  useEffect(() => {
    if (contentWidth <= 0) return;
    setArtifactWidth((current) => {
      if (current == null) {
        return clampArtifactWidth(
          Math.round(splitRowWidth * defaultArtifactRatio),
          contentWidth,
          minPanelWidth,
          columnGap,
        );
      }
      return clampArtifactWidth(current, contentWidth, minPanelWidth, columnGap);
    });
  }, [contentWidth, columnGap, defaultArtifactRatio, minPanelWidth, splitRowWidth]);

  const resolvedArtifactWidth = artifactWidth == null
    ? clampArtifactWidth(
      Math.round(splitRowWidth * defaultArtifactRatio),
      contentWidth,
      minPanelWidth,
      columnGap,
    )
    : clampArtifactWidth(artifactWidth, contentWidth, minPanelWidth, columnGap);

  const maxArtifactWidth = splitRowWidth > 0
    ? Math.max(minPanelWidth, splitRowWidth - minPanelWidth)
    : resolvedArtifactWidth;

  const updateArtifactWidth = useCallback((nextWidth) => {
    setArtifactWidth(clampArtifactWidth(nextWidth, contentWidth, minPanelWidth, columnGap));
  }, [columnGap, contentWidth, minPanelWidth]);

  const measureArtifactWidthFromPointer = useCallback((clientX) => {
    const node = containerRef.current;
    const metrics = node ? readContentMetrics(node) : contentMetricsRef.current;
    return metrics.contentRight - clientX;
  }, []);

  const handleResizePointerDown = useCallback((event) => {
    event.preventDefault();
    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) {
      updateArtifactWidth(measureArtifactWidthFromPointer(moveEvent.clientX));
    }

    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);
  }, [measureArtifactWidthFromPointer, updateArtifactWidth]);

  const handleResizeKeyDown = useCallback((event) => {
    if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight' && event.key !== 'Home' && event.key !== 'End') {
      return;
    }
    event.preventDefault();

    if (event.key === 'Home') {
      updateArtifactWidth(maxArtifactWidth);
      return;
    }

    if (event.key === 'End') {
      updateArtifactWidth(minPanelWidth);
      return;
    }

    const delta = event.shiftKey ? 32 : 16;
    /* 向右拖宽产物区 = 增大宽度；ArrowRight 与拖拽方向一致 */
    updateArtifactWidth(resolvedArtifactWidth + (event.key === 'ArrowRight' ? delta : -delta));
  }, [maxArtifactWidth, minPanelWidth, resolvedArtifactWidth, updateArtifactWidth]);

  return (
    <div
      ref={containerRef}
      className={[SPLIT_OUTER, className].filter(Boolean).join(' ')}
      style={{
        paddingLeft: `${pagePaddingX}px`,
        paddingRight: `${pagePaddingX}px`,
        gap: `${columnGap}px`,
      }}
      data-tfds-component="ChatArtifactSplitLayout"
    >
      <div
        className={CONVERSATION_COLUMN}
        style={{ minWidth: `${minPanelWidth}px` }}
        data-tfds-component="ChatArtifactSplitLayout.Conversation"
      >
        {conversation}
      </div>

      <div
        className={ARTIFACT_FRAME}
        style={{
          width: `${resolvedArtifactWidth}px`,
          minWidth: `${minPanelWidth}px`,
          flexShrink: 0,
        }}
        data-tfds-component="ChatArtifactSplitLayout.Artifact"
      >
        <button
          type="button"
          className={RESIZE_HANDLE}
          aria-label="调整产物详情区宽度"
          aria-orientation="vertical"
          aria-valuemin={minPanelWidth}
          aria-valuemax={Math.round(maxArtifactWidth)}
          aria-valuenow={Math.round(resolvedArtifactWidth)}
          onPointerDown={handleResizePointerDown}
          onKeyDown={handleResizeKeyDown}
        >
          <span className={RESIZE_HANDLE_LINE} aria-hidden="true" />
        </button>
        <div className={ARTIFACT_BODY} data-tfds-region="chat-artifact-split-artifact-body">
          {artifactPanel}
        </div>
      </div>
    </div>
  );
}
