import { useState, useEffect, forwardRef } from 'react'
import { 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 OnlineImageList from './onlineImageList'

import { uploadFile } from '@/utils/oss'

const { Dragger } = Upload

const ImageModal = (props, ref) => {
  const { editor, setImageVisible, imageInfo, setImageInfo, isOnline = false } = 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 [initValues, setInitValues] = useState({ imgUrl: '', imgTitle: '', imgDescript: '' })
  const [tempNodeInfo, setTempNodeInfo] = useState(null)

  useEffect(() => {
    if (imageInfo && Object.entries(imageInfo).length > 0) {
      const { image } = 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({})
      setImageInfo({})
    }
  }, [imageInfo])

  const uploadProps = {
    name: 'file',
    maxCount: 1,
    showUploadList: false,
    accept: fileAccept.join(','),
    beforeUpload: file => {
      const fileExt = file.name.substring(file.name.lastIndexOf('.'))
      if (!fileAccept.includes(fileExt.toLowerCase())) {
        message.error('请上传正确格式的图片')
        return false
      }
      setFile(file)
    },
    customRequest: async () => {
      setUploading(true)
      const url = await uploadFile(file)
      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 => {
    console.log(values)
    editor.restoreSelection()

    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] = nodeEntry
      if (node.children[0].text === '') {
        SlateTransforms.removeNodes(editor)
      }
    }

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

    if (tempNodeInfo && Object.entries(tempNodeInfo).length > 0) {
      const elem = editor.toDOMNode(tempNodeInfo.node) // 返回 HTMLElement
      const nextElem = elem.nextSibling

      SlateTransforms.removeNodes(editor)

      // 当前结构下标题固定在图片下方
      if (nextElem && nextElem.textContent === tempNodeInfo.image.alt) {
        nextElem.parentNode.removeChild(nextElem)
      }

      let nodes = []
      nodes.push(oImg)
      if (values.imgTitle) {
        nodes.push(oP)
      }
      SlateTransforms.insertNodes(editor, nodes)
      clear()
      return
    }
    let nodes = []
    nodes.push(oImg)
    if (values.imgTitle) {
      nodes.push(oP)
    }

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

  const onOnlineImageChange = url => {
    setImgUrl(url)
    form.setFieldsValue({ imgUrl: url })
  }
  return (
    <div>
      <Divider />
      <div className="editor-content-form">
        <Form layout="vertical" name="validate_other" form={form} onFinish={onFinish} initialValues={initValues}>
          {isOnline ? (
            <Form.Item label="在线图片" name="imgUrl" rules={[{ required: true, message: '请选择图片' }]}>
              <OnlineImageList imgUrl={imgUrl} onChange={onOnlineImageChange}></OnlineImageList>
            </Form.Item>
          ) : (
            <Form.Item label="上传图片" name="imgUrl" 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 forwardRef(ImageModal)
