import { Image, message, Spin } from 'antd';
import classNames from 'classnames';
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
// import { request } from '@wisdom-utils/utils';
import request from 'umi-request';
import WangEditor from './wangEditor.js';
// import { API } from '@/api/service/workflow';
const API = {};
// import { appWork, projectManageService } from '@/api';
import FileListItem from './fileListItem';
import styles from './index.less';
let editor = null;
let range;
const selection = window.getSelection();
let startOffset;
let tempList = [];
let allPeople = []; // 全部人员
let selectPersonIndex;
let selectPerson = [];
const RichText = forwardRef((props, ref) => {
  const [loading, setLoading] = useState(false);
  const [zIndex, setZIndex] = useState(500);
  // const [inputValue, setInputValue] = useState('');
  const [selectIndex, setSelectIndex] = useState(null);
  const [selectList, setSelectList] = useState([]);
  const [selectSearchList, setSelectSearchList] = useState([]);
  const [fileList, setFileList] = useState([]);
  const [imgVisible, setImgVisible] = useState(false);
  const [imgPreviewSrc, setImgPreviewSrc] = useState('');
  const richTextRef = useRef();
  const selectBoxRef = useRef();
  const fileInputRef = useRef();
  const getData = async () => {
    // const { data } = await projectManageService.GetWorkHourUserList({ projectId: props.projectId });
    // setSelectList(data);
  };
  // 获取全部人员信息
  const getAllPeople = async () => {
    // const res = await appWork.GetAllPersonnels();
    // allPeople = res?.data?.data || [];
  };
  // 图片上传
  const uploadImg = (file) => {
    const formData = new FormData();
    formData.append('file', file);
    setLoading(true);
    request({
      url: API.POST_UPLOADERFILES,
      method: 'POST',
      data: formData,
    })
      .then((res) => {
        if (!res.data) return;
        const img = res.data.replace(/[\\ \/=]/g, '/');
        const imgHtml = `
                    <img contenteditable="false" style="display: block;" width="50%" src="${API.GET_DOWNLOADFILES}?filePath=${img}" >
                `;
        editor.cmd.do('insertHTML', imgHtml);
        setLoading(false);
      })
      .catch((err) => {
        setLoading(false);
      });
  };
  const init = () => {
    const { BtnMenu } = WangEditor;
    editor = new WangEditor('#RichTextToolbar', '#RichTextContainer');
    // 自定义菜单
    const menuKey = 'fileMenuKey';
    if (props.onChangeFile) {
      class InsertABCMenu extends BtnMenu {
        constructor(editor) {
          const $elem = WangEditor.$(
            `<div class="w-e-menu">
                            <i class="w-e-icon-link">
                            </i>
                        </div>`,
          );
          super($elem, editor);
        }

        // 菜单点击事件
        clickHandler() {
          // 触发选择文件
          fileInputRef.current.click();
        }

        // 菜单激活状态
        tryChangeActive() {
          // this.active(); // 菜单激活
        }
      }
      editor.menus.extend(menuKey, InsertABCMenu);
    }

    editor.config = Object.assign(
      {},
      editor.config,
      {
        placeholder: props.placeholder ?? '',
        focus: false,
        pasteFilterStyle: true, // 忽略粘贴样式
        pasteIgnoreImg: true, // 忽略粘贴的图片
        styleWithCSS: false,
        zIndex: 500,
        menus: [
          'bold',
          'fontSize',
          'italic',
          'underline',
          'strikeThrough',
          'foreColor',
          'backColor',
          'list',
          'justify',
          'table',
          menuKey,
          'undo',
          'redo',
          'image',
        ],
      },
      props.config || {},
    );

    setZIndex(Number(editor.config.zIndex));
    // 内容变更
    editor.config.onchange = (newHtml, e) => {
      props.onChange(newHtml);
    };
    // 粘贴前置处理
    editor.config.pasteTextHandle = (pasteStr) => pasteStr;
    editor.config.onblur = (newHtml) => {
      selectBoxRef.current.style.display = 'none';
    };
    // 点击事件
    editor.txt.eventHooks.clickEvents.push((e) => {
      // 图片预览
      // 已弃用
      if (e.target.getAttribute('type') === 'preview') {
        const imgSrc = e.target?.parentNode?.parentNode
          ?.getElementsByTagName('img')?.[0]
          ?.getAttribute('src');
        setImgPreviewSrc(imgSrc);
        setImgVisible(true);
      }
      // 关闭选人的下拉框
      selectBoxRef.current.style.display = 'none';
    });

    editor.txt.eventHooks.onPreviewEvents.push((link) => {
      // 图片预览
      if (link) {
        setImgPreviewSrc(link);
        setImgVisible(true);
      }
    });

    editor.txt.eventHooks.imgClickEvents.push((e) => {});
    // 粘贴图片上传
    editor.txt.eventHooks.pasteEvents.push((e) => {
      const file = e?.clipboardData?.items[0]?.getAsFile() || null;
      if (!file) return;
      uploadImg(file);
    });

    editor.create();
    editor.txt.html(props.content || '');
    richTextRef.current.onkeydown = keyDownEvent;
    richTextRef.current.addEventListener('input', (e) => {
      if (range) {
        // 判断节点是否在选区及光标是否在@后面
        const type = selection.containsNode(selection.getRangeAt(0).commonAncestorContainer, false);
        if (!type || startOffset > selection.focusOffset) {
          closeList();
          return;
        }
        range.setEnd(selection.getRangeAt(0).commonAncestorContainer, selection.focusOffset);
        // console.log('🚀 ~ range', range.toString(), tempList, selectList);
        const str = range.toString() || '';
        moveListBox();
        handleChange(str, tempList);
      }
      if (e.data !== '@') return;
      if (range) {
        closeList();
      }
      range = document.createRange();
      startOffset = selection.focusOffset;
      range.setStart(selection.getRangeAt(0).commonAncestorContainer, selection.focusOffset);
      selection.addRange(range);

      moveListBox();
      // 清空搜索
      handleChange('', tempList);
    });
  };
  // 跟据光标位置移动下拉框
  const moveListBox = () => {
    // 获取光标位置
    const cursor = window?.getSelection()?.getRangeAt(0)?.getBoundingClientRect() || null;
    const containerRect = document.querySelector('#RichText').getBoundingClientRect();
    selectBoxRef.current.style.display = 'block';
    selectBoxRef.current.style.left = `${parseInt(cursor.x - containerRect.x, 10) + 5}px`;
    selectBoxRef.current.style.top = `${parseInt(cursor.y - containerRect.y, 10) + 25}px`;
  };
  // 键盘事件
  const keyDownEvent = (evet) => {
    // 上下方向键
    if (evet.key === 'ArrowDown' || evet.key === 'ArrowUp') {
      evet.preventDefault();
      if (selectBoxRef.current?.style?.display === 'block') {
        const max = selectBoxRef.current.querySelectorAll('.selectItem')?.length || 1000;
        let val = selectPersonIndex;
        if (evet.key === 'ArrowDown') {
          if (!val && val != 0) {
            val = 0;
          } else {
            val += 1;
          }
        }
        if (evet.key === 'ArrowUp') val -= 1;
        if (isNaN(val) || !val || val < 0) val = 0;
        if (val > max - 1) val = max - 1;
        selectPersonIndex = val;
        setSelectIndex(selectPersonIndex);
      }
    }
    if (evet.key === 'Enter') {
      // 解决无法回车换行的bug
      if (selectBoxRef.current.style.display === 'block' && selectSearchList.length) {
        evet.preventDefault();
        if (selectPerson[selectPersonIndex]) {
          onSelect(selectPerson[selectPersonIndex]);
        }
        return false;
      }
    }
  };

  useEffect(() => {
    richTextRef.current && richTextRef.current.removeEventListener('input', (e) => {});
    init();
    getAllPeople();
    return () => {
      richTextRef.current && richTextRef.current.removeEventListener('input', (e) => {});

      editor && editor.destroy();
      editor = null;
    };
  }, []);
  useEffect(() => {
    selectPersonIndex = null;
    setSelectIndex(null);
    selectPerson = selectSearchList || [];
  }, [selectSearchList]);
  useEffect(() => {
    if (props.projectId) getData();
  }, [props.projectId]);
  useEffect(() => {
    const keys = [];
    const arr = [];
    if (props.personList) {
      props.personList.forEach((i) => {
        i.userId = Number(i.userId);
        if (!keys.includes(i.userId)) {
          keys.push(i.userId);
          arr.push(i);
        }
      });
    }
    if (selectList) {
      selectList.forEach((i) => {
        i.userId = Number(i.userId);
        if (!keys.includes(i.userId)) {
          arr.push(i);
          keys.push(i.userId);
        }
      });
    }

    tempList = arr;
    setSelectSearchList(arr);
  }, [selectList, props.personList]);
  // useEffect(() => {
  //     if (!props.projectId) {
  //         setSelectList(props.personList || []);
  //     }
  // }, [props.personList]);
  useEffect(() => {
    setFileList(props.fileList);
  }, [props.fileList]);
  const getHtml = (val) => editor.txt.html();
  // 获取文本,不含标签
  const getText = (val) => editor.txt.text();
  // 清除
  const onClear = () => {
    editor.txt.clear();
  };
  // 设置内容
  const setHtml = (val) => {
    editor.txt.html(val || '');
  };
  // 关闭人员下拉选框
  const closeList = () => {
    selectPersonIndex = null;
    setSelectIndex(null);
    selectBoxRef.current.style.display = 'none';
    if (range) {
      selection.removeRange(range);
      range = null;
    }
  };
  // @某人
  const onSelect = (item) => {
    if (range) {
      range.deleteContents();
      // 删除前一个@符号
      editor.cmd.do('delete');
      const _html = `<span><span data-userId="${item.userId}" data-type="person" >@${item.userName}</span><span>&nbsp;</span></span>`;
      editor.cmd.do('insertElem', _html);
      closeList();
      selection.collapseToEnd();
    }
  };
  // const onChange = val => {
  //     setInputValue(val.currentTarget.value);
  //     handleChange(val.currentTarget.value);
  // };
  let timer = null;
  const filterList = (val, list) => {
    if (!val) {
      if (list.length === 0) {
        selectBoxRef.current.style.display = 'none';
      }
      setSelectSearchList(list);
    } else {
      const arr = getArrayByName(val, allPeople);
      if (arr.length === 0) {
        selectBoxRef.current.style.display = 'none';
      }
      setSelectSearchList(arr);
    }
  };
  const handleChange = (val, list) => {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      timer = null;
      filterList(val, list);
    }, 200);
    // filterList(val, list);
  };
  /**
   * 根据字符串模糊搜索返回符合条件的数据
   * name   搜索字符串
   * array  检索json数组
   */
  const getArrayByName = (name, array) => {
    const result = [];
    array.forEach((i) => {
      if (i.name.indexOf(name) != -1) result.push({ userName: i.name, userId: i.id, port: i.port });
    });
    return result;
  };
  const addFile = (e) => {
    if (e.target) {
      const file = e.target.files[0];
      const formData = new FormData();
      formData.append('file', file);
      setLoading(true);
      request({
        url: API.POST_UPLOADERFILES,
        method: 'POST',
        data: formData,
      })
        .then((res) => {
          if (res.data) {
            const arr = [...fileList];
            const url = res.data.replace(/[\\ \/=]/g, '/');
            arr.unshift({
              name: file.name,
              type: file.type ? file.type.toLowerCase() : '',
              size: file.size,
              path: `${API.GET_DOWNLOADFILES}?filePath=${url}`,
            });
            // setFileList(arr);
            props.onChangeFile(arr);
            setLoading(false);
          } else {
            message.error(res.msg);
            setLoading(false);
          }
        })
        .catch((err) => {
          setLoading(false);
        });
    }
  };
  const onDelFile = (item) => {
    const arr = [];
    fileList.forEach((i) => {
      if (i.path !== item.path) {
        arr.push(i);
      }
    });
    // setFileList(arr);
    props.onChangeFile(arr);
  };
  useImperativeHandle(ref, () => ({
    setHtml,
    onClear,
    getHtml,
    getText,
  }));
  return (
    <div className={styles.RichText} id="RichText">
      {loading ? (
        <div className={styles.loadingWrap} style={{ zIndex: zIndex + 20 }}>
          <Spin spinning={loading} />
        </div>
      ) : null}
      <div id="RichTextToolbar" className={styles.RichTextToolbar} />
      <div ref={richTextRef} id="RichTextContainer" className={styles.RichTextContainer} />
      <div className={styles.RichTextFileList}>
        <FileListItem
          list={fileList}
          onDel={(val) => {
            onDelFile(val);
          }}
          type="edit"
          onPreview={(val) => {
            if (!val) return;
            setImgPreviewSrc(val.path);
            setImgVisible(true);
          }}
        />
      </div>
      <div
        ref={selectBoxRef}
        className={styles.selectBox}
        style={{ maxWidth: '300px', minWidth: '150px', zIndex: zIndex + 10 }}
      >
        {selectSearchList.length ? (
          <div className={styles.selectList}>
            {selectSearchList.map((item, index) => (
              <div
                key={item.userId}
                onClick={() => {
                  onSelect(item);
                }}
                className={classNames(
                  'selectItem',
                  styles.selectItem,
                  selectIndex === index ? styles.selectActiveItem : '',
                )}
              >
                {item.userName}
              </div>
            ))}
          </div>
        ) : null}
      </div>
      <input
        style={{ display: 'none' }}
        type="file"
        ref={fileInputRef}
        onChange={(e) => {
          addFile(e);
        }}
        name="file"
      />
      <Image
        width={200}
        style={{ display: 'none' }}
        src={imgPreviewSrc}
        preview={{
          visible: imgVisible,
          src: imgPreviewSrc,
          onVisibleChange: (value) => {
            setImgVisible(value);
            if (!value) setImgPreviewSrc('');
          },
        }}
      />
    </div>
  );
});
export default RichText;