import React, { useCallback, useMemo, useRef, useState } from 'react'
import styles from './index.module.scss'

// 引入编辑器组件

// 安装---npm install braft-editor --save --force
// npm install braft-utils --save --force
import { ContentUtils } from 'braft-utils'
import BraftEditor from 'braft-editor'
// 引入编辑器样式
import 'braft-editor/dist/index.css'

import classNames from 'classnames'
import { MessageFu } from '@/utils/message'
import { fileDomInitialFu } from '@/utils/domShow'
import { baseURL } from '@/utils/http'

import { forwardRef, useImperativeHandle } from 'react'
import { API_upFile } from '@/store/action/layout'
import ZupAudio, { ZupAudioType } from '../ZupAudio'
import { Button, Checkbox, Input } from 'antd'
import { ArrowDownOutlined, DeleteOutlined, ArrowUpOutlined } from '@ant-design/icons'
import MyPopconfirm from '../MyPopconfirm'

export type SectionArrType = {
  id: number
  name: string
  txt: any
  fileInfo: ZupAudioType
}

type Props = {
  check: boolean //表单校验，为fasle表示不校验
  dirCode: string //文件的code码
  isLook: boolean //是否是查看进来
  ref: any //当前自己的ref，给父组件调用
  myUrl: string //上传的api地址
  isOne?: boolean //只显示单个富文本
  upAudioBtnNone?: boolean //是否能上传无障碍音频
  // 其他后端需要的配置项
  otherArr?: { key: string; value: string }[]
}

function ZRichTexts(
  {
    check,
    dirCode,
    isLook,
    myUrl,
    isOne = false,
    upAudioBtnNone = false,
    otherArr
  }: Props,
  ref: any
) {
  const [sectionArr, setSectionArr] = useState<SectionArrType[]>([
    {
      id: Date.now(),
      name: '',
      txt: BraftEditor.createEditorState(''),
      fileInfo: { fileName: '', filePath: '' }
    }
  ])

  // 是否按章节发布
  const [isSection, setIsSection] = useState(false)

  // 当前上传 图片
  const nowIndexRef = useRef(0)

  // 判断 富文本是否为空
  const isTxtFlag = useMemo(() => {
    let flag = false

    // 不是按章节发布，检查第一个富文本
    if (!isSection) {
      const txt = sectionArr[0].txt.toText()
      const txtHtml = sectionArr[0].txt.toHTML()
      const txtRes = txt.replaceAll('\n', '').replaceAll(' ', '')
      if (!txtRes && !txtHtml.includes('class="media-wrap')) flag = true
    } else {
      // 按章节发布  检查 所有的 标题 和富文本
      sectionArr.forEach(v => {
        if (!v.name) flag = true
        const txt = v.txt.toText()
        const txtHtml = sectionArr[0].txt.toHTML()
        const txtRes = txt.replaceAll('\n', '').replaceAll(' ', '')
        if (!txtRes && !txtHtml.includes('class="media-wrap')) flag = true
      })
    }

    return flag
  }, [isSection, sectionArr])

  const myInput = useRef<HTMLInputElement>(null)

  // 上传图片
  const handeUpPhoto = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        // 拿到files信息
        const filesInfo = e.target.files[0]

        let type = ['image/jpeg', 'image/png']
        let size = 5
        let txt = '图片只支持png、jpg和jpeg格式!'
        let txt2 = '图片最大支持5M!'

        // 校验格式
        if (!type.includes(filesInfo.type)) {
          e.target.value = ''
          return MessageFu.warning(txt)
        }

        // 校验大小
        if (filesInfo.size > size * 1024 * 1024) {
          e.target.value = ''
          return MessageFu.warning(txt2)
        }

        // 创建FormData对象
        const fd = new FormData()
        // 把files添加进FormData对象（‘photo’为后端需要的字段）
        fd.append('type', 'img')
        fd.append('dirCode', dirCode)
        fd.append('file', filesInfo)

        if (otherArr) {
          otherArr.forEach((v: any) => {
            fd.append(v.key, v.value)
          })
        }

        e.target.value = ''

        try {
          const res = await API_upFile(fd, myUrl)
          if (res.code === 0) {
            MessageFu.success('上传成功!')
            // 在光标位置插入图片
            const newTxt = ContentUtils.insertMedias(
              sectionArr[nowIndexRef.current].txt,
              [
                {
                  type: 'IMAGE',
                  url: baseURL + res.data.filePath
                }
              ]
            )
            const arr = [...sectionArr]
            arr[nowIndexRef.current].txt = newTxt
            setSectionArr(arr)
          }
          fileDomInitialFu()
        } catch (error) {
          fileDomInitialFu()
        }
      }
    },
    [dirCode, myUrl, otherArr, sectionArr]
  )

  // 让父组件调用的 回显 富文本
  const ritxtShowFu = useCallback((val: any) => {
    if (val) {
      setIsSection(val.isSection || false)
      if (val.txtArr) {
        const arr = val.txtArr.map((v: any) => ({
          ...v,
          txt: BraftEditor.createEditorState(v.txt)
        }))
        setSectionArr(arr)
      }
    }
  }, [])

  // 让父组件调用的返回 富文本信息 和 表单校验 isTxtFlag为ture表示未通过校验
  const fatherBtnOkFu = useCallback(() => {
    const arr: any[] = []

    sectionArr.forEach((v, i) => {
      arr.push({
        ...v,
        txt: v.txt.toHTML()
      })
    })

    const obj = {
      isSection: isSection, //是否按章节发布
      txtArr: arr,
      isTxtFlag
    }

    return { val: obj, flag: isTxtFlag }
  }, [isSection, isTxtFlag, sectionArr])

  // 可以让父组件调用子组件的方法
  useImperativeHandle(ref, () => ({
    ritxtShowFu,
    fatherBtnOkFu
  }))

  // 点击新增章节
  const addSectionFu = useCallback(() => {
    if (sectionArr.length >= 20) return MessageFu.warning('最多存在20个章节')
    setSectionArr([
      ...sectionArr,
      {
        id: Date.now(),
        name: '',
        txt: BraftEditor.createEditorState(''),
        fileInfo: { fileName: '', filePath: '' }
      }
    ])
  }, [sectionArr])

  // 章节音频上传成功
  const upSectionFu = useCallback(
    (info: ZupAudioType, index: number) => {
      const arr = [...sectionArr]
      arr[index].fileInfo = info
      setSectionArr(arr)
    },
    [sectionArr]
  )

  // 章节音频删除
  const delSectionFu = useCallback(
    (index: number) => {
      // console.log("ppppppppp", index);

      const arr = [...sectionArr]
      arr[index].fileInfo = { fileName: '', filePath: '' }
      setSectionArr(arr)
    },
    [sectionArr]
  )

  // 整个章节的删除
  const delSectionAllFu = useCallback(
    (id: number) => {
      setSectionArr(sectionArr.filter(v => v.id !== id))
    },
    [sectionArr]
  )

  // 整个章节的位移
  const moveSectionFu = useCallback(
    (index: number, num: number) => {
      const arr = [...sectionArr]
      const temp = arr[index]
      arr[index] = arr[index + num]
      arr[index + num] = temp
      setSectionArr(arr)
    },
    [sectionArr]
  )

  // 单个富文本是否输入完整
  const isOneTxtFlag = useCallback(
    (name: string, txt: any) => {
      let flag = false
      if (!name && isSection) flag = true
      const txt2 = txt.toText()
      const txtHtml = txt.toHTML()
      const txtRes = txt2.replaceAll('\n', '').replaceAll(' ', '')
      if (!txtRes && !txtHtml.includes('class="media-wrap')) flag = true
      return flag
    },
    [isSection]
  )

  return (
    <div className={styles.ZRichTexts}>
      <input
        id='upInput'
        type='file'
        accept='.png,.jpg,.jpeg'
        ref={myInput}
        onChange={e => handeUpPhoto(e)}
      />

      <div className={classNames('formRightZW', isLook ? 'formRightZWLook' : '')}>
        {isOne ? (
          <div></div>
        ) : (
          <Checkbox checked={isSection} onChange={e => setIsSection(e.target.checked)}>
            按章节发布
          </Checkbox>
        )}

        {isSection ? (
          <Button hidden={isLook} type='primary' onClick={addSectionFu}>
            新增章节
          </Button>
        ) : (
          <div className='formRightZWRR'>
            {upAudioBtnNone ? null : (
              <ZupAudio
                fileInfo={sectionArr[0].fileInfo}
                upDataFu={info => upSectionFu(info, 0)}
                delFu={() => delSectionFu(0)}
                dirCode={dirCode}
                myUrl={myUrl}
                isLook={isLook}
              />
            )}

            <div hidden={isLook}>
              <Button
                onClick={() => {
                  nowIndexRef.current = 0
                  myInput.current?.click()
                }}
              >
                上传图片
              </Button>
            </div>
          </div>
        )}
      </div>

      <div className={classNames('txtBox', isLook ? 'txtBoxLook' : '')}>
        {sectionArr.map((item, index) => (
          <div
            className={classNames(
              'zztxtRow',
              isOneTxtFlag(item.name, item.txt) && check ? 'zztxtRowErr' : ''
            )}
            key={item.id}
            hidden={!isSection && index > 0}
          >
            {/* 顶部 */}
            <div className='zztxtRow1' hidden={!isSection && index === 0}>
              <div className='zztxtRow1_1'>
                <div className='zztxtRow1_1_1'>章节 {index + 1}</div>
                <div className='zztxtRow1_1_2'>
                  标题：
                  <Input
                    readOnly={isLook}
                    value={item.name}
                    placeholder='请输入内容'
                    maxLength={100}
                    showCount
                    style={{ width: 400 }}
                    onChange={e => {
                      const arr = [...sectionArr]
                      arr[index].name = e.target.value.replace(/\s+/g, '')
                      setSectionArr(arr)
                    }}
                  />
                  &emsp;
                  <Button
                    hidden={isLook}
                    onClick={() => {
                      nowIndexRef.current = index
                      myInput.current?.click()
                    }}
                  >
                    上传图片
                  </Button>
                </div>
              </div>
              <div className='zztxtRow1_2'>
                <ZupAudio
                  fileInfo={item.fileInfo}
                  upDataFu={info => upSectionFu(info, index)}
                  delFu={() => delSectionFu(index)}
                  dirCode={dirCode}
                  myUrl={myUrl}
                  isLook={isLook}
                />
                &emsp;
                <div
                  hidden={isLook}
                  className={classNames(
                    'zztxtRow1_2Icon',
                    index === 0 ? 'zztxtRow1_2IconNo' : ''
                  )}
                  onClick={() => moveSectionFu(index, -1)}
                >
                  <ArrowUpOutlined title='上移' rev={undefined} />
                </div>
                &emsp;
                <div
                  hidden={isLook}
                  className={classNames(
                    'zztxtRow1_2Icon',
                    index === sectionArr.length - 1 ? 'zztxtRow1_2IconNo' : ''
                  )}
                  onClick={() => moveSectionFu(index, 1)}
                >
                  <ArrowDownOutlined title='下移' rev={undefined} />
                </div>
                &emsp;
                {isLook || sectionArr.length <= 1 ? null : (
                  <MyPopconfirm
                    txtK='删除'
                    onConfirm={() => delSectionAllFu(item.id)}
                    Dom={
                      <DeleteOutlined title='删除' className='ZTbox2X' rev={undefined} />
                    }
                  />
                )}
              </div>
            </div>
            {/* 主体 */}
            <BraftEditor
              readOnly={isLook}
              placeholder='请输入内容'
              value={item.txt}
              onChange={e => {
                const arr = [...sectionArr]
                arr[index].txt = e
                setSectionArr(arr)
              }}
              imageControls={['remove']}
            />
          </div>
        ))}
      </div>
      <div className={classNames('noUpThumb', check && isTxtFlag ? 'noUpThumbAc' : '')}>
        {`请完整输入${isSection ? '标题/' : ''}正文!`}
      </div>
    </div>
  )
}

export default forwardRef(ZRichTexts)
