import React, { useEffect, useRef, useState } from 'react'
import { Prompt } from 'react-router-dom'
import {
  DragDropContext,
  Droppable,
  Draggable,
  DroppableProvided,
  DroppableStateSnapshot,
  DraggableProvided,
  DraggableStateSnapshot,
  DropResult,
  ResponderProvided,
  DraggingStyle,
  NotDraggingStyle
} from 'react-beautiful-dnd'

import useRequest from '@ahooksjs/use-request/es'
import { useHistory } from 'react-router-dom'

import { Modal, Popover, Upload, UploadProps, message } from 'antd'
import { Input } from 'antd'
import { SearchOutlined } from '@ant-design/icons'

import { ReactComponent as File } from 'assets/file.svg'
import { ReactComponent as Image } from 'assets/image.svg'
import { ReactComponent as Close } from 'assets/close.svg'
import { ReactComponent as Close2 } from 'assets/close2.svg'

import { FilesSvg } from './ColumnEditor'
import Picture from 'Activity/components/Picture'
import { ColumnType } from './components/ColumnContent'
import { MaterialService } from 'Material/Material.service'
import { ColumnService, IDocsList, ISaveColumnDetailParams, IUploadFileRes } from './Column.service'
import { ColumnStatus } from './components/ColumnCenter'
import styles from './css/ColumnEditor.module.scss'

const FroalaWrapper = React.lazy(() => import('components/FroalaWrapper'))

interface IColumnModifyProps {
  articleId: number // 文章ID(笔记或观点的ID)
}

let timer: NodeJS.Timeout

/**修改并发布-笔记/观点 */
const ColumnModify: React.FC<IColumnModifyProps> = props => {
  const history = useHistory()
  const froalaInstanceRef = useRef<any>(null)
  const [froalaValue, setFroalaValue] = useState('') // 正文
  const [selectType, setSelectType] = useState(1) // 类型1:笔记，2:观点
  const [searchCategrayValue, setSearchCategrayValue] = useState<string>('') // 搜索行业标签
  const [searchCompanyValue, setSearchCompanyValue] = useState<string>('') // 搜索公司标签
  const [industryTags, setIndustryTags] = useState<string[]>([]) // 选中的行业标签
  const [companyTags, setCompanyTags] = useState<string[]>([]) // 选中的公司标签
  const [bigImg, setBigImg] = useState<string>() // 展开的图片
  const [title, setTitle] = useState<string>('') // 标题
  const [fileList, setFileList] = useState<IDocsList[]>([]) // 上传文件列表
  const [fileImageList, setFileImageList] = useState<IUploadFileRes[]>([]) // 上传图片列表
  const [clickType, setClickType] = useState<number>() // 记录点击操作
  const [hasModify, setHasModify] = useState(false) // 是否有变动

  useEffect(() => {
    const listener = (e: any) => {
      e.preventDefault()
      e.returnValue = '内容还未保存，确定离开吗？'
    }
    if (hasModify) {
      window.addEventListener('beforeunload', listener)
    }
    return () => {
      clearTimeout(timer)
      window.removeEventListener('beforeunload', listener)
    }
  }, [hasModify])

  useEffect(() => {
    props.articleId && getColumnDetail(props.articleId)
    getSearchIndustry('')
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.articleId])

  // 详情
  const { data: columnDetail, run: getColumnDetail } = useRequest(ColumnService.getColumnDetail, {
    manual: true,
    formatResult: response => response.data.Data,
    onSuccess: res => {
      setSelectType(res.Type)
      setTitle(res.Title)
      setFroalaValue(res.Content)
      setFileList(res.Docs)
      setIndustryTags(res.IndustryTags)
      setCompanyTags(res.CompanyTags)
      const imgList = res?.ImgUrlList?.map((item: string, index: number) => ({ Id: index, ResourceUrl: item }))
      setFileImageList(imgList || [])
    }
  })
  // 保存前的校验
  const { loading: checkLoading, run: applyCheckColumnDetail } = useRequest(ColumnService.postCheckColumnDetail, {
    manual: true,
    onSuccess: res => {
      if (res.data.Success) {
        const previewDetail = formatPreviewDetail(clickType)
        applySaveColumnDetail(previewDetail)
      } else {
        message.error(res.data.Msg || res.data.ErrMsg)
      }
    }
  })
  // 保存
  const { loading: saveLoading, run: applySaveColumnDetail } = useRequest(ColumnService.postSaveColumnDetail, {
    manual: true,
    onSuccess: res => {
      res.data.Success ? message.success(res.data.Msg) : message.error(res.data.Msg || res.data.ErrMsg)
      res.data.Success && setHasModify(false)
      res.data.Success && history.push(`/column`)
    }
  })

  const { data: industryList, run: getSearchIndustry } = useRequest(ColumnService.getSearchIndustry, {
    manual: true,
    formatResult: response => response.data.Data
  })
  const { data: companyList, run: getSearchCompanyTags } = useRequest(ColumnService.getSearchCompanyTags, {
    manual: true,
    formatResult: response => response.data.Data
  })

  const handleFormatFileList = (item: IUploadFileRes) => {
    return {
      DocName: item.ResourceName,
      DocSuffix: computeFileSvgShow(item?.ResourceName || '', 'suffix'),
      DocUrl: item.ResourceUrl
      // DocIcon?: string
    } as IDocsList
  }
  const computeFileSvgShow = (name: string, type: 'suffix' | 'svg') => {
    if (!name) return
    const suffix = name?.split('.')?.pop()
    if (type === 'suffix') return suffix
    return FilesSvg?.find(item => item.suffix === suffix)?.svg
  }
  // 上传文件
  const uploadFileprops: UploadProps = {
    name: 'file',
    accept: '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf',
    headers: {
      authorization: 'authorization-text'
    },
    multiple: true,
    itemRender: () => {
      // 不渲染
    },
    beforeUpload: file => {
      const allowedExtensions = ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf']
      const fileExtension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase()

      if (!allowedExtensions.includes(fileExtension)) {
        message.error('只允许上传.doc, .docx, .xls, .xlsx, .ppt, .pptx 和 .pdf 文件')
        return Upload.LIST_IGNORE
      }
    },
    customRequest: async options => {
      try {
        const response = await ColumnService.postUploadFile(options.file)
        if (!response.data.Success) return message.error(response.data.Msg || response.data.ErrMsg)
        const fileItem = handleFormatFileList(response.data?.Data)
        setFileList(prevList => [...(prevList || []), fileItem])
        setHasModify(true)
      } catch (error) {
        console.log(error)
      }
    }
  }
  // 上传图片
  const uploadImageprops: UploadProps = {
    name: 'file',
    accept: 'image/*',
    headers: {
      authorization: 'authorization-text'
    },
    multiple: true,
    maxCount: 6,
    itemRender: () => {
      // 不渲染
    },
    beforeUpload: file => {
      const isPNG = file.type.toLowerCase().includes('image')
      if (!isPNG) {
        message.error(`请上传图片`)
      }
      return isPNG || Upload.LIST_IGNORE
    },
    customRequest: async options => {
      try {
        if (fileImageList.length >= 6) return message.error('最多上传6张图片')
        const response = await MaterialService.postUploadImage(options.file)
        if (!response.data.Success) return message.error(response.data.Msg || response.data.ErrMsg)
        setFileImageList(prevList => {
          if (prevList?.length >= 6) {
            message.error('最多上传6张图片')
            return prevList
          }
          return [...(prevList || []), response.data.Data]
        })
        setHasModify(true)
      } catch (error) {
        console.log(error)
      }
    }
  }
  // 删除文件
  const handleDeleteFile = (file: IDocsList, e: React.MouseEvent) => {
    e.stopPropagation()
    setFileList(prevList => prevList.filter(item => item.DocName !== file.DocName))
    setHasModify(true)
  }
  // 删除图片
  const handleDeleteImg = (img: IUploadFileRes, e: React.MouseEvent) => {
    e.stopPropagation()
    setFileImageList(prevList => prevList.filter(item => item.Id !== img.Id))
    setHasModify(true)
  }

  const handleSelectType = (type: number) => {
    setSelectType(type)
    setHasModify(true)
  }

  // 关闭图片查看
  const handleToCloseBigImg = () => {
    setBigImg(undefined)
  }

  // 图片拖拽 start
  const reorder = (list: IUploadFileRes[], startIndex: number, endIndex: number) => {
    const result = Array.from(list)
    const [removed] = result.splice(startIndex, 1)
    result.splice(endIndex, 0, removed)
    return result
  }
  const getItemStyle = (isDragging: boolean, draggableStyle: DraggingStyle | NotDraggingStyle | undefined) =>
    ({
      userSelect: 'none',
      margin: `0 20px 20px 0`,
      background: isDragging ? '#ffffff' : '#ffffff',
      ...draggableStyle
    } as React.CSSProperties)

  const getListStyle = (isDraggingOver: boolean) => ({
    background: isDraggingOver ? '#ffffff' : '#ffffff',
    display: 'flex',
    overflow: 'auto'
  })

  const onDragEnd = (result: DropResult, provided: ResponderProvided) => {
    if (!result.destination) {
      return
    }
    const reorderedList = reorder(fileImageList, result.source.index, result.destination.index)
    setFileImageList(reorderedList)
    setHasModify(true)
  }
  // 图片拖拽 end

  // 修改并发布
  const handleToClick = (type: string) => {
    if (!columnDetail?.IsApprovalAdmin) return message.error('您没有权限操作')
    if (columnDetail?.Status !== ColumnStatus.Auditing) return message.error('该文章未提交审批或已审批')
    if (checkLoading || saveLoading) return
    const typeFn: {
      [key: string]: () => void
    } = {
      modify: () => {
        Modal.confirm({
          title: '提示',
          content: '确定修改并通过此内容的审核吗？',
          okText: '确定',
          cancelText: '取消',
          centered: true,
          closable: true,
          onOk: () => {
            handleApplyCheckColumnDetail(2)
          }
        })
      }
    }
    typeFn[type]()
  }
  // 保存/发布前先校验
  const handleApplyCheckColumnDetail = (doType: number) => {
    if (!title) return message.error('请输入标题')
    if (doType === 2 && !froalaValue) return message.error('请输入正文')
    if (doType === 2 && industryTags?.length === 0 && companyTags?.length === 0)
      return message.error('请选至少选择一个标签')
    setClickType(doType)
    const imgList = getImgUrlList(froalaValue)
    const uploadImgList = fileImageList?.map(item => item.ResourceUrl)

    applyCheckColumnDetail({ Content: froalaValue, ImgUrl: imgList.concat(uploadImgList) })
  }

  // 获取正文中添加的img地址
  const getImgUrlList = (str: string) => {
    // 匹配 <img> 标签的 src 属性
    const imgRegex = /<img[^>]+src="([^">]+)"/g
    // 使用正则表达式的 exec 方法来提取匹配的内容
    let match
    const imgSrcList = []

    while ((match = imgRegex.exec(str)) !== null) {
      const src = match[1] // 提取的 src 属性值
      imgSrcList.push(src)
    }
    return imgSrcList
  }
  // 标题
  const handleInputTitle = (e: React.ChangeEvent<HTMLInputElement>) => {
    setTitle(e.target.value.replace(/\s/g, ''))
    setHasModify(true)
  }
  // 正文编辑
  const handleChangeText = (value: string) => {
    setFroalaValue(value)
    setHasModify(true)
  }

  // 组合预览详情
  const formatPreviewDetail = (doType?: number) => {
    // 图片
    const imgList = fileImageList?.map(item => item.ResourceUrl)
    return {
      Id: props.articleId || 0,
      Content: froalaValue,
      IndustryTags: industryTags, // 行业标签
      CompanyTags: companyTags, // 公司标签
      DoType: doType || 0, // 1保存2发布
      ImgUrl: imgList,
      Docs: fileList,
      Title: title,
      Type: selectType, //类型1:笔记，2:观点
      IsApprovalPersonnel: true
    } as ISaveColumnDetailParams
  }
  // 搜索行业标签
  const handleChangeSearchCategrayValue = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchCategrayValue(e.target.value.replace(/\s/g, ''))
    clearTimeout(timer)
    timer = setTimeout(() => {
      getSearchIndustry(e.target.value)
    }, 500)
  }
  // 搜索公司标签
  const handleChangeSearchCompanyValue = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchCompanyValue(e.target.value.replace(/\s/g, ''))
    clearTimeout(timer)
    timer = setTimeout(() => {
      getSearchCompanyTags(e.target.value)
    }, 500)
  }
  // 删除行业标签
  const handleDeleteIndustry = (tag: string, e: React.MouseEvent) => {
    // 阻止冒泡
    e.stopPropagation()
    setIndustryTags(prevList => prevList.filter(item => item !== tag))
    setHasModify(true)
  }
  // 删除公司标签
  const handleDeleteCompany = (tag: string, e: React.MouseEvent) => {
    e.stopPropagation()
    setCompanyTags(prevList => prevList.filter(item => item !== tag))
    setHasModify(true)
  }
  // 添加公司标签
  const handleAddCompanyTag = () => {
    if (!searchCompanyValue) return message.error('请输入标签')
    if (companyTags?.includes(searchCompanyValue)) return message.error('已存在该标签')
    setCompanyTags(prevList => [...prevList, searchCompanyValue])
    setSearchCompanyValue('')
    setHasModify(true)
  }

  // 选中的标签
  const handleAddTags = (actItem: string, type: 'industry' | 'company') => {
    if (type === 'industry') {
      // 如果存在则删除
      if (industryTags?.includes(actItem)) {
        setIndustryTags(prevList => prevList.filter(item => item !== actItem))
        return
      }
      setIndustryTags(prevList => [...prevList, actItem])
    } else {
      // 如果存在则删除
      if (companyTags?.includes(actItem)) {
        setCompanyTags(prevList => prevList.filter(item => item !== actItem))
        return
      }
      setCompanyTags(prevList => [...prevList, actItem])
    }
    setHasModify(true)
  }

  return (
    <div className={styles['columnedit-page']} style={{ overflow: 'auto', height: '100%' }}>
      <Prompt message="您有未保存的数据，确定离开本页面吗?" when={hasModify} />
      <Picture visible={!!bigImg} imgSrc={bigImg} onClose={handleToCloseBigImg} />
      <div className="columnedit-top">
        <strong>发布内容</strong>
        <div className="columnedit-select">
          <span
            className={`columnedit-select-label ${
              selectType === ColumnType.Note ? 'columnedit-active' : 'columnedit-notselect'
            }`}
            onClick={handleSelectType.bind(this, ColumnType.Note)}
          >
            笔记
          </span>
          <span
            className={`columnedit-select-label ${
              selectType === ColumnType.Viewpoint ? 'columnedit-active' : 'columnedit-notselect'
            }`}
            onClick={handleSelectType.bind(this, ColumnType.Viewpoint)}
          >
            观点
          </span>
        </div>
      </div>
      <div className="columnedit-title-wrapper">
        <input
          type="text"
          placeholder="请输入标题"
          className="columnedit-title-input"
          value={title}
          onChange={handleInputTitle}
        />
      </div>
      <div className="columnedit-edit-wrapper">
        <FroalaWrapper
          handleUpstream={editorInstance => {
            froalaInstanceRef.current = editorInstance
          }}
          value={froalaValue}
          onChange={handleChangeText}
          configType="column"
        />
      </div>
      <div className="columnedit-edit-operate-wrapper">
        <div className="operate-file-wrapper">
          {fileList?.map((item, index) => (
            <div className="operate-file-item" key={index}>
              <div className="g-flex g-flex-v-center">
                {computeFileSvgShow(item.DocName, 'svg')}
                <span className="operate-file-text">{item.DocName}</span>
              </div>
              <Close className="delete-file" onClick={handleDeleteFile.bind(this, item)} />
            </div>
          ))}
        </div>
        <div className="operate-file-wrapper">
          <DragDropContext onDragEnd={onDragEnd}>
            <Droppable droppableId="droppable" direction="horizontal">
              {(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => (
                <div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)} {...provided.droppableProps}>
                  {fileImageList?.map((item, index) => (
                    <Draggable key={item.Id} draggableId={item.Id.toString()} index={index}>
                      {(provided2: DraggableProvided, snapshot2: DraggableStateSnapshot) => (
                        <div
                          ref={provided2.innerRef}
                          {...provided2.draggableProps}
                          {...provided2.dragHandleProps}
                          style={getItemStyle(snapshot2.isDragging, provided2.draggableProps.style)}
                        >
                          <div className="operate-image-item">
                            <img src={item?.ResourceUrl} alt="图片" className="operate-image" />
                            <Close2 className="delete2-select" onClick={handleDeleteImg.bind(this, item)} />
                          </div>
                        </div>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          </DragDropContext>
        </div>
        <div className="operate-btn-wrapper">
          <div className="operate-left-btn">
            <Upload {...uploadFileprops}>
              <div className="operate-btn-item operate-upload-btn">
                <File className="upload-file-icon" />
                <span className="upload-file-text">上传文件</span>
              </div>
            </Upload>
            <Upload {...uploadImageprops}>
              <div className="operate-btn-item operate-upload-btn">
                <Image className="upload-file-icon" />
                <span className="upload-file-text">上传图片</span>
              </div>
            </Upload>
            <Popover
              content={
                <div className={styles['operate-select-label']}>
                  <div className="operate-select-search">
                    <SearchOutlined className="com-fz16" />
                    <Input
                      className="operate-search-input"
                      placeholder="搜索行业分类"
                      size="large"
                      variant="borderless"
                      value={searchCategrayValue}
                      onChange={handleChangeSearchCategrayValue}
                    />
                  </div>
                  <div className="selected-line">
                    <div className="select-title">
                      <span>已选标签</span>
                      <span className="select-tips-gray">
                        {industryTags.length === 0 ? '至少添加一个标签' : `已选${industryTags.length}个标签`}
                      </span>
                    </div>
                    <div className={`${styles['select-item-wrapper']} selected-wrapper`}>
                      {industryTags?.map(item => (
                        <div className="select-item active-select-item" key={item}>
                          <span>{item}</span>
                          <Close className="delete-select" onClick={handleDeleteIndustry.bind(this, item)} />
                        </div>
                      ))}
                    </div>
                  </div>
                  <div className="will-select-line">
                    <div className="select-title">标签</div>
                    <div className={`${styles['select-item-wrapper']} will-select-wrapper`}>
                      {industryList?.map(item => (
                        <div
                          className={`select-item ${industryTags.includes(item) ? 'active-select-item' : ''}`}
                          key={item}
                          onClick={handleAddTags.bind(this, item, 'industry')}
                        >
                          <span>{item}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              }
              trigger="click"
            >
              <div className="operate-btn-item operate-add-label">
                {industryTags?.length ? (
                  <div className={`${styles['select-item-wrapper']} operate-add-select`}>
                    {industryTags.map(item => (
                      <div className="select-item " key={item}>
                        <span>{item}</span>
                      </div>
                    ))}
                  </div>
                ) : (
                  <span className="add-categray-label-text">添加行业标签</span>
                )}
              </div>
            </Popover>
            <Popover
              content={
                <div className={styles['operate-select-label']}>
                  <div className="operate-select-search">
                    <SearchOutlined className="com-fz16" />
                    <Input
                      className="operate-search-input"
                      placeholder="搜索公司标签"
                      size="large"
                      variant="borderless"
                      value={searchCompanyValue}
                      onChange={handleChangeSearchCompanyValue}
                    />
                    <div className="create-company-btn" onClick={handleAddCompanyTag}>
                      <span>+</span>
                      <span className="m-l-xs">创建</span>
                    </div>
                  </div>
                  <div className="selected-line">
                    <div className="select-title">
                      <span>已选标签</span>
                      <span className="select-tips-gray">
                        {companyTags.length === 0 ? '至少添加一个标签' : `已选${companyTags.length}个标签`}
                      </span>
                    </div>
                    <div className={`${styles['select-item-wrapper']} selected-wrapper`}>
                      {companyTags?.map(item => (
                        <div className="select-item active-select-item" key={item}>
                          <span>{item}</span>
                          <Close className="delete-select" onClick={handleDeleteCompany.bind(this, item)} />
                        </div>
                      ))}
                    </div>
                  </div>
                  <div className="will-select-line">
                    <div className="select-title">标签</div>
                    <div className={`${styles['select-item-wrapper']} will-select-wrapper`}>
                      {companyList?.map(item => (
                        <div
                          className={`select-item ${companyTags.includes(item) ? 'active-select-item' : ''}`}
                          key={item}
                          onClick={handleAddTags.bind(this, item, 'company')}
                        >
                          <span>{item}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              }
              trigger="click"
            >
              <div className="operate-btn-item operate-add-label">
                {companyTags?.length ? (
                  <div className={`${styles['select-item-wrapper']} operate-add-select`}>
                    {companyTags?.map(item => (
                      <div className="select-item " key={item}>
                        <span>{item}</span>
                      </div>
                    ))}
                  </div>
                ) : (
                  <span className="add-company-label-text">添加公司标签</span>
                )}
              </div>
            </Popover>
          </div>
          <div className="operate-right-btn">
            <div className="operate-nomal-btn publish-btn" onClick={handleToClick.bind(this, 'modify')}>
              修改并发布
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

export default ColumnModify
