/**
 * BlockMenu.tsx - 块操作菜单组件
 * 
 * 悬浮在块左侧的操作菜单，提供删除和插入等快捷操作
 * 
 * @module components/Editor/blocks
 */

import React from 'react';
import { Button, Dropdown, Upload, message } from 'antd';
import type { MenuProps } from 'antd';
import type { RcFile } from 'antd/es/upload/interface';
import {
  isSafeImageSource,
  sanitizeImageAlt,
  validateImageDimensions,
  validateImageUpload,
} from '../../../utils/imageUpload';
import {
  DeleteOutlined,
  PlusOutlined,
  FontSizeOutlined,
  FileTextOutlined,
  OrderedListOutlined,
  PictureOutlined,
  TableOutlined,
} from '@ant-design/icons';
import './BlockMenu.css';

// ══════════════════════════════════════════════════════════════════════════════
// Component Props
// ══════════════════════════════════════════════════════════════════════════════

export interface BlockMenuProps {
  blockId: string;
  isEmpty?: boolean;
  isFirst?: boolean;
  isLast?: boolean;
  onDelete?: () => void;
  onDuplicate?: () => void;
  onMoveUp?: () => void;
  onMoveDown?: () => void;
  onInsertHeading?: (level: 1 | 2 | 3 | 4 | 5 | 6) => void;
  onInsertParagraph?: () => void;
  onInsertOrderedList?: () => void;
  onInsertImage?: (dataUrl: string, fileName: string, width: number, height: number) => void;
  onInsertTable?: () => void;
  blockType?: 'heading' | 'paragraph' | 'image' | 'table';
}

// ══════════════════════════════════════════════════════════════════════════════
// Component
// ══════════════════════════════════════════════════════════════════════════════

/**
 * BlockMenu - 块操作菜单
 * 
 * 显示在块左侧的操作按钮，hover时可见
 */
export const BlockMenu: React.FC<BlockMenuProps> = ({
  blockId,
  isEmpty = false,
  onDelete,
  onInsertHeading,
  onInsertParagraph,
  onInsertOrderedList,
  onInsertImage,
  onInsertTable,
}) => {
  const uploadRef = React.useRef<HTMLDivElement>(null);
  const isMountedRef = React.useRef(true);

  React.useEffect(() => {
    return () => {
      isMountedRef.current = false;
    };
  }, []);

  /**
   * 处理图片上传
   */
  const handleImageUpload = (file: RcFile): boolean => {
    const validationError = validateImageUpload(file);
    if (validationError) {
      message.error(validationError);
      return false;
    }

    // 读取文件并转为Base64
    const reader = new FileReader();
    reader.onload = (e) => {
      const dataUrl = e.target?.result as string;
      if (!isMountedRef.current || typeof dataUrl !== 'string' || !isSafeImageSource(dataUrl)) {
        return;
      }

      // 使用Image对象获取图片尺寸
      const img = new Image();
      img.onload = () => {
        if (!isMountedRef.current) return;

        const dimensionError = validateImageDimensions(img.width, img.height);
        if (dimensionError) {
          message.error(dimensionError);
          return;
        }

        // 计算适合的显示尺寸（默认最大宽度15cm）
        const maxWidthCm = 15;
        const aspectRatio = img.height / img.width;
        const widthCm = Math.min(maxWidthCm, img.width / 37.795); // 37.795 px ≈ 1cm
        const heightCm = widthCm * aspectRatio;
        const safeFileName = sanitizeImageAlt(file.name);

        // 调用插入图片回调
        onInsertImage?.(dataUrl, safeFileName, parseFloat(widthCm.toFixed(2)), parseFloat(heightCm.toFixed(2)));
        message.success('图片已插入');
      };
      img.onerror = () => {
        if (!isMountedRef.current) return;
        message.error('图片加载失败');
      };
      img.src = dataUrl;
    };
    reader.onerror = () => {
      if (!isMountedRef.current) return;
      message.error('图片读取失败');
    };
    reader.readAsDataURL(file);

    return false; // 阻止默认上传行为
  };

  // 插入标题子菜单
  const insertHeadingMenuItems: MenuProps['items'] = [
    {
      key: 'h1',
      label: '标题 1',
      onClick: () => onInsertHeading?.(1),
    },
    {
      key: 'h2',
      label: '标题 2',
      onClick: () => onInsertHeading?.(2),
    },
    {
      key: 'h3',
      label: '标题 3',
      onClick: () => onInsertHeading?.(3),
    },
    {
      key: 'h4',
      label: '标题 4',
      onClick: () => onInsertHeading?.(4),
    },
    {
      key: 'h5',
      label: '标题 5',
      onClick: () => onInsertHeading?.(5),
    },
    {
      key: 'h6',
      label: '标题 6',
      onClick: () => onInsertHeading?.(6),
    },
  ];

  const handleInsertImage = () => {
    const input = uploadRef.current?.querySelector<HTMLInputElement>('input[type="file"]');
    input?.click();
  };

  // 插入面板，只保留已实现的功能
  const insertMenuItems: MenuProps['items'] = [
    { key: 'paragraph', icon: <FileTextOutlined />, label: '正文', onClick: onInsertParagraph },
    { key: 'heading', icon: <FontSizeOutlined />, label: '标题', children: insertHeadingMenuItems },
    { key: 'ordered-list', icon: <OrderedListOutlined />, label: '有序列表', onClick: onInsertOrderedList },
    { key: 'image', icon: <PictureOutlined />, label: '图片', onClick: handleInsertImage },
    { key: 'table', icon: <TableOutlined />, label: '表格', onClick: onInsertTable },
  ];

  // 加号面板同时承载插入和原三点菜单中的块操作。
  const plusMenuItems: MenuProps['items'] = [
    ...insertMenuItems,
    { type: 'divider' },
    {
      key: 'delete',
      icon: <DeleteOutlined />,
      label: '删除',
      danger: true,
      onClick: onDelete,
    },
  ];

  return (
    <div className={`block-menu${isEmpty ? ' block-menu-empty' : ''}`} data-block-id={blockId}>
      <Dropdown
        menu={{ items: plusMenuItems }}
        trigger={['click']}
        placement="bottomLeft"
        overlayClassName="block-insert-dropdown"
      >
        <Button
          type="text"
          size="small"
          icon={<PlusOutlined />}
          className="block-menu-add"
          aria-label="插入块"
        />
      </Dropdown>

      {/* 隐藏的图片上传组件 */}
      <div ref={uploadRef} style={{ display: 'none' }}>
        <Upload
          accept="image/*"
          beforeUpload={handleImageUpload}
          showUploadList={false}
        >
          <Button />
        </Upload>
      </div>
    </div>
  );
};

export default BlockMenu;
