import { useState, useEffect, forwardRef, useImperativeHandle } from 'react'
import {
  Divider,
  Upload,
  Input,
  Space,
  Button,
  Form,
  Spin,
  message,
  ColorPicker,
  Select,
  InputNumber,
  Row,
  Col
} from 'antd'
import { CloudUploadOutlined } from '@ant-design/icons'
import { SlateEditor, SlateTransforms, SlateElement } from '@wangeditor/editor'
import { fontFamilyList, fontSizeList } from '../utils/setting'
import './index.less'

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

const { Dragger } = Upload

const ImageModal = (props, ref) => {
  const { editor, setTitleVisible, titleInfo, setTitleInfo } = props

  const fileAccept = ['.png', '.jpg', '.jpeg', '.svg']
  const [form] = Form.useForm()
  const [bgColorValue, setBgColorValue] = useState('#000000')
  const [textColor, setTextColor] = useState('#ffffff')
  const [uploading, setUploading] = useState(false) // 文件上传状态
  const [progress, setProgress] = useState(0)
  const [file, setFile] = useState({})
  const [imgUrl, setImgUrl] = useState('')
  const [initValues, setInitValues] = useState({
    title: '',
    size: 32,
    bgImgUrl: '',
    textColor: textColor,
    align: 'left',
    bgColor: bgColorValue,
    height: 200,
    family: '黑体'
  })
  // 是否更新的判断
  const [toolStatus, setToolStatus] = useState(false)
  const [nowRandom, setNowRandom] = useState(null)

  useEffect(() => {
    if (titleInfo && Object.entries(titleInfo).length > 0) {
      setInitValues({ ...titleInfo })
      setImgUrl(titleInfo.bgImgUrl)
      form.setFieldsValue({ ...titleInfo })
      setTextColor(titleInfo.textColor)
      setBgColorValue(titleInfo.bgColor)
      setNowRandom(titleInfo.random)
      setTitleInfo({})
    }
  }, [titleInfo])

  useImperativeHandle(ref, () => {
    return {
      form,
      setInitValues
    }
  })

  const textColorChange = value => {
    const hex = typeof value === 'string' ? value : value?.toHexString()
    setTextColor(hex)
    form.setFieldsValue({ textColor: hex })
  }
  const bgColorChange = value => {
    const hex = typeof value === 'string' ? value : value?.toHexString()
    setBgColorValue(hex)
    form.setFieldsValue({ bgColor: hex })
  }

  const callback = ({ title, random, bgImgUrl, textColor, align, height, size, family }) => {
    form.setFieldsValue({
      title: title,
      bgImgUrl: bgImgUrl,
      textColor: textColor,
      align: align,
      height: height,
      size: size,
      family: family
    })
    setImgUrl(bgImgUrl)
    setToolStatus(true)
    setNowRandom(random)
  }

  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({ bgImgUrl: url })
      setUploading(false)
    }
  }

  const onFinish = 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)
      }
    }

    if (nowRandom) {
      const nodeEntries = SlateEditor.nodes(editor, {
        match: node => {
          // JS syntax
          if (SlateElement.isElement(node)) {
            if (node.type === 'chapterHeader') {
              return true // 匹配 chapterHeader
            }
          }
          return false
        },
        universal: true
      })

      if (nodeEntries) {
        for (let nodeEntry of nodeEntries) {
          const [node, path] = nodeEntry
          if (parseInt(node.random) === parseInt(nowRandom)) {
            SlateTransforms.setNodes(editor, { ...node, ...values }, { at: path })
            setImgUrl('')
            setProgress(0)
            setUploading(false)
            form.resetFields()
            setTitleVisible(false)
            return false
          }
        }
      }
      return false
    }

    const html = editor.getHtml()
    const parser = new DOMParser()
    let random = Math.random().toString(10).substring(2, 10)
    if (nowRandom) {
      random = nowRandom
    }
    const docBody = parser.parseFromString(html, 'text/html')
    const section = docBody.body.querySelectorAll('.chapter-item-header') // 是否存在章头

    editor.insertNode({
      type: 'chapterHeader',
      title: values.title,
      textColor: values.textColor,
      bgImgUrl: values.bgImgUrl,
      align: values.align,
      random: random,
      bgColor: values.bgColor ? values.bgColor : '',
      height: values.height ? values.height : 200,
      size: values.size ? values.size : 26,
      family: values.family,
      callback: callback,
      children: [{ text: '' }]
    })
    setImgUrl('')
    setProgress(0)
    setUploading(false)
    form.resetFields()
    setTitleVisible(false)
  }

  return (
    <div>
      <Divider />
      <div className="editor-content-form">
        <Form layout="vertical" name="validate_other" form={form} onFinish={onFinish} initialValues={initValues}>
          <Form.Item label="章头背景图片" name="bgImgUrl">
            <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">
                          <Space>
                            <Button
                              size="small"
                              type="primary"
                              ghost
                              onClick={() => {
                                setImgUrl(null)
                                form.setFieldsValue({ bgImgUrl: '' })
                              }}>
                              替换
                            </Button>
                            <Button
                              size="small"
                              type="default"
                              onClick={ev => {
                                ev.stopPropagation()
                                ev.preventDefault()
                                setImgUrl(null)
                                form.setFieldsValue({ bgImgUrl: '' })
                              }}>
                              移除
                            </Button>
                          </Space>
                        </div>
                      </div>
                    </>
                  )}
                </Dragger>
              </div>
            </Spin>
          </Form.Item>
          <Form.Item label="标题" name="title" rules={[{ required: true, message: '请输入标题' }]} extra="最多输入30字">
            <Input maxLength={30} placeholder="" allowClear />
          </Form.Item>
          <Form.Item>
            <Row gutter={20}>
              <Col span={12}>
                <div className="justcontent-color-inline">
                  <Form.Item
                    label="章头背景色"
                    name="bgColor"
                    className="flex-max"
                    rules={[{ pattern: /^#[0-9A-Fa-f]{6}$/i, message: '请输入正确的16进制色值' }]}>
                    <Input placeholder="" allowClear />
                  </Form.Item>
                  <Form.Item label={` `}>
                    <ColorPicker
                      disabledAlpha
                      value={bgColorValue}
                      defaultValue={bgColorValue}
                      format="hex"
                      onChange={bgColorChange}
                    />
                  </Form.Item>
                </div>
              </Col>
              <Col span={12}>
                <div className="justcontent-color-inline">
                  <Form.Item
                    label="文本颜色"
                    name="textColor"
                    className="flex-max"
                    rules={[{ pattern: /^#[0-9A-Fa-f]{6}$/i, message: '请输入正确的16进制色值' }]}>
                    <Input maxLength={100} placeholder="" allowClear />
                  </Form.Item>
                  <Form.Item label={` `}>
                    <ColorPicker
                      value={textColor}
                      defaultValue={textColor}
                      disabledAlpha
                      format="hex"
                      onChange={textColorChange}
                    />
                  </Form.Item>
                </div>
              </Col>
              <Col span={12}>
                <Form.Item label="字体" name="family">
                  <Select>
                    {fontFamilyList.map((item, index) => {
                      return (
                        <Select.Option value={item.value} key={index}>
                          {item.name}
                        </Select.Option>
                      )
                    })}
                  </Select>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="文字大小" name="size" rules={[{ required: true, message: '请输入文字大小' }]}>
                  <Select>
                    {fontSizeList.map((item, index) => {
                      return (
                        <Select.Option value={item.value} key={index}>
                          {item.name}
                        </Select.Option>
                      )
                    })}
                  </Select>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="对齐方式" name="align" rules={[{ required: true, message: '请选择对齐方式' }]}>
                  <Select>
                    <Select.Option value="left">左对齐</Select.Option>
                    <Select.Option value="center">居中对齐</Select.Option>
                    <Select.Option value="right">右对齐</Select.Option>
                  </Select>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item label="高度" name="height">
                  <InputNumber
                    controls={false}
                    placeholder=""
                    style={{ width: '100%', textAlign: 'left' }}
                    allowClear
                  />
                </Form.Item>
              </Col>
            </Row>
          </Form.Item>
          <Form.Item className="editor-form-buttons">
            <Space>
              <Button type="default" disabled={uploading} onClick={() => setTitleVisible(false)}>
                取消
              </Button>
              <Button type="primary" disabled={uploading} htmlType="submit">
                {nowRandom ? '更新' : '插入'}
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </div>
    </div>
  )
}

export default forwardRef(ImageModal)
