import moment from "moment";
import xeUtils from 'xe-utils';
import indexUtil from "../../utils/index.js"
import {treeScolly} from '../../utils/global.js';
import settingConfig from "@/settings";

let tmixins = {};
tmixins = {
  data() {
    return {
      isFullscreen: false,
      dialogTableVisible: false,
      userInfo: null,
      content: null,
      userContentMap: {},
      showUserDialog: false,
      talkUserId: null,
      inited: false,
      timer0: null,
      timer: null,
      talkUsers: [],
      keyword: null,
      unread: false,
      isExitsRead: false,
      btnDisabled: false,
      isCanUserTalk: false,
      roleCodes: [],

      files: [],
      tempIndex: 1,
      showPrivateUploadBtn: false,
      showPrivateProfileDialog: false,
      editFileIndex: -1,
      showFileNameDialog: false,
      editFileName: null,
      editFileSuffix: null,

      showHistoryDialog: false,
      historyType: null,
      topHistoryEnd: false,
      talkHRecords: [],
      historyKeyword: null,
      fileTab: 'list'
    };
  },
  mounted() {
    this.initCanUserTalk();
  },
  computed: {
    title() {
      if (this.talkUserId) {
        let nickName = this.talkUser.nickName;
        return `在线沟通（${nickName}）`
      } else {
        return `在线沟通`
      }
    },
    talkUserDatas() {
      let keyword = this.keyword;
      let unread = this.unread;
      return this.talkUsers.filter(talkUser => {
        let flag1 = keyword ? talkUser.nickName.includes(keyword) : true;
        let flag2 = unread ? talkUser.readed == 1 : true;
        return flag1 && flag2;
      })
    },
    talkUser() {
      let talkUserId = this.talkUserId;
      if (talkUserId) {
        return this.talkUsers.find(user => user.toUser === talkUserId) || {}
      } else {
        return {};
      }
    },
    records() {
      let talkUser = this.talkUser;
      let talkRecords = talkUser && talkUser.toUser && talkUser.talkRecords ? talkUser.talkRecords : [];
      let dataMap = xeUtils.groupBy(talkRecords, '_time');
      let datas = [];
      Object.keys(dataMap).forEach(key => {
        datas.push({
          time: key,
          datas: dataMap[key]
        })
      })
      return datas;
    },
    hasFile() {
      let files = this.files.filter(file => file.status !== "success");
      return files.length > 0;
    }
  },
  beforeDestroy() {
    this.clearTimerHandle();
  },
  methods: {
    bindMove(e) {
      let that = this;
      that.btnDisabled = false;
      let x = e.target;
      let H = document;
      let sh = window.innerHeight - 100;
      let sw = window.innerWidth - 100;
      let styleObj = getComputedStyle(x)
      let left0 = Number(styleObj.left.replaceAll('px', ''));
      let top0 = Number(styleObj.top.replaceAll('px', ''));
      let y0 = e.clientY;
      let x0 = e.clientX;
      indexUtil.addClass(document.body, "resize-ing");
      H.onmousemove = function (u) {
        u.preventDefault();
        let a = top0 + (u.clientY - y0);
        let b = left0 + (u.clientX - x0);

        let diff = Math.abs(u.clientY - y0) + Math.abs(u.clientX - x0);//移动偏差
        that.btnDisabled = diff > 2;//移动偏差大于2，禁用按钮点开事件

        x.style.top = Math.min(Math.max((a), 0), sh) + 'px'
        x.style.left = Math.min(Math.max((b), 0), sw) + 'px'
      };

      H.onmouseup = function (u) {
        indexUtil.removeClass(document.body, "resize-ing");
        H.onmousemove = null;
        H.onmouseup = null;
        if (that.btnDisabled) {
          setTimeout(() => {
            that.btnDisabled = false;
          }, 200)
        }
      };

    },
    getUserItemClass(row) {
      let arr = [];
      if (row.toUser == this.talkUserId) {
        arr.push('on');
      }
      if (row.readed == 1) {
        arr.push('noRead');
      }
      arr.push('user_' + row.toUser);
      return arr.join(" ");
    },
    handleScroll1(event) {
      let scrollTop = event.target.scrollTop;
      let scrollHeight = event.target.scrollHeight;
      let clientHeight = event.target.clientHeight;
      let isTop = scrollTop <= 0;
      let isButtom = scrollTop + clientHeight >= scrollHeight;
      if (isTop) {
        //上拉，查上一页的记录
        let firstDom = event.target.querySelector('.item');
        this.getList(1, () => {
          firstDom && firstDom.scrollIntoView();
        });
      }
    },
    addFile() {
      if (!this.talkUserId) return
      this.$baseUpload.open({
        limit: 200,
        accept: "file",
        size: 5 * 1024 * 1024 * 1024,
        pickPrivateProfile: true,
        callback: (rows) => {
          this.saveFileTalk(rows);
        },
      });
    },
    confirmInserUser(rows) {
      if (rows.length) {
        let row = rows[0];
        this.saveTalkUser(row);
      }
    },
    deleteTalkUser(row, index) {
      this.$http({
        url: USER_PREFIX + `/talkUser/delete`,
        method: `post`,
        data: {id: row.toUser},
        isLoading: true,
        loadingTarget: document.body,
        success: res => {
          if (row.toUser == this.talkUser.toUser) {
            this.talkUserId = null
          }
          this.talkUsers.splice(index, 1)
        }
      });
    },
    openDialog() {
      if (this.btnDisabled) return;
      this.dialogTableVisible = true;
      setTimeout(() => {
        treeScolly({target: this.$refs.talkDialog, type: 'default', rate: true, nextMin: 250});
      }, 200)
      this.talkHandle()
    },
    handleClose() {
      this.isFullscreen = false;
    },
    getUserInfo() {
      this.$http({
        url: USER_PREFIX + '/user/currentUser',
        method: 'post',
        success: res => {
          let userInfo = res.objx;
          this.userInfo = userInfo;
        }
      });
    },
    saveFileTalk(rows, callback) {
      let talkUser = this.talkUser;
      if (!this.talkUserId || rows.length == 0) return
      let userInfo = this.userInfo;
      let size = rows.length;
      let num = 0;
      rows.forEach(row => {
        let content = "#file:" + JSON.stringify(row);
        this.$http({
          url: USER_PREFIX + `/talk/save`,
          method: `post`,
          data: {
            toUser: talkUser.toUser,
            content: content
          },
          isLoading: true,
          loadingTarget: document.body,
          callback: res => {
            num++;
            if (num >= size) {
              this.getList(0, () => {
                this.$nextTick(() => {
                  this.topChatBoxButtom();
                  this.$refs.contentRef.focus();
                })
              });
              callback && callback();
            }
          }
        });
      })


    },
    saveTalk(formData) {
      let talkUser = this.talkUser;

      let userInfo = this.userInfo;
      let reqDaqta = {
        toUser: talkUser.toUser,
        content: talkUser.content,
        ...formData
      }
      if (!this.talkUserId || !reqDaqta.content) return
      this.$http({
        url: USER_PREFIX + `/talk/save`,
        method: `post`,
        data: reqDaqta,
        isLoading: true,
        loadingTarget: document.body,
        success: res => {
          let row = res.objx || {};
          talkUser.content = null;
          this.getList(0, () => {
            this.$nextTick(() => {
              this.topChatBoxButtom();
              this.$refs.contentRef.focus();
            })
          })
        }
      });
    },
    getUserPage(flag) {
      if (!this.dialogTableVisible) return
      if (!this.inited) {
        flag = null;
        this.inited = true;
      }
      let time = flag === 1 ? moment().format('YYYY-MM-DD HH:mm:ss') : null;
      this.$http({
        url: USER_PREFIX + `/talkUser/list`,
        method: `post`,
        data: {operateTime: time},
        modal: false,
        success: res => {
          let records = res.objx || [];
          records.forEach(record => {
            Object.assign(record, {
              talkRecords: [],
              content: null
            })
          });
          let ids = records.map(record => record.id);
          if (flag == 1) {
            let users = [];
            this.talkUsers.forEach(talkUser => {
              let item = records.find(record => record.toUser == talkUser.toUser)
              if (item) {
                talkUser.readed = item.readed;
                Object.assign(item, talkUser)
              } else {
                users.push(talkUser);
              }
            });
            records.push(...users);
          }
          this.talkUsers = records;
        }
      });
    },
    saveTalkUser(row) {
      let item = this.talkUsers.find(talkUser => talkUser.toUser == row.id);
      if (!item) {
        this.$http({
          url: USER_PREFIX + `/talkUser/save`,
          method: `post`,
          data: {id: row.id},
          isLoading: true,
          loadingTarget: document.body,
          success: res => {
            this.talkUsers.splice(0, 0, {
              id: res.objx,
              toUser: row.id,
              nickName: row.nickName,
              mobile: row.mobile,
              readed: false,
              talkRecords: [],
              content: null
            });
            this.$nextTick(() => {
              let dom = this.$refs.userBox.querySelector('.user_' + row.id);
              dom && dom.scrollIntoView();
              this.checkUser(this.talkUsers[0]);
            })
          }
        });
      } else {
        let dom = this.$refs.userBox.querySelector('.user_' + item.toUser);
        dom && dom.scrollIntoView();
        this.checkUser(item);
      }

    },
    checkUser(row) {
      this.talkUserId = row.toUser;
      this.setReadState(row);
      this.getList(0, () => {
        this.$nextTick(() => {
          this.topChatBoxButtom();
          this.$refs.contentRef.focus();
        })
      });
    },
    getLastRecordId(direction) {
      direction = direction || 0;
      let lastTalkRecordId = null;
      let talkUser = this.talkUser;
      if (talkUser.talkRecords.length) {
        if (direction == 0) {
          //下拉，获取最后一条记录的ID
          lastTalkRecordId = talkUser.talkRecords [talkUser.talkRecords.length - 1].id;
        } else {
          //上拉，获取第一条记录的ID
          lastTalkRecordId = talkUser.talkRecords [0].id;
        }
      }
      return lastTalkRecordId;
    },
    getList(direction, callback) {
      if (!this.dialogTableVisible) return
      if (!this.talkUserId) return
      let talkUser = this.talkUser;
      if (direction == 1 && talkUser.topEnd) {
        ////上拉，且没有记录
        return;
      }
      let lastId = this.getLastRecordId(direction);
      direction = direction || 0;
      this.$http({
        url: USER_PREFIX + `/talk/list`,
        method: `post`,
        data: {
          toUser: this.talkUserId,
          lastId: lastId,
          direction: direction
        },
        modal: false,
        success: res => {
          let rows = res.objx || [];
          if (rows.length) {
            rows.forEach(row => {
              this.handleContent(row);
            })
            let items = rows;
            if (talkUser.talkRecords.length) {
              let ids = talkUser.talkRecords.map(item => item.id);
              items = rows.filter(item => !ids.includes(item.id));
            }
            if (direction == 0) {
              talkUser.talkRecords.push(...items);
            } else {
              talkUser.talkRecords.splice(0, 0, ...items);
            }
          }
          if (direction == 1 && rows.length == 0) {
            //上拉，且没有记录
            talkUser.topEnd = true;
          }
          callback && callback();
        }
      });
    },
    handleContent(row) {
      //处理消息的发送时间（精确到分钟），用于分组
      row._time = row.createDate.substring(0, 16)
      //处理文本是否文件
      let contentType = 0;
      let file = null;
      let answers = [];
      let cotnent = row.content;
      let str = "#file:";
      let str2 = "#answer:";
      if (cotnent) {
        if (cotnent.indexOf(str) == 0) {
          let jsonStr = cotnent.slice(str.length)
          if (jsonStr) {
            try {
              file = JSON.parse(jsonStr);
              if (!file.domain || !file.url) {
                file = null;
              }
            } catch (e) {
              console.error(e);
            }
          }
          contentType = 1;
        } else if (cotnent.startsWith(str2)) {
          let jsonStr = cotnent.slice(str2.length)
          if (jsonStr) {
            try {
              answers = JSON.parse(jsonStr) || [];
            } catch (e) {
              console.error(e);
            }
          }
          contentType = 2;
        }
      }

      row.contentType = contentType;
      row.file = file;
      row.answers = answers;
    },
    createTimerHandle() {
      this.clearTimerHandle();
      this.handleExitsRead();
      this.talkHandle();
      this.timer = setInterval(() => {
        this.handleExitsRead();
        this.talkHandle();
      }, 10000)
    },
    talkHandle() {
      this.getUserPage(1);
      this.getList(0);
    },
    clearTimerHandle() {
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null;
      }
    },
    setReadState(row) {
      this.$http({
        url: USER_PREFIX + `/talkUser/setReadState`,
        method: `post`,
        data: {id: row.toUser},
        success: res => {
          row.readed = 0;
        }
      });
    },
    handleExitsRead() {
      this.$http({
        url: USER_PREFIX + `/talkUser/isExitsRead`,
        method: `post`,
        data: {},
        modal: false,
        success: res => {
          this.isExitsRead = res.objx === 1;
        }
      });
    },
    topChatBoxButtom() {
      let dom = this.$refs.chatBox
      let scrollTop = dom.scrollTop;
      let scrollHeight = dom.scrollHeight;
      let clientHeight = dom.clientHeight;
      dom.scrollTop = scrollHeight - clientHeight
    },
    initCanUserTalk() {
      this.$http({
        url: USER_PREFIX + `/talkRole/canUserTalk`,
        method: `post`,
        data: {},
        failMsg: false,
        errorMsg: false,
        success: res => {
          this.isCanUserTalk = res.objx === true;
          if (this.isCanUserTalk) {
            this.initPrivateUploadBt();
            this.createTimerHandle();
            this.getUserInfo();
          }
        }
      });
    },
    openUserDialog() {
      this.$http({
        url: USER_PREFIX + `/talkRole/talkRoleList`,
        method: `post`,
        data: {},
        isLoading: true,
        loadingTarget: document.body,
        success: res => {
          let roleCodes = res.objx || [];
          this.roleCodes = roleCodes;
          this.showUserDialog = true;
        }
      });
    },
    //file begin
    formatFileSize(fileSize) {
      fileSize = fileSize || 0;
      if (fileSize < 1024) {
        return fileSize + 'B';
      } else if (fileSize < (1024 * 1024)) {
        var temp = fileSize / 1024;
        temp = temp.toFixed(2);
        return temp + 'KB';
      } else if (fileSize < (1024 * 1024 * 1024)) {
        var temp = fileSize / (1024 * 1024);
        temp = temp.toFixed(2);
        return temp + 'MB';
      } else {
        var temp = fileSize / (1024 * 1024 * 1024);
        temp = temp.toFixed(2);
        return temp + 'GB';
      }
    },
    getShowImage(file, fileName) {
      fileName = fileName || file.name;
      if (this.$commonFileUtil.isPictureFile(fileName)) {
        return file.showUrl || file.url;
      } else {
        return this.$commonFileUtil.getFileIconRequire(fileName);
      }
    },
    pasteMessage(event) {
      const clipboardData = event.clipboardData || window.clipboardData;
      const rawFiles = Array.from(clipboardData.files);
      if (rawFiles.length) {
        event.preventDefault();
        this.addFiles(rawFiles);
      }
    },
    createFileObj(rawFile, isPrimitive) {
      let uid = Date.now() + this.tempIndex++;
      let name = isPrimitive ? rawFile.fileName : rawFile.name;
      let index = name.lastIndexOf(".");
      let getFileSuffix = this.$commonFileUtil.getFileSuffix;
      let fileSuffix = isPrimitive ? rawFile.extension : getFileSuffix(name);
      let fileName = index >= 0 ? name.substring(0, index).toString() : name.toString();
      let file = null;
      if (!isPrimitive) {
        file = {
          status: 'ready',
          name: rawFile.name,
          size: rawFile.size,
          percentage: 0,
          uid: uid,
          raw: rawFile,
          url: URL.createObjectURL(rawFile),
          fileName: fileName,
          fileSuffix: fileSuffix
        };
      } else {
        let fileInfo = {
          name: rawFile.fileName,
          thumbnail: rawFile.thumbnail,
          extension: rawFile.extension,
          large: rawFile.large,
          fileSize: rawFile.fileSize,
          domain: rawFile.domain,
          widthHeight: rawFile.widthHeight,
          source: rawFile.source,
          medium: rawFile.medium,
          url: rawFile.url
        };
        file = {
          status: 'ready',
          name: rawFile.fileName,
          size: rawFile.fileSize,
          percentage: 0,
          uid: uid,
          // raw: rawFile,
          fileInfo: fileInfo,
          url: this.getShowUrl(rawFile),
          fileName: fileName,
          fileSuffix: fileSuffix
        };
      }
      return file;
    },
    changeFile(e) {
      let rawFiles = Array.from(e.target.files);
      this.addFiles(rawFiles);
    },
    changeFileName(file) {
      if (file.fileSuffix) {
        file.name = (file.fileName + "." + file.fileSuffix).toString();
      } else {
        file.name = file.fileName.toString();
      }
    },
    addFiles(rawFiles, isPrimitive) {
      if (rawFiles) {
        let files = rawFiles.map(rawFile => {
          let file = this.createFileObj(rawFile, isPrimitive);
          return file;
        });
        this.files.push(...files);
      }
    },
    sendMsg() {
      this.saveTalk();
      this.uploadFile();
    },
    uploadFile() {
      let files = this.files.filter(file => file.status == "ready");
      if (!files.length) return
      files.forEach(file => {
        file.status = "uploading";
        if (file.raw) {
          this.$baseUpload.upload({
            file: file.raw,
            isLoading: true,
            onProgress: (progressEvent, fileObj) => {
              let percent = Math.min(progressEvent.percent, 99);
              this.$set(file, "percentage", percent);
            },
            callback: (res) => {
              if (res.type == "success") {
                let fileData = res.objx;
                fileData.name = file.name;
                this.saveFileTalk([fileData], () => {
                  this.$set(file, "percentage", 100);
                  file.status = "success";
                });
              } else {
                file.status = "fail"
                file.failMsg = res.content;
                this.$set(file, "percentage", 0);
              }
            },
          });
        } else {
          this.saveFileTalk([file.fileInfo], () => {
            this.$set(file, "percentage", 100);
            file.status = "success";
          });
        }
      })
    },
    deleteFile(index) {
      this.files.splice(index, 1);
    },
    confirmPrivateProfileDialog(rows) {
      this.addFiles(rows, true)
    },
    getShowUrl(attachment, field) {
      let showUrl = null;
      let typeStr = Object.prototype.toString.call(attachment);
      if (typeStr == '[object Object]') {
        let showField = field ? field : 'medium';
        let fullUrl = attachment.domain + (attachment[showField] ? attachment[showField] : attachment.url);
        showUrl = this.$commonFileUtil.getShowUrl(fullUrl)
      } else {
        showUrl = this.$commonFileUtil.getShowUrl(attachment)
      }
      return showUrl;
    },
    initPrivateUploadBt() {
      if (settingConfig.privateProfileCode) {
        this.$http({
          url: USER_PREFIX + '/file_store_area/getByCode',
          method: 'post',
          data: {"stringOne": settingConfig.privateProfileCode},
          failMsg: false,
          errorMsg: false,
          success: res => {
            this.showPrivateUploadBtn = res.objx ? true : false;
          }
        });
      } else {
        this.showPrivateUploadBtn = false;
      }
    },
    handleEnterWithCtrl(event) {
      event.stopPropagation();
      event.preventDefault();
      this.sendMsg();
    },
    openFileNameDialog(row, index) {
      this.editFileName = row.fileName?.toString();
      this.editFileSuffix = row.fileSuffix?.toString();
      this.editFileIndex = index
      this.showFileNameDialog = true;
    },
    confirmFileNameDialog() {
      if (!this.editFileName) {
        this.$message({
          message: "文件名不能为空",
          type: "error",
          showClose: true,
          duration: 3000,
        });
        return
      }
      let editFileIndex = this.editFileIndex;
      let file = this.files[editFileIndex];
      file.fileName = this.editFileName.toString();
      file.name = (file.fileName + "." + file.fileSuffix).toString();
      this.showFileNameDialog = false;
    },
    answerCheckHandle(item) {
      this.saveTalk({
        content: item.question,
        knowledgeId: item.id
      })
    },
    openHistoryDialog() {
      this.historyKeyword = null;
      this.historyType = null;
      this.topHistoryEnd = false;
      this.talkHRecords = [];
      this.showHistoryDialog = true;
      this.getHList(0, () => {
        if (this.talkHRecords.length) {
          this.$nextTick(() => {
            document.querySelector('.talk_h' + this.talkHRecords[this.talkHRecords.length - 1].id).scrollIntoView();
          })
        }
      });
    },
    checkHistoryType(historyType) {
      this.historyType = historyType;
      this.topHistoryEnd = false;
      this.talkHRecords = [];
      this.getHList(0, () => {
        if (this.talkHRecords.length) {
          this.$nextTick(() => {
            document.querySelector('.talk_h' + this.talkHRecords[this.talkHRecords.length - 1].id).scrollIntoView();
          })
        }
      });
    },
    changeHistoryKeyword() {
      this.topHistoryEnd = false;
      this.talkHRecords = [];
      this.getHList(0, () => {
        if (this.talkHRecords.length) {
          this.$nextTick(() => {
            document.querySelector('.talk_h' + this.talkHRecords[this.talkHRecords.length - 1].id).scrollIntoView();
          })
        }
      });
    },
    handleScrollH(event) {
      let scrollTop = event.target.scrollTop;
      let scrollHeight = event.target.scrollHeight;
      let clientHeight = event.target.clientHeight;
      let isTop = scrollTop <= 0;
      let isButtom = scrollTop + clientHeight >= scrollHeight;
      if (isTop) {
        //上拉，查上一页的记录
        let firstDom = event.target.querySelector('.item');
        this.getHList(1, () => {
          firstDom && firstDom.scrollIntoView();
        });
      }
    },
    getHList(direction, callback) {
      if (!this.showHistoryDialog) return
      if (!this.talkUserId) return
      let talkUser = this.talkUser;
      if (direction == 1 && this.topHistoryEnd) {
        ////上拉，且没有记录
        return;
      }
      let lastId = this.getLastHRecordId(direction);
      direction = direction || 0;
      this.$http({
        url: USER_PREFIX + `/talk/list`,
        method: `post`,
        data: {
          toUser: this.talkUserId,
          lastId: lastId,
          direction: direction,
          type: this.historyType,
          keyWord: this.historyKeyword
        },
        modal: false,
        success: res => {
          let rows = res.objx || [];
          let talkHRecords = this.talkHRecords;
          if (rows.length) {
            rows.forEach(row => {
              this.handleContent(row);
            })
            let items = rows;
            if (talkHRecords.length) {
              let ids = talkHRecords.map(item => item.id);
              items = rows.filter(item => !ids.includes(item.id));
            }
            if (direction == 0) {
              talkHRecords.push(...items);
            } else {
              talkHRecords.splice(0, 0, ...items);
            }
          }

          if (direction == 1 && rows.length == 0) {
            //上拉，且没有记录
            this.topHistoryEnd = true;
          }
          callback && callback();
        }
      });
    },
    getLastHRecordId(direction) {
      direction = direction || 0;
      let lastTalkRecordId = null;
      if (this.talkHRecords.length) {
        if (direction == 0) {
          //下拉，获取最后一条记录的ID
          lastTalkRecordId = this.talkHRecords[this.talkHRecords.length - 1].id;
        } else {
          //上拉，获取第一条记录的ID
          lastTalkRecordId = this.talkHRecords[0].id;
        }
      }
      return lastTalkRecordId;
    },
    //file end
  }
};
export const mixins = tmixins
