// components/RichEditor/index.tsx

import { Editor } from '@tinymce/tinymce-react';
import { message } from 'antd';
import React, { useCallback, useEffect, useState } from 'react';
import type { Editor as TinyMCEEditor } from 'tinymce';
import './index.less';

export interface RichEditorProps {
  value?: string;
  onChange?: (content: string) => void;
  height?: number;
  placeholder?: string;
  disabled?: boolean;
  uploadConfig?: {
    action: string;
    headers?: Record<string, string>;
    maxSize?: number;
    acceptTypes?: string[];
    data?: Record<string, any>;
  };
  showWordCount?: boolean;
  maxWords?: number;
}

const RichEditor: React.FC<RichEditorProps> = ({
  value = '',
  onChange,
  height = 400,
  placeholder = '请输入内容...',
  disabled = false,
  showWordCount = true,
  maxWords,
  uploadConfig = {
    action: '/api/upload/image',
    maxSize: 5,
    acceptTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
  },
}) => {
  const [uploading, setUploading] = useState(false);
  const [wordCount, setWordCount] = useState(0);
  const [charCount, setCharCount] = useState(0);

  // 自定义字数统计函数
  const countWords = (text: string) => {
    const plainText = text.replace(/<[^>]*>/g, '');
    const cleanText = plainText.replace(/\s+/g, ' ').trim();

    if (!cleanText) return { words: 0, characters: 0 };

    const chineseChars = cleanText.match(/[\u4e00-\u9fa5]/g) || [];
    const englishWords = cleanText.match(/[a-zA-Z]+/g) || [];
    const numbers = cleanText.match(/\d+/g) || [];

    const words = chineseChars.length + englishWords.length + numbers.length;
    const characters = cleanText.length;

    return { words, characters };
  };

  const handleEditorChange = (content: string) => {
    onChange?.(content);

    if (showWordCount) {
      const { words, characters } = countWords(content);
      setWordCount(words);
      setCharCount(characters);

      if (maxWords && words > maxWords) {
        message.warning(
          `内容超出字数限制，当前 ${words} 字，限制 ${maxWords} 字`,
        );
      }
    }
  };

  useEffect(() => {
    if (showWordCount && value) {
      const { words, characters } = countWords(value);
      setWordCount(words);
      setCharCount(characters);
    }
  }, [value, showWordCount]);

  const uploadFile = useCallback(
    async (file: File): Promise<string> => {
      return new Promise((resolve, reject) => {
        const formData = new FormData();
        formData.append('file', file);

        if (uploadConfig.data) {
          Object.keys(uploadConfig.data).forEach((key) => {
            if (uploadConfig.data) formData.append(key, uploadConfig.data[key]);
          });
        }

        const xhr = new XMLHttpRequest();

        xhr.upload.addEventListener('progress', (e) => {
          if (e.lengthComputable) {
            const percent = Math.round((e.loaded / e.total) * 100);
            console.log(`上传进度: ${percent}%`);
          }
        });

        xhr.addEventListener('load', () => {
          if (xhr.status === 200) {
            try {
              const response = JSON.parse(xhr.responseText);
              if (response.code === 200 && response.data?.url) {
                resolve(response.data.url);
              } else {
                reject(response.message || '上传失败');
              }
            } catch (_error) {
              reject('响应解析失败');
            }
          } else {
            reject(`上传失败: ${xhr.status}`);
          }
        });

        xhr.addEventListener('error', () => {
          reject('网络错误');
        });

        if (uploadConfig.headers) {
          Object.keys(uploadConfig.headers).forEach((key) => {
            if (uploadConfig.headers)
              xhr.setRequestHeader(key, uploadConfig.headers[key]);
          });
        }

        xhr.open('POST', uploadConfig.action);
        xhr.send(formData);
      });
    },
    [uploadConfig],
  );

  const handleImageUpload = useCallback(
    (blobInfo: any, _: (percent: number) => void): Promise<string> => {
      return new Promise((resolve, reject) => {
        try {
          setUploading(true);
          const file = blobInfo.blob();
          uploadFile(file).then((url) => {
            resolve(url);
            message.success('图片上传成功');
          });
        } catch (error) {
          reject(error);
          message.error(typeof error === 'string' ? error : '上传失败');
        } finally {
          setUploading(false);
        }
      });
    },
    [uploadFile],
  );

  const handleCustomUpload = useCallback(
    (editor: TinyMCEEditor) => {
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = uploadConfig.acceptTypes?.join(',') || 'image/*';
      input.multiple = true;

      const handleFileChange = async (event: Event) => {
        const target = event.target as HTMLInputElement;
        const files = Array.from(target.files || []);

        if (files.length === 0) return;

        setUploading(true);

        try {
          for (const file of files) {
            const isValidType = uploadConfig.acceptTypes?.includes(file.type);
            if (!isValidType) {
              message.error(`文件 ${file.name} 类型不支持`);
              continue;
            }

            const isValidSize =
              file.size / 1024 / 1024 < (uploadConfig.maxSize || 5);
            if (!isValidSize) {
              message.error(
                `文件 ${file.name} 大小超过 ${uploadConfig.maxSize || 5}MB`,
              );
              continue;
            }

            try {
              const url = await uploadFile(file);
              const imgHtml = `<img src="${url}" alt="${file.name}" style="max-width: 100%; height: auto;" />`;
              editor.insertContent(imgHtml);
              message.success(`${file.name} 上传成功`);
            } catch (error) {
              message.error(`${file.name} 上传失败: ${error}`);
            }
          }
        } finally {
          setUploading(false);
        }
      };

      input.addEventListener('change', handleFileChange);
      input.click();
    },
    [uploadConfig, uploadFile],
  );

  // 全展开的工具栏配置
  const editorConfig = {
    height,
    menubar: 'file edit view insert format tools table help',
    plugins: [
      'advlist',
      'autolink',
      'lists',
      'link',
      'image',
      'charmap',
      'preview',
      'anchor',
      'searchreplace',
      'visualblocks',
      'code',
      'fullscreen',
      'insertdatetime',
      'media',
      'table',
      'help',
      'wordcount',
      'emoticons',
      'template',
      'codesample',
      'hr',
      'pagebreak',
      'nonbreaking',
      'toc',
      'imagetools',
      'textpattern',
      'noneditable',
      'quickbars',
      'accordion',
    ],

    // 修改为全展开的工具栏配置
    toolbar: [
      // 第一行：撤销重做 + 格式选择 + 字体
      'undo redo | blocks fontfamily fontsize',

      // 第二行：文本格式
      'bold italic underline strikethrough subscript superscript | forecolor backcolor',

      // 第三行：对齐和列表
      'alignleft aligncenter alignright alignjustify | bullist numlist outdent indent',

      // 第四行：插入功能
      'link customupload image media table emoticons charmap insertdatetime hr pagebreak',

      // 第五行：高级功能
      'codesample accordion blockquote | searchreplace visualblocks code',

      // 第六行：其他工具
      'removeformat | fullscreen preview help',
    ].join(' | '),

    // 设置工具栏模式为换行显示，而不是滑动
    toolbar_mode: 'wrap' as const, // 改为 wrap 模式，全部展开

    // 工具栏分组，每组之间有分隔符
    toolbar_groups: {
      history: { icon: 'undo', tooltip: '历史操作' },
      formatting: { icon: 'bold', tooltip: '文本格式' },
      alignment: { icon: 'align-left', tooltip: '对齐方式' },
      indentation: { icon: 'indent', tooltip: '缩进' },
      insert: { icon: 'plus', tooltip: '插入' },
      tools: { icon: 'preferences', tooltip: '工具' },
    },

    font_family_formats: [
      '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif',
      '苹方=PingFang SC,Microsoft YaHei,sans-serif',
      '宋体=SimSun,serif',
      '黑体=SimHei,sans-serif',
      '楷体=KaiTi,serif',
      'Arial=arial,helvetica,sans-serif',
      'Times New Roman=times new roman,times,serif',
      'Courier New=courier new,courier,monospace',
    ].join(';'),

    fontsize_formats:
      '8px 9px 10px 11px 12px 14px 16px 18px 20px 22px 24px 26px 28px 36px 48px 72px',

    block_formats: [
      '段落=p',
      '标题1=h1',
      '标题2=h2',
      '标题3=h3',
      '标题4=h4',
      '标题5=h5',
      '标题6=h6',
      '预格式化=pre',
      '地址=address',
      '代码=code',
    ].join(';'),

    // 字数统计配置
    wordcount_countregex: /[\w\u2019\u4e00-\u9fa5]+/g,
    wordcount_cleanregex: /[0-9.(),;:!?%#$?\x27\x22_+=\\/-]*/g,

    // 颜色配置
    color_map: [
      '000000',
      '黑色',
      '993300',
      '深红色',
      '333300',
      '深黄色',
      '003300',
      '深绿色',
      '003366',
      '深青色',
      '000080',
      '深蓝色',
      '333399',
      '蓝色',
      '333333',
      '深灰色',
      '800000',
      '栗色',
      'FF6600',
      '橙色',
      '808000',
      '橄榄色',
      '008000',
      '绿色',
      '008080',
      '青色',
      '0000FF',
      '蓝色',
      '666699',
      '灰蓝色',
      '808080',
      '灰色',
      'FF0000',
      '红色',
      'FF9900',
      '琥珀色',
      '99CC00',
      '黄绿色',
      '339966',
      '海绿色',
      '33CCCC',
      '青绿色',
      '3366FF',
      '蓝色',
      '800080',
      '紫色',
      '999999',
      '中灰色',
      'FF00FF',
      '洋红色',
      'FFCC00',
      '金色',
      'FFFF00',
      '黄色',
      '00FF00',
      '酸橙色',
      '00FFFF',
      '水蓝色',
      '00CCFF',
      '天蓝色',
      '993366',
      '红紫色',
      'FFFFFF',
      '白色',
    ],

    // 代码高亮配置
    codesample_languages: [
      { text: 'HTML/XML', value: 'markup' },
      { text: 'JavaScript', value: 'javascript' },
      { text: 'TypeScript', value: 'typescript' },
      { text: 'CSS', value: 'css' },
      { text: 'SCSS', value: 'scss' },
      { text: 'Python', value: 'python' },
      { text: 'Java', value: 'java' },
      { text: 'C++', value: 'cpp' },
      { text: 'C#', value: 'csharp' },
      { text: 'PHP', value: 'php' },
      { text: 'Ruby', value: 'ruby' },
      { text: 'Go', value: 'go' },
      { text: 'Rust', value: 'rust' },
      { text: 'SQL', value: 'sql' },
      { text: 'JSON', value: 'json' },
      { text: 'Bash', value: 'bash' },
    ],

    // 表格配置
    table_default_attributes: {
      border: '1',
    },
    table_default_styles: {
      'border-collapse': 'collapse',
      width: '100%',
    },
    table_class_list: [
      { title: '无样式', value: '' },
      { title: '简单表格', value: 'simple-table' },
      { title: '条纹表格', value: 'striped-table' },
      { title: '边框表格', value: 'bordered-table' },
    ],

    // 链接配置
    link_default_target: '_blank',
    link_assume_external_targets: true,
    link_context_toolbar: true,

    // 图片配置
    image_advtab: true,
    image_caption: true,

    // 媒体配置
    media_live_embeds: true,
    media_filter_html: false,

    content_style: `
      body {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
        font-size: 14px;
        line-height: 1.6;
        margin: 16px;
        color: #333;
      }

      h1, h2, h3, h4, h5, h6 {
        margin-top: 24px;
        margin-bottom: 16px;
        font-weight: 600;
        line-height: 1.25;
      }

      h1 { font-size: 2em; color: #1a1a1a; }
      h2 { font-size: 1.5em; color: #2a2a2a; }
      h3 { font-size: 1.25em; color: #3a3a3a; }

      p { margin-bottom: 16px; }

      img {
        max-width: 100%;
        height: auto;
        border-radius: 6px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        margin: 8px 0;
      }

      table {
        border-collapse: collapse;
        width: 100%;
        margin: 16px 0;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1);
      }

      table td, table th {
        border: 1px solid #e8e8e8;
        padding: 12px;
        text-align: left;
      }

      table th {
        background-color: #f8f9fa;
        font-weight: 600;
        color: #495057;
      }

      blockquote {
        border-left: 4px solid #1890ff;
        margin: 16px 0;
        padding: 8px 16px;
        background-color: #f6f8fa;
        color: #666;
        font-style: italic;
      }

      code {
        background-color: #f1f3f4;
        padding: 2px 4px;
        border-radius: 3px;
        font-family: 'Courier New', monospace;
        font-size: 0.9em;
        color: #d73a49;
      }

      pre {
        background-color: #f8f8f8;
        border: 1px solid #e1e4e8;
        border-radius: 6px;
        padding: 16px;
        overflow-x: auto;
        margin: 16px 0;
      }

      pre code {
        background: none;
        padding: 0;
        color: inherit;
      }
    `,

    placeholder,
    branding: false,
    elementpath: true,
    resize: 'both' as const,
    statusbar: showWordCount,

    // 图片上传配置
    images_upload_handler: handleImageUpload,
    automatic_uploads: true,
    images_reuse_filename: true,
    images_upload_url: uploadConfig.action,
    images_upload_base_path: '',
    images_upload_credentials: true,

    // 粘贴配置
    paste_data_images: true,
    paste_as_text: false,
    paste_webkit_styles: 'none',
    paste_merge_formats: true,
    paste_remove_styles_if_webkit: true,

    // 文件选择器配置
    file_picker_types: 'image media',
    file_picker_callback: (
      callback: (url: string, meta?: any) => void,
      // value: string,
      meta: any,
    ) => {
      if (meta.filetype === 'image') {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = uploadConfig.acceptTypes?.join(',') || 'image/*';

        const handleChange = async (event: Event) => {
          const target = event.target as HTMLInputElement;
          const file = target.files?.[0];

          if (!file) return;

          const isValidType = uploadConfig.acceptTypes?.includes(file.type);
          const isValidSize =
            file.size / 1024 / 1024 < (uploadConfig.maxSize || 5);

          if (!isValidType) {
            message.error('文件类型不支持');
            return;
          }

          if (!isValidSize) {
            message.error(`文件大小不能超过 ${uploadConfig.maxSize || 5}MB`);
            return;
          }

          try {
            setUploading(true);
            const url = await uploadFile(file);
            callback(url, { alt: file.name });
            message.success('图片上传成功');
          } catch (error) {
            message.error('上传失败');
            console.error('Upload error:', error);
          } finally {
            setUploading(false);
          }
        };

        input.addEventListener('change', handleChange);
        input.click();
      }
    },

    // 快速工具栏
    quickbars_selection_toolbar:
      'bold italic | quicklink h2 h3 blockquote quickimage quicktable',
    quickbars_insert_toolbar: 'quickimage quicktable',

    // 文本模式
    textpattern_patterns: [
      { start: '*', end: '*', format: 'italic' },
      { start: '**', end: '**', format: 'bold' },
      { start: '#', format: 'h1' },
      { start: '##', format: 'h2' },
      { start: '###', format: 'h3' },
      { start: '####', format: 'h4' },
      { start: '#####', format: 'h5' },
      { start: '######', format: 'h6' },
      { start: '1. ', cmd: 'InsertOrderedList' },
      { start: '* ', cmd: 'InsertUnorderedList' },
      { start: '- ', cmd: 'InsertUnorderedList' },
    ],

    // 初始化设置
    setup: (editor: TinyMCEEditor) => {
      // 注册自定义上传按钮
      editor.ui.registry.addButton('customupload', {
        text: uploading ? '上传中...' : '上传',
        icon: 'upload',
        tooltip: '上传图片（支持多选）',
        enabled: !disabled && !uploading,
        onAction: () => {
          handleCustomUpload(editor);
        },
      });

      // 监听内容变化，实时更新字数统计
      editor.on('input change undo redo', () => {
        if (showWordCount) {
          const content = editor.getContent();
          const { words, characters } = countWords(content);
          setWordCount(words);
          setCharCount(characters);
        }
      });

      editor.on('init', () => {
        console.log('编辑器初始化完成');

        // 初始化字数统计
        if (showWordCount && value) {
          const { words, characters } = countWords(value);
          setWordCount(words);
          setCharCount(characters);
        }
      });
    },

    // 其他配置
    convert_urls: false,
    remove_script_host: false,
    relative_urls: false,
    language: 'zh_CN',
    directionality: 'ltr' as const,

    // 高级配置
    extended_valid_elements: 'script[src|async|defer|type|charset]',

    // 性能配置
    browser_spellcheck: true,
    contextmenu: 'link image table',
  };

  return (
    <div className="rich-editor-wrapper">
      <Editor
        value={value}
        onEditorChange={handleEditorChange}
        init={editorConfig}
        disabled={disabled}
      />

      {/* 自定义字数统计显示 */}
      {showWordCount && (
        <div className="word-count-display">
          <span className="word-count">
            字数: {wordCount}
            {maxWords && (
              <span className={wordCount > maxWords ? 'over-limit' : ''}>
                /{maxWords}
              </span>
            )}
          </span>
          <span className="char-count">字符: {charCount}</span>
        </div>
      )}

      {uploading && (
        <div className="upload-overlay">
          <div className="upload-spinner">
            <div className="spinner"></div>
            <span>上传中...</span>
          </div>
        </div>
      )}
    </div>
  );
};

export default RichEditor;
