import 'quill-mention/dist/quill.mention.css';
import 'react-quill/dist/quill.snow.css';
import 'react-quill-emoji/dist/quill-emoji.css';

import ImageUploader from '@writergate/quill-image-uploader-nextjs';
import { Image, Modal, Space } from 'antd';
import _ from 'lodash';
import React, { useRef, useState } from 'react';
import ReactQuill, { Quill } from 'react-quill';

import { postMessage } from '../services/chat';
import styles from '../style.module.css';
import { qiniuUploadMD5 } from '../utils/qiniu';
import { fileSize, qiniuUrl } from '../utils/utils';
import Button from './Button';
import IconFont from './IconFonts';
import Qiniu from './ReactQiniu';

type PropType = {
  roomId: string;
  username: string;
  members: any[];
  qiniu_url: string;
};

let record: string[] = [];
Quill.register('modules/imageUploader', ImageUploader);

const ChatEditor: React.FC<PropType> = ({ roomId, username, members, qiniu_url }) => {
  let message: Chat.Message[] = [];
  const [previewModalVisible, setPreviewModalVisible] = useState(false);
  const [pastedModalVisible, setPastedModalVisible] = useState(false);
  const [pastedFiles, setPastedFiles] = useState<any[]>([]);
  const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
  const [filePreview, setFilePreview] = useState<any[]>([]);
  const quillRef = useRef<any>();
  const quill = quillRef?.current;

  const userList = members.map((v) => ({
    user_id: v.user_id,
    avatar: v.avatar,
    value: v.user_name,
  }));

  const sendMessage = () => {
    const scrollDiv = document.getElementById('chatlist');
    const blocks = quill.editor.editor.delta;
    if (pastedFiles.length > 0) {
      message = pastedFiles.map((f: any) => ({
        type: 'attachment',
        sub_type: 'image',
        text: '',
        source_url: f.source_url,
      }));
    } else if (uploadedFiles.length > 0) {
      message = uploadedFiles.map((f: string) => ({
        type: 'attachment',
        sub_type: 'image',
        text: '',
        source_url: f,
      }));
    } else {
      message = blocks.map((v) => {
        if (v.insert.mention) {
          return {
            type: 'mention',
            text: `@${v.insert.mention.value}`,
            user_id: Number(userList.filter((u) => u.value === v.insert.mention.value).map((s) => s.user_id)),
          };
        }
        if (v.attributes && !v.attributes.imageBlot) {
          return {
            type: 'task_mention',
            text: v.insert,
            card_id: v.attributes.link,
          };
        }
        if (v.insert.emoji) {
          return {
            type: 'emoicon',
            text: `:${v.insert.emoji}:`,
          };
        }
        return { type: 'text', text: v.insert };
      });
    }
    if (
      uploadedFiles.length > 0 ||
      pastedFiles.length > 0 ||
      message.filter((m) => m.text.replace(/[\r\n]/g, '') !== '').length > 0
    ) {
      postMessage(username, roomId, message, [
        ...new Set(message.filter((v) => v.type === 'mention').map((v) => v.user_id!)),
      ]).then(() => {
        if (scrollDiv) {
          scrollDiv.scrollIntoView({ block: 'end' });
        }
        setUploadedFiles([]);
        setPastedFiles([]);
        record = [];
        quill.editor.focus();
        quill.editor.setSelection(quill.editor.getLength(), 0);
      });
    }
  };

  const onDrop = (droppedFiles: any[]) => {
    setFilePreview(droppedFiles);
    setPreviewModalVisible(true);
    Promise.all(droppedFiles.map((v) => v.uploadPromise))
      .then((values) => setUploadedFiles(values.map((s) => qiniuUrl(s.body.key, qiniu_url))))
      .catch((e) => console.error(e));
  };

  const EditorToolbar = () => (
    <Space id="toolbar" className="flex items-center">
      <Qiniu onDrop={onDrop} prefix="chat-" accept=".png,.jpg,.jpeg">
        <IconFont icon="icon-attachment" className="cursor-pointer text-base font-bold hover:text-blue-400" />
      </Qiniu>
    </Space>
  );

  const modules = {
    toolbar: {
      container: '#toolbar',
    },
    // 'emoji-toolbar': true,
    keyboard: {
      bindings: {
        tab: {
          key: 13,
          handler() {
            sendMessage();
            quill.editor.setContents([{ insert: '\n' }]);
          },
        },
      },
    },
    imageUploader: {
      upload: (fileToUpload) => {
        const blocks = quill.editor.editor.delta;
        return new Promise(() => {
          qiniuUploadMD5(
            fileToUpload,
            undefined,
            [],
            (res) => {
              record = record.concat(
                Object.assign(fileToUpload, {
                  source_url: qiniuUrl(res.key, qiniu_url),
                })
              );
              setPastedFiles(record);
              setPastedModalVisible(true);
              quill.editor.setContents(blocks.filter((v) => v.insert.image === undefined));
            },
            () => {}
          );
        });
      },
    },
  };

  return (
    <>
      <ReactQuill className={styles.qlContainer} modules={modules} ref={quillRef} />
      <div className="flex items-center justify-between">
        <div className="flex items-center">
          <EditorToolbar />
        </div>
        <Button
          type="primary"
          className="rounded-lg border-2"
          onClick={_.debounce(() => {
            sendMessage();
            quill.editor.setContents([{ insert: '\n' }]);
          }, 200)}
        >
          发送
        </Button>
      </div>
      <Modal
        title="发送图片"
        width={400}
        visible={previewModalVisible}
        onCancel={() => {
          setPreviewModalVisible(false);
          setUploadedFiles([]);
          quill.editor.setSelection(quill.editor.getLength(), 0);
        }}
        onOk={() => {
          sendMessage();
          setPreviewModalVisible(false);
          setFilePreview([]);
        }}
        okText="发送"
      >
        {filePreview.length > 1
          ? filePreview.map((v: any) => (
              <div className="my-2 flex items-center justify-between" key={v.preview}>
                <div className="flex items-center">
                  <Image src={v.preview} className="w-12" />
                  <div className="flex flex-col">
                    <div className="ml-2">{v.name}</div>
                    <div className="ml-2 text-xs text-gray-400">{fileSize(v.size)}</div>
                  </div>
                </div>
                <div className="flex items-center">
                  <IconFont
                    icon="icon-delete"
                    className="cursor-pointer text-xl hover:text-red-400"
                    onClick={() => {
                      setFilePreview(filePreview.filter((a) => a !== v));
                      Promise.all(filePreview.filter((a) => a !== v).map((m) => m.uploadPromise))
                        .then((values) => setUploadedFiles(values.map((s) => qiniuUrl(s.body.key, qiniu_url))))
                        .catch((e) => console.error(e));
                    }}
                  />
                </div>
              </div>
            ))
          : filePreview.map((v) => (
              <div className="text-center" key={v.preview}>
                <Image src={v.preview} />
                <div>{v.name}</div>
              </div>
            ))}
      </Modal>
      <Modal
        title="发送图片"
        width={400}
        visible={pastedModalVisible}
        onCancel={() => {
          setPastedModalVisible(false);
          setPastedFiles([]);
          record = [];
          quill.editor.setSelection(quill.editor.getLength(), 0);
        }}
        onOk={() => {
          sendMessage();
          setPastedModalVisible(false);
        }}
        okText="发送"
      >
        {pastedFiles.length > 1
          ? pastedFiles.map((v: any) => (
              <div className="my-2 flex items-center justify-between" key={v.preview}>
                <div className="flex items-center">
                  <Image src={v.source_url} className="w-12" />
                  <div className="flex flex-col">
                    <div className="ml-2">{v.name}</div>
                    <div className="ml-2 text-xs text-gray-400">{fileSize(v.size)}</div>
                  </div>
                </div>
                <div className="flex items-center">
                  <IconFont
                    icon="icon-delete"
                    className="cursor-pointer text-xl hover:text-red-400"
                    onClick={() => {
                      setPastedFiles(pastedFiles.filter((a) => a !== v));
                      Promise.all(filePreview.filter((a) => a !== v).map((m) => m.uploadPromise))
                        .then((values) => setUploadedFiles(values.map((s) => qiniuUrl(s.body.key, qiniu_url))))
                        .catch((e) => console.error(e));
                    }}
                  />
                </div>
              </div>
            ))
          : pastedFiles.map((v) => (
              <div className="text-center" key={v.source_url}>
                <Image src={v.source_url} />
                <div>{v.name}</div>
              </div>
            ))}
      </Modal>
    </>
  );
};

export default ChatEditor;
