import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { Modal, Divider, Upload, Input, Space, Button, Form, Spin, message } from 'antd';
import { CloudUploadOutlined } from '@ant-design/icons';
import { SlateTransforms, SlateEditor, SlateElement } from '@wangeditor/editor';
import './index.less';

import { partSize, normalUploader, multipartUploader } from '../utils/upload';

const { Dragger } = Upload;

const tImg = 'http://zxts-book-file.zijingebook.com/2024/02/27/image-1709025121892-8jswpoazmvk.png';
const ImageModal = forwardRef((props, ref) => {
  const { editor, ossClient, setImageVisible, imageInfo, setImageInfo } = props;

  const [imgUrl, setImgUrl] = useState('');
  const fileAccept = ['.png', '.jpg', '.jpeg', '.svg'];
  const [form] = Form.useForm();
  const [uploading, setUploading] = useState(false); // 文件上传状态
  const [progress, setProgress] = useState(0);
  const [file, setFile] = useState({});
  const [fileList, setFileList] = useState([]);
  const [initValues, setInitValues] = useState({ imgUrl: '', imgTitle: '', imgDescript: '' });
  const [tempNodeInfo, setTempNodeInfo] = useState(null);

  useEffect(() => {
    if (imageInfo && Object.entries(imageInfo).length > 0) {
      const { image, node } = imageInfo;
      setImgUrl(image.src);
      setInitValues({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href });
      form.setFieldsValue({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href });
      setTempNodeInfo(imageInfo);
      setFile({});
      setFileList([]);
      setImageInfo({});
    }
  }, [imageInfo]);

  const normFile = (e) => {
    if (Array.isArray(e)) {
      return e;
    }
    return e?.fileList;
  };
  const uploadProps = {
    name: 'file',
    maxCount: 1,
    showUploadList: false,
    accept: fileAccept.join(','),
    beforeUpload: (file, fileList) => {
      const fileExt = file.name.substring(file.name.lastIndexOf('.'));
      if (!fileAccept.includes(fileExt.toLowerCase())) {
        message.error('请上传正确格式的图片');
        return false;
      }
      setFile(file);
      setFileList(fileList);
    },
    customRequest: async () => {
      setUploading(true);
      let data = null;
      if (file.size >= partSize) {
        data = await multipartUploader(file, 'image', ossClient, (progress, checkpoint) => {
          console.log(`上传进度 ${progress}`);
          setProgress(parseInt(progress * 100));
        });
        console.log('multipartUploader --> ', data);
      } else {
        data = await normalUploader(file, 'image', ossClient);
        console.log('normalUploader --> ', data);
      }

      if (data.status === 200 && data.statusCode === 200) {
        const { url, name } = data;
        setImgUrl(url);
        form.setFieldsValue({ imgUrl: url });
      }
      setUploading(false);
    },
  };

  const clear = () => {
    setImgUrl('');
    setProgress(0);
    setUploading(false);
    setTempNodeInfo(null);
    setInitValues({ imgUrl: imgUrl, imgTitle: '', imgDescript: '' });
    form.resetFields();
    setImageVisible(false);
  };

  const onFinish = (values) => {
    editor.restoreSelection();
    // editor.insertNode({
    //   type: 'chapterImage',
    //   title: values.imgTitle,
    //   imgUrl: values.imgUrl,
    //   imgDescript: values.imgDescript,
    //   children: [{ text: '' }],
    // });

    const nodeEntries = SlateEditor.nodes(editor, {
      match: (node) => {
        // JS syntax
        if (SlateElement.isElement(node)) {
          if (node.type === 'paragraph') {
            return true; // 匹配 paragraph
          }
        }
        return false;
      },
      universal: true,
    });
    for (let nodeEntry of nodeEntries) {
      const [node, path] = nodeEntry;
      if (node.children[0].text === '') {
        SlateTransforms.removeNodes(editor);
      }
    }

    const oImg = {
      type: 'paragraph',
      children: [
        {
          type: 'image',
          src: values.imgUrl,
          alt: values.imgTitle,
          href: values.imgDescript,
          children: [
            {
              // 该字段必须要
              text: '',
            },
          ],
        },
      ],
    };
    const oP = {
      type: 'paragraph',
      children: [{ text: values.imgTitle }],
    };

    if (tempNodeInfo && Object.entries(tempNodeInfo).length > 0) {
      const elem = editor.toDOMNode(tempNodeInfo.node); // 返回 HTMLElement
      let nodeProps = JSON.parse(JSON.stringify(tempNodeInfo.node));
      let obj = {};
      let cIndex = -1;
      nodeProps.children.forEach((element, index) => {
        if (element.type === 'image') {
          obj = {
            ...element,
            alt: values.imgTitle,
            src: values.imgUrl,
            href: values.imgDescript,
          };
          cIndex = index;
        }
      });

      SlateTransforms.removeNodes(editor);
      const elem2 = elem.nextSibling;
      if (elem2 && elem2.textContent === tempNodeInfo.image.alt) {
        elem2.parentNode.removeChild(elem2);
      }
      let nodes = [];
      if (values.imgTitle) {
        nodes.push(oP);
      }
      nodes.push(oImg);
      SlateTransforms.insertNodes(editor, nodes);
      clear();
      return;
    }
    let nodes = [];
    if (values.imgTitle) {
      nodes.push(oP);
    }
    nodes.push(oImg);

    SlateTransforms.insertNodes(editor, nodes);
    clear();
  };

  return (
    <div>
      <Divider />
      <div className='editor-content-form'>
        <Form
          layout='vertical'
          name='validate_other'
          form={form}
          onFinish={onFinish}
          initialValues={initValues}
        >
          <Form.Item
            label='上传图片'
            valuePropName='fileList'
            name='imgUrl'
            getValueFromEvent={normFile}
            rules={[{ required: true, message: '请上传图片' }]}
          >
            <Spin spinning={uploading} tip={`${progress}%`}>
              <div className='editor-dragger'>
                <Dragger {...uploadProps} showUploadList={false}>
                  {!imgUrl && (
                    <div className='editor-uploader-process'>
                      <p className='ant-upload-drag-icon'>
                        <CloudUploadOutlined style={{ fontSize: 40 }} />
                      </p>
                      <p className='ant-upload-text'>点击上传或拖拽到此处上传</p>
                      <p className='ant-upload-hint'>支持上传 .png、.jpg、.jpeg、.svg格式的图片</p>
                    </div>
                  )}
                  {imgUrl && (
                    <>
                      <div className='editor-uploader-result'>
                        <div className='editor-uploader-result-img'>
                          <img src={imgUrl} alt='' />
                        </div>
                        <div className='editor-uploader-result-tips'>
                          <Button size='small' type='primary' ghost onClick={() => setImgUrl(null)}>
                            替换
                          </Button>
                        </div>
                      </div>
                    </>
                  )}
                </Dragger>
              </div>
            </Spin>
          </Form.Item>
          <Form.Item label='图片标题' name='imgTitle' extra='最多输入100字'>
            <Input maxLength={100} placeholder='' allowClear />
          </Form.Item>
          <Form.Item label='图片描述' name='imgDescript' extra='最多输入200字'>
            <Input.TextArea
              maxLength={200}
              autosize={{ minRows: 4, maxRows: 6 }}
              placeholder=''
              allowClear
            />
          </Form.Item>
          <Form.Item className='editor-form-buttons'>
            <Space>
              <Button type='default' disabled={uploading} onClick={() => setImageVisible(false)}>
                取消
              </Button>
              <Button type='primary' disabled={uploading} htmlType='submit'>
                插入
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </div>
    </div>
  );
});

export default ImageModal;
