import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
import { Input, Spin, message, Button } from 'antd';
import { EyeOutlined } from '@ant-design/icons';
import AliOSS from 'ali-oss';
import dayjs from 'dayjs';

import { Boot } from '@wangeditor/editor';
import { useSelector } from 'react-redux';
import { SlateEditor, SlateNode, SlateElement, SlateText } from '@wangeditor/editor';
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import './node/index.less';
import timesave from '@/assets/images/timesave.png';

import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);

import { storageChange } from '@/utils/storage.js';

import linkCardModule from '@wangeditor/plugin-link-card';

import PaddingSpace from './customer/padding';

import ImageAutoConf from './customer/Image';
import GalleryAutoConf from './customer/Gallery';
import VideoAutoConf from './customer/Video';
import AudioAutoConf from './customer/Audio';
import ChapterTitleAutoConf from './customer/ChapterTitle';
import ChapterItemAutoConf from './customer/ChapterItem';
import PracticeAutoConf from './customer/Practice';
import FormulaAutoConf from './customer/Formula';
import TooltipAutoConf from './customer/Tooltip';

import ImageModal from './components/image';
import VideoModal from './components/video';
import GalleryModal from './components/gallery';
import AudioModal from './components/audio';
import ChapterTitleModal from './components/chapter-title';
import ChapterItemModal from './components/chapter-item';
import PracticeModal from './components/practice';
import FormulaModal from './components/formula';
import TooltipModal from './components/tooltip';

import chapterSectionModule from './node/chapterItem';
import chapterHeaderModule from './node/chapterTitle';
import chapterImageModule from './node/image';
import chapterVideoModule from './node/video';
import chapterAudioModule from './node/audio';
import chapterGalleryModule from './node/gallery';
import chapterPracticeModule from './node/practice';
import formulaModule from './node/formula';
import tooltipModule from './node/tooltip';

import PracticeSettingModal from './practice/index';

import $ from 'jquery';

import { getInfoByChapterId } from '@/pages/books/section/request';
import { getAliOSSSTSToken } from './utils/request';
import './index.less';

const menuArr1 = ['字体样式', '字号'];
const menuArr2 = ['图片', '画廊', '视频', '音频'];
const menuArr3 = ['代码块', '链接', '引用', '公式', '章头', '章节', '交互练习', '气泡'];
const colorList = ['#ab1941', '#2970f6', '#2ad882', '#eb3351'];
const bookBucketName = 'zxts-book-file';

const module = {
  menus: [
    ImageAutoConf,
    GalleryAutoConf,
    VideoAutoConf,
    AudioAutoConf,
    FormulaAutoConf,
    TooltipAutoConf,
    ChapterTitleAutoConf,
    ChapterItemAutoConf,
    PracticeAutoConf,
  ],
};
Boot.registerModule(module);
// 注册节头内容
Boot.registerModule(chapterSectionModule);
// 注册章头内容
Boot.registerModule(chapterHeaderModule);
// 注册图片内容
Boot.registerModule(chapterImageModule);
// 注册视频内容
Boot.registerModule(chapterVideoModule);
// 注册音频内容
Boot.registerModule(chapterAudioModule);
// 注册画廊
Boot.registerModule(chapterGalleryModule);
// 注册公式
Boot.registerModule(formulaModule);
// 注册练习
Boot.registerModule(chapterPracticeModule);
// 注册气泡
Boot.registerModule(tooltipModule);

Boot.registerModule(linkCardModule);

const tabsMenu = [
  { key: 'text', title: '文本设置' },
  { key: 'style', title: '样式模版' },
];

storageChange();

const WangEditorCustomer = forwardRef((props, ref) => {
  const { chapterId, bookId, contentId, html, setHtml, saveContent } = props;
  
  // 自动保存时间
  const { autosaveTime } = useSelector((state) => state.editor);

  const toolbarRef = useRef();
  const paddingSpaceRef = useRef();
  const [cId, setCId] = useState(contentId);

  const [ossClient, setOssClient] = useState(null); // oss 操作
  const [STSToken, setSTSToken] = useState(null); // oss 过期设置

  const [tabKey, setTabKey] = useState('text');
  const [loading, setLoading] = useState(true);
  // editor 实例
  const [editor, setEditor] = useState(null);
  const [editorNodes, setEditorNodes] = useState(null);
  const [content, setContent] = useState(html);
  const saveRef = useRef();

  // 工具栏配置
  const toolbarConfig = {
    toolbarKeys: [
      // '|',
      // 'redo',
      // 'undo',
      // 'emotion',
      // 'todo',
      // 'fullScreen',
      // '|',
      // 'headerSelect',
      // 'lineHeight',
      // '|',
      'fontFamily',
      // 'uploadImage',
      'fontSize',
      '|',
      'justifyLeft',
      'justifyRight',
      'justifyCenter',
      'justifyJustify',
      'divider',
      '|',
      'lineHeight',
      '|',
      'bold',
      'italic',
      'through',
      'underline',
      'sub',
      'sup',
      'color',
      'bgColor',
      'bulletedList',
      'numberedList',
      'indent',
      'delIndent',
      '|',
      // 'insertImage',
      // 'uploadImage',
      // 'insertVideo',
      // 'uploadVideo',
      'insertTable',
      '|',
      'codeBlock', // 代码块
      'insertLink', // 链接
      // 'insertFormula', // 公式
      'blockquote', // 引用
      // 'code',
      // 'clearStyle',
    ],
  };

  useImperativeHandle(ref, () => {
    return {
      editor,
    };
  });

  const imageRef = useRef();
  const galleryRef = useRef();
  const videoRef = useRef();
  const audioRef = useRef();
  const formulaRef = useRef();
  const tooltipRef = useRef();
  const chapterTitleRef = useRef();
  const chapterItemRef = useRef();
  const practiceRef = useRef();
  const practiceSettingRef = useRef();

  toolbarConfig.insertKeys = {
    index: 30,
    keys: [
      'ImageAuto',
      'GalleryAuto',
      'VideoAuto',
      'AudioAuto',
      'FormulaAuto',
      'ChapterTitle',
      'ChapterItem',
      'Practice',
      'TooltipAuto',
    ],
  };
  // 编辑器配置
  const editorConfig = {
    placeholder: '请输入内容...',
    // 选中公式时的悬浮菜单
    hoverbarKeys: {
      //   formula: {
      //     menuKeys: ['editFormula'], // “编辑公式”菜单
      //   },
      // 在编辑器中，选中链接文本时，要弹出的菜单
      link: {
        menuKeys: [
          'editLink',
          'unLink',
          'viewLink', // 默认的配置可以通过 `editor.getConfig().hoverbarKeys.link` 获取
          'convertToLinkCard', // 增加 '转为链接卡片'菜单
        ],
      },
      MENU_CONF: {
        // '转为链接卡片'菜单的配置
        convertToLinkCard: {
          // 自定义获取 link-card 信息，可选
          // 返回 { title, iconImgSrc }
          async getLinkCardInfo(linkText, linkUrl) {
            // 1. 可通过 iframe 加载网页，然后获取网页 title 和其中的图片
            // 2. 服务端获取（有些网页会设置 `X-Frame-Options` ，无法通过 iframe 加载）
            // // 模拟异步返回
            // return new Promise(resolve => {
            //   setTimeout(() => {
            //     const info = { title: linkText, iconImgSrc: '' }
            //     resolve(info)
            //   }, 100)
            // })
          },
        },

        // 其他...
      },
    },
  };
  // 编辑器按钮重排
  const toolSetttingReplace = () => {
    setTimeout(() => {
      const toolbarElement = toolbarRef.current && toolbarRef.current.children[1].children[0];
      const allChildren = toolbarElement.children;

      const oH6_1 = document.createElement('h4');
      oH6_1.setAttribute('class', 'w-auto type-heading');
      oH6_1.innerHTML = '常用格式';
      toolbarElement.insertBefore(oH6_1, allChildren[0]);

      const oHDiv_3 = document.createElement('div');
      oHDiv_3.setAttribute('class', 'custom-bar-box two');
      toolbarElement.insertBefore(oHDiv_3, allChildren[1]);
      $(allChildren[1]).append($(allChildren[2]).detach());
      $(allChildren[1]).append($(allChildren[2]).detach());

      const oH6_2 = document.createElement('h4');
      oH6_2.setAttribute('class', 'w-auto type-heading');
      oH6_2.innerHTML = '媒体资源';
      toolbarElement.insertBefore(oH6_2, allChildren[22]);
      const oHDiv_1 = document.createElement('div');
      oHDiv_1.setAttribute('class', 'custom-bar-box');
      toolbarElement.insertBefore(oHDiv_1, allChildren[23]);

      const itemBox = '<div class="w-e-bar-boxitem"></div>';
      $(itemBox).insertBefore($(allChildren[4]));
      const itemBox2 = '<div class="w-e-bar-boxitem you"></div>';
      $(itemBox2).insertBefore($(allChildren[10]));

      $(allChildren[4]).append($(allChildren[3]).detach());
      $(allChildren[3]).append($(allChildren[5]).detach());
      $(allChildren[3]).append($(allChildren[5]).detach());
      $(allChildren[3]).append($(allChildren[5]).detach());
      $(allChildren[3]).append($(allChildren[4]).detach());

      const oHDivInput_1 = document.createElement('div');
      oHDivInput_1.setAttribute('class', 'custom-bar-box input');
      oHDivInput_1.setAttribute('id', 'custom-bar-box-input');
      toolbarElement.insertBefore(oHDivInput_1, allChildren[4]);

      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());
      $(allChildren[6]).append($(allChildren[7]).detach());

      $(allChildren[9]).append($(allChildren[15]).detach());
      $(allChildren[9]).append($(allChildren[15]).detach());
      $(allChildren[9]).append($(allChildren[15]).detach());
      $(allChildren[9]).append($(allChildren[15]).detach());
      $(allChildren[9]).append($(allChildren[10]).detach());

      const oH6_3 = document.createElement('h4');
      oH6_3.setAttribute('class', 'w-auto type-heading');
      oH6_3.innerHTML = '高级模块';
      toolbarElement.insertBefore(oH6_3, allChildren[11]);
      const oHDiv_2 = document.createElement('div');
      oHDiv_2.setAttribute('class', 'custom-bar-box');
      toolbarElement.insertBefore(oHDiv_2, allChildren[12]);

      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());
      $(allChildren[12]).append($(allChildren[13]).detach());

      $('.custom-bar-box').each((index, item) => {
        $(item)
          .find('.w-e-bar-item')
          .each((cIndex, cItem) => {
            if (index === 2 && cIndex === 4) {
              $(cItem).hide();
            } else {
              const oP = document.createElement('p');
              if (index === 0) {
                $(oP).insertBefore($(cItem).find('button'));
                oP.innerHTML = menuArr1[cIndex];
              } else if (index === 2) {
                oP.innerHTML = menuArr2[cIndex];
                $(cItem).append(oP);
              } else if (index === 3) {
                oP.innerHTML = menuArr3[cIndex];
                $(cItem).append(oP);
              }
            }
          });
      });
      setLoading(false);
    }, 200);
  };
  editorConfig.onCreated = (editor) => {
    setLoading(true);
    toolSetttingReplace();
  };
  editorConfig.onFocus = (editor) => {
    clearTimeout(saveRef.current);
  };
  editorConfig.onBlur = (editor) => {
    // 失焦保存
    // setHtml(editor.getHtml());
    saveContent();
  };
  editorConfig.onChange = (editor) => {
    // setHtml(editor.getHtml());
    // clearTimeout(saveRef.current);
    // saveRef.current = setTimeout(() => {
    //   saveContent();
    // }, 800);
  };

  // 及时销毁 editor ，重要！
  useEffect(() => {
    if (editor) {
      // 图片上传
      editor.on('ImageMenuClick', () => {
        console.log('ImageMenuClick', '----');
        imageRef.current.setVisible(true);
      });
      // 画廊上传
      editor.on('GalleryMenuClick', () => {
        console.log('GalleryMenuClick', '----');
        galleryRef.current.setVisible(true);
      });
      // 视频上传
      editor.on('VideoMenuClick', () => {
        console.log('VideoMenuClick', '----');
        videoRef.current.setVisible(true);
      });
      // 音频上传
      editor.on('AudioMenuClick', () => {
        console.log('AudioMenuClick', '----');
        audioRef.current.setVisible(true);
      });
      // 章节
      editor.on('ChapterItemMenuClick', () => {
        console.log('ChapterItemMenuClick', '----');
        chapterItemRef.current.setVisible(true);
      });
      // 章头
      editor.on('ChapterTitleClick', () => {
        console.log('ChapterTitleClick', '----');
        chapterTitleRef.current.setVisible(true);
      });
      // 交互练习
      editor.on('PracticeMenuClick', () => {
        console.log('PracticeMenuClick', '----');
        practiceRef.current.setVisible(true);
      });
      // 公式
      editor.on('FormulaMenuClick', () => {
        console.log('FormulaMenuClick', '----');
        formulaRef.current.setVisible(true);
      });
      // 气泡
      editor.on('TooltipMenuClick', () => {
        if (editor.getSelectionText()) {
          const textSelection = editor.selection;
          if (textSelection.anchor.path[0] === textSelection.focus.path[0]) {
            tooltipRef.current.setVisible(true);
          } else {
            message.error('气泡操作不能跨段落进行！');
          }
        } else {
          message.error('气泡操作需要选中内容！');
        }
      });
    }
    return () => {
      if (editor === null) return;
      editor.destroy();
      setEditor(null);
    };
  }, [editor]);

  useEffect(() => {
    if (editor && html) {
      setContent(html);
    }
  }, [html, editor]);

  const tabKeyChange = (key) => {
    if (key === 'text') {
      toolSetttingReplace();
    }
    setTabKey(key);
  };

  const getStsAuthToken = async () => {
    const data = await getAliOSSSTSToken();
    if (data) {
      window.sessionStorage.setItem('sts', JSON.stringify(data));
      setSTSToken(data);
      const ossClientTemp = await new AliOSS({
        accessKeyId: data.AccessKeyId,
        accessKeySecret: data.AccessKeySecret,
        stsToken: data.SecurityToken,
        endpoint: 'zijingebook.com',
        // region: 'cn-beijing',
        // endpoint: data.endpoint,
        bucket: bookBucketName,
        timeout: 180000,
        refreshSTSToken: async () => {
          const info = await getAliOSSSTSToken();
          return {
            AccessKeyId: info.AccessKeyId,
            AccessKeySecret: info.AccessKeySecret,
            SecurityToken: info.SecurityToken,
          };
        },
        refreshSTSTokenInterval: 14 * 60 * 1000,
      });
      setOssClient(ossClientTemp);
    }
  };

  useEffect(() => {
    (async () => {
      const tempStsToken = window.sessionStorage ? window.sessionStorage.getItem('sts') : '';
      try {
        const stsToken = JSON.parse(tempStsToken);
        // 15 分钟过期
        if (dayjs(stsToken.Expiration).valueOf() - dayjs().valueOf() >= 14 * 60 * 1000) {
          getStsAuthToken();
        } else {
          const ossClientTemp = await new AliOSS({
            accessKeyId: data.AccessKeyId,
            accessKeySecret: data.AccessKeySecret,
            stsToken: data.SecurityToken,
            // endpoint: data.endpoint,
            // region: 'cn-beijing',
            endpoint: 'zijingebook.com',
            bucket: bookBucketName,
            timeout: 180000,
            refreshSTSToken: async () => {
              const info = await getAliOSSSTSToken();
              return {
                AccessKeyId: info.AccessKeyId,
                AccessKeySecret: info.AccessKeySecret,
                SecurityToken: info.SecurityToken,
              };
            },
            refreshSTSTokenInterval: 14 * 60 * 1000,
          });
          setOssClient(ossClientTemp);
          setSTSToken(stsToken);
        }
      } catch (e) {
        getStsAuthToken();
      }
    })();
  }, []);

  const setColor = (type) => {
    $(`#chapter-item-header`).css({ color: '#fff', backgroundColor: colorList[type - 1] });
    $(`#chapter-item-section`).css({ color: '#fff', backgroundColor: colorList[type - 1] });
  };

  return (
    <div className='wangeditor-customer-container'>
      <div
        style={{ height: 'calc(100vh - 250px)', overflowY: 'hidden' }}
        className='editor-content-container'
      >
        <div className='title-head'>
          <div className='right'>
            <div className='save-time time-on'>
              <Button
                danger
                type='link'
                className='timepsave'
                onClick={saveContent}
                icon={<img src={timesave} />}
              >
                自动保存
              </Button>
              <span className='time'>{autosaveTime > 0 ? dayjs(autosaveTime).fromNow() : ''}</span>
            </div>
            <div className='save-time'>
              <Button icon={<EyeOutlined />} className='view'>
                预览
              </Button>
              <span className='time'>&nbsp;</span>
            </div>
          </div>
        </div>
        <Spin spinning={loading} className='editor-content-container-loading'>
          <Editor
            defaultConfig={editorConfig}
            value={content}
            onCreated={setEditor}
            // onChange={(editor) => setHtml(editor.getHtml())}
            mode='default'
            style={{ height: 'calc(100vh - 250px)', overflowY: 'hidden' }}
          />
        </Spin>
      </div>

      {/* <CustomerMenu editor={editor} /> */}

      <div className='menu-tabs-key'>
        <div className='tabs'>
          {tabsMenu &&
            tabsMenu.length &&
            tabsMenu.map((item) => {
              return (
                <div
                  className={`tabs-item ${item.key === tabKey ? 'active' : ''}`}
                  key={item.key}
                  onClick={() => tabKeyChange(item.key)}
                >
                  {item.title}
                  <span></span>
                </div>
              );
            })}
        </div>
        <div className='menu-tabs-content'>
          {tabKey === 'text' && (
            <div ref={toolbarRef} className='toolbox-parent'>
              <PaddingSpace ref={paddingSpaceRef} editor={editor} editorNodes={editorNodes} />
              <Toolbar
                editor={editor}
                defaultConfig={toolbarConfig}
                mode='default'
                style={{ borderBottom: '1px solid #ccc' }}
                className='editor-toolbar-container'
              ></Toolbar>
            </div>
          )}
          {tabKey === 'style' && (
            <div className='styletem'>
              <p>样式模板</p>
              <ul>
                <li>
                  <div className='left'>
                    <span className='color color1'></span>
                    <b className='type'>默认</b>
                  </div>
                  <Button type='link' className='use' onClick={() => setColor(1)}>
                    使用
                  </Button>
                </li>
                <li>
                  <div className='left'>
                    <span className='color color2'></span>
                    <b className='type'>蓝色</b>
                  </div>
                  <Button type='link' className='use' onClick={() => setColor(2)}>
                    使用
                  </Button>
                </li>
                <li>
                  <div className='left'>
                    <span className='color color3'></span>
                    <b className='type'>绿色</b>
                  </div>
                  <Button type='link' className='use' onClick={() => setColor(3)}>
                    使用
                  </Button>
                </li>
                <li>
                  <div className='left'>
                    <span className='color color4'></span>
                    <b className='type'>红色</b>
                  </div>
                  <Button type='link' className='use' onClick={() => setColor(4)}>
                    使用
                  </Button>
                </li>
              </ul>
            </div>
          )}
        </div>
      </div>

      <ImageModal ref={imageRef} editor={editor} ossClient={ossClient} STSToken={STSToken} />
      <VideoModal ref={videoRef} editor={editor} ossClient={ossClient} STSToken={STSToken} />
      <GalleryModal ref={galleryRef} editor={editor} ossClient={ossClient} STSToken={STSToken} />
      <AudioModal ref={audioRef} editor={editor} ossClient={ossClient} STSToken={STSToken} />
      <ChapterTitleModal
        ref={chapterTitleRef}
        editor={editor}
        ossClient={ossClient}
        STSToken={STSToken}
      />
      <ChapterItemModal
        ref={chapterItemRef}
        editor={editor}
        ossClient={ossClient}
        STSToken={STSToken}
      />
      <PracticeModal
        ref={practiceRef}
        chapterId={chapterId}
        bookId={bookId}
        editor={editor}
        ossClient={ossClient}
        STSToken={STSToken}
      />
      <FormulaModal ref={formulaRef} editor={editor} ossClient={ossClient} STSToken={STSToken} />
      <TooltipModal
        ref={tooltipRef}
        editor={editor}
        chapterId={chapterId}
        bookId={bookId}
        ossClient={ossClient}
        STSToken={STSToken}
      />

      <PracticeSettingModal
        ref={practiceSettingRef}
        nodes={practiceRef.current && practiceRef.current.nodes ? practiceRef.current.nodes : null}
        chapterId={chapterId}
        bookId={bookId}
        editor={editor}
      />
    </div>
  );
});

export default WangEditorCustomer;
