// 聊天室 -- 咨询
import React from 'react';
// import ReactDOM from 'react-dom';
import "../common/style/index.less";
import "./style/index.less";
import TIM from 'tim-js-sdk';
// 发送图片、文件等消息需要的 COS SDK
import COS from "cos-js-sdk-v5";
import { TextareaItem, PullToRefresh, Toast, Modal, Popover, ActivityIndicator } from 'antd-mobile';
import { $http } from "containers/config/https";
import { emojiMap, emojiName, emojiUrl } from "../../../tools/emojiMap.js"; //
import { decodeText } from '../../../tools/decodeText.js'; // 解析表情

import copy from 'copy-to-clipboard'; // 复制到粘贴板

const alert = Modal.alert;
const Item = Popover.Item;

export default class ChatRoomConsultation extends React.Component {
  constructor({ history }) {
    super();
    let userData = localStorage.getItem("userData") ? JSON.parse(localStorage.getItem("userData")) : {};
    this.state = {
      userData,
      messageValue: undefined,
      sendHeight: "60px",
      refreshing: false,
      chatData: [],
      doctorData: {},
      moreMsgFlag: "Y",
      newMessage: "",
      lastMsgID: "",
      isKickedOut: true,
      imgPath: "",
      emoticonVisible: false,
      textareaItemVisible: false
    };
    this.history = history;
    this.tim = null;
    this.timeOutEvent = 0;//定时器   
    this.timeOutTextareaItem = 0;

    this.message = {}
  }

  componentDidMount() {
    let options = {
      SDKAppID: 1400361531 // 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
    };
    // 创建 SDK 实例，TIM.create() 方法对于同一个 SDKAppID 只会返回同一份实例
    this.tim = TIM.create(options); // SDK 实例通常用 tim 表示

    // 设置 SDK 日志输出级别，详细分级请参见 setLogLevel 接口的说明
    this.tim.setLogLevel(0); // 普通级别，日志量较多，接入时建议使用
    // tim.setLogLevel(1); // release 级别，SDK 输出关键信息，生产环境时建议使用

    // 注册 COS SDK 插件
    this.tim.registerPlugin({ 'cos-js-sdk': COS });

    // let {userData} = this.state;
    // this.login(userData.imUserID, "user");

    this.customFocusInst.focus();
    let doctorData = this.props.location && this.props.location.state ? this.props.location.state : {};
    console.log(doctorData)
    if (doctorData && doctorData.doctorID) {
      this.queryWhetherTheUserExists(doctorData)
      document.title = doctorData.doctorName ? doctorData.doctorName : "咨询";
      this.setState({ doctorData }, () => {
        this.getChatData("isScroll", "", "");
      })
    } else {
      this.history.goBack();
    }
    let messageScrollDom = document.querySelector(".am-pull-to-refresh");
    if (messageScrollDom) {
      messageScrollDom.addEventListener('scroll', this.onMessageScroll);
    }

    document.addEventListener("click", this.hideMoticonVisible);
  }

  componentWillUnmount() {
    this.modifyMessageStatus();
    this.signOut();
    let messageScrollDom = document.querySelector(".am-pull-to-refresh");
    if (messageScrollDom) {
      messageScrollDom.removeEventListener('scroll', this.bindHandleScroll);
    }
    this.setState = (state, callback) => {
      return;
    };
    // this.tim = null;
    document.removeEventListener("click", this.hideMoticonVisible);
  }

  //  检查IM通信用户是否存在
  queryWhetherTheUserExists = (doctorData) => {
    let { userData } = this.state;
    let data = {
      params: [{
        imUserID: doctorData.imUserID,
      }]
    }
    $http.post("urlS", this, {
      code: "03090001",
      data: data,
      namespace: "HIS",
      success: function (res) {
        if (+res.errorCode === 0) {
          if (res.result.exitFlag === "Y") {
            console.log(doctorData.imUserID, "用户已存在。")
            this.login(userData)
          } else {
            this.login(doctorData, "user");
          }
        } else {
          Toast.info(res.errorMessage, 3, () => { }, false)
        }
      }
    })
  }

  // 保存IM通信用户
  saveCommunicationUser = (doctorData) => {
    let data = {
      params: [{
        userType: 'U',
        userID: doctorData.doctorID || '',
      }]
    }
    $http.post("urlS", this, {
      code: "03090002",
      data: data,
      namespace: "HIS",
      success: function (res) {
        if (+res.errorCode === 0) {
          console.log(doctorData.imUserID + "用户保存成功。")
        } else {
          Toast.info(res.errorMessage, 3, () => { }, false)
        }
      }
    })
  }

  // 更新图文咨询本次聊天记录状态
  modifyMessageStatus = () => {
    let { doctorData, userData } = this.state;
    if (!(doctorData && doctorData.imUserID)) {
      return;
    }
    let data = {
      params: [{
        signRecordID: doctorData.signRecordID || '',
        frUser: userData.imUserID || '',
        toUser: doctorData.imUserID || '',
      }]
    }
    $http.post("urlS", this, {
      code: "03070082",
      data: data,
      namespace: "HIS",
      success: function (res) {
        if (+res.errorCode === 0) {
          console.log("更新记录状态成功");
        } else {
          Toast.info(res.errorMessage, 3, () => { }, false)
        }
      }
    })
  }

  // 监听滚动条变化
  onMessageScroll = (event) => {
    this.closeBubble("navBarVisible"); // 滚动消息列表时将复制等功能弹窗英隐藏
    this.setState({ textareaItemVisible: false }); // 滚动消息列表时将粘贴弹窗关闭
    let messageScrollDom = document.querySelector(".am-pull-to-refresh");
    let heigth = messageScrollDom.clientHeight || messageScrollDom.offsetHeight;
    if (messageScrollDom.scrollHeight > heigth) {
      if ((messageScrollDom.scrollHeight - heigth) === messageScrollDom.scrollTop) {
        this.setState({ newMessage: "" }, () => {
          this.getSendHeight();
        })
      }
    }
  }

  // 获取消息列表数据
  getChatData = (isScroll, isLoading, newMessage, isRefresh) => {
    let { doctorData, userData, lastMsgID } = this.state;
    if (isLoading !== "isLoading") {
      this.setState({ refreshing: true });
    }
    let data = {
      params: [{
        signRecordID: doctorData.signRecordID || '',
        frUser: userData.imUserID || '',
        toUser: doctorData.imUserID || '',
        lastMsgID
        // lastMsgID: chatData&&chatData.length > 0 ? chatData[0].megID : ""
      }]
    }
    $http.post("urlS", this, {
      code: "03070077",
      data: data,
      namespace: "HIS",
      success: function (res) {
        if (+res.errorCode === 0) {
          let chatData = res.result && res.result.msgData instanceof Array ? res.result.msgData : [];
          for (var i = 0; i < chatData.length; i++) {
            chatData[i].navBarVisible = false;
            chatData[i].key = i + 1;
          }
          this.setState({ chatData, refreshing: false, moreMsgFlag: res.result.moreMsgFlag, newMessage: newMessage ? newMessage : "" }, () => {
            this.getSendHeight(isScroll, isRefresh);
          });
        } else {
          this.setState({ chatData: [], refreshing: false, moreMsgFlag: "Y", newMessage: newMessage ? newMessage : "" })
        }
      }
    });
  }

  // 计算前十条数据的高度
  getNewMessageHeight = () => {
    let {chatData} = this.state;
    let height = 0;
    for (let i = 0; i < 20; i++) {
      if (chatData[i].msgType === "1" && chatData[i].consultText) {
        height += 56
      } else if (chatData[i].msgType === "1" && chatData[i].picture) {
        height += 150
      } else if (chatData[i].msgType === '3' || chatData[i].msgType === '2') {
        height += 33
      }
    }
    console.log(height)
    return height; 
  }

  // 重新获取底部高度
  getSendHeight = (isScroll, isRefresh) => {
    let sendDom = document.getElementById("message-send-box-wrapper");
    var sendHeight = sendDom.offsetHeight || sendDom.clientHeight;
    this.setState({ sendHeight: sendHeight + "px" }, () => {
      if (isScroll === "isScroll") {
        this.messageWrapperScrollBottom();
      }
      if (isRefresh === "isRefresh") {
        let height = this.getNewMessageHeight();
        this.messageWrapperScrollBottom(height);
      }
    })
  }

  // input-onChange
  messageValueOnChange = e => {
    this.setState({ messageValue: e }, () => {
      this.getSendHeight();
    });
  }

  // 消息列表滚动条默认至最低端
  messageWrapperScrollBottom = (height) => {
    let messageScrollDom = document.querySelector(".am-pull-to-refresh");
    if (height) {
      messageScrollDom.scrollTop = height;
    } else {
      console.log(messageScrollDom.scrollHeight)
      messageScrollDom.scrollTop = messageScrollDom.scrollHeight;
    }
  }

  login = (doctorData, type) => {
    // if (!imUserID) {
    //   return;
    // }
    let user = window.genTestUserSig(doctorData.imUserID || "");
    let promise = this.tim.login({ userID: doctorData.imUserID || "", userSig: user && user.userSig ? user.userSig : "" });
    promise.then((imResponse) => {
      if (imResponse.data.errorCode === 0) {
        this.setState({ isKickedOut: true }, () => {
          this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, this.onMessageReceived);
          this.tim.on(TIM.EVENT.KICKED_OUT, this.monitorKickedOut);
        })
        if (type === "user") {
          this.saveCommunicationUser(doctorData);
          setTimeout(() => {
            this.signOut("user"); // 退出医生登录
          }, 300)
        }
      } else {
        Toast.info(imResponse.data.errorInfo, 3, () => { }, false);
      }
    }).catch(function (imError) {
      console.warn('login error:', imError); // 登录失败的相关信息
    });
  }

  // 退出
  signOut = (type) => {
    let { userData } = this.state;
    let promise = this.tim.logout();
    if (promise) {
      promise.then((imResponse) => {
        console.log("用户退出成功");
        if (type === "user") {
          this.login(userData || "");
        }
      }).catch(function (imError) {
        console.warn('logout error:', imError);
      });
    }
  }

  // 监听接收消息
  onMessageReceived = event => {
    // console.log("触发监听了", event)
    let { doctorData } = this.state;
    let from = event.data[0].from;
    if (doctorData && doctorData.imUserID === from) {
      let messageScrollDom = document.querySelector(".am-pull-to-refresh");
      let heigth = messageScrollDom.clientHeight || messageScrollDom.offsetHeight;
      if (messageScrollDom.scrollHeight > heigth) {
        let lastMessage = document.querySelectorAll(".mw-message")[document.querySelectorAll(".mw-message").length - 1];
        let lastMessageHeight = lastMessage.clientHeight || lastMessage.offsetHeight;
        if ((messageScrollDom.scrollHeight - heigth - messageScrollDom.scrollTop) > lastMessageHeight) {
          // 显示
          let newMessage = event.data && event.data.length > 0 ? event.data[0].payload.text : ""
          this.setState({ sendHeight: "84px" }, () => {
            this.getChatData("", "", newMessage);
          })
        } else {
          this.getChatData("isScroll", "", "");
        }
      } else {
        this.getChatData("isScroll", "", "");
      }
    }
  }

  // 监听是否被踢下线
  monitorKickedOut = (event) => {
    let { isKickedOut } = this.state;
    if (!isKickedOut) return;
    this.setState({isKickedOut: false}, () => {
      alert('账号异常', '您的账号在别处登录，是否重新登录???', [
        { text: '退出', onPress: () => this.confirmLoginAgain(1) },
        { text: '确认', onPress: () => this.confirmLoginAgain(2) },
      ])
    })
  }

  // 确认重新登录
  confirmLoginAgain = (num) => {
    let { userData } = this.state;
    // this.login(userData.imUserID, "user");
    this.setState(() => {
      if (num === 1) {
        this.history.goBack()
      } else {
        this.login(userData || "");
      }
    })
  }

  canvasDataURL = (path, obj, callback) => {
    var img = new Image();
    img.src = path;
    img.onload = function () {
      var that = this;
      // 默认按比例压缩
      var w = that.width,
        h = that.height,
        scale = w / h;
      w = obj.width || w;
      h = obj.height || (w / scale);
      var quality = 0.6;  // 默认图片质量为0.7
      //生成canvas
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      // 创建属性节点
      var anw = document.createAttribute("width");
      anw.nodeValue = w;
      var anh = document.createAttribute("height");
      anh.nodeValue = h;
      canvas.setAttributeNode(anw);
      canvas.setAttributeNode(anh);
      ctx.drawImage(that, 0, 0, w, h);
      // 图像质量
      if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
        quality = obj.quality;
      }
      // quality值越小，所绘制出的图像越模糊
      var base64 = canvas.toDataURL('image/jpeg', quality);
      // 回调函数返回base64的值
      callback(base64);
    }
  }

  fileToBase64 = (file) => {
    let _this = this;
    let reader = new FileReader();
    reader.readAsDataURL(file[0]);
    return new Promise((resolve, reject) => {
      reader.onload = function (e) { //这里是一个异步，所以获取数据不好获取在实际项目中，就用new Promise解决
        if (e.target.result) {
          // resolve(e.target&&e.target.result ? e.target.result : "");
          _this.canvasDataURL(e.target && e.target.result ? e.target.result : "", {width: 150}, resolve);
        } else {
          reject("")
        }
      }
    })
  }

  // 图片上传至服务器
  imageUpload = (fileList, success, error) => {
    let {userData} = this.state;
    if (!(userData&&userData.upLoadUrl)) {
      Toast.info('图片发送失败', 3, () => { }, false);
      this.deleteLoading();
      return;
    };
    let data = new FormData();
    data.append('file', fileList);
    const option = {
      method: 'post',
      mode: 'cors',
      headers: {},
      body: data
    };
    fetch(userData.upLoadUrl, option)
      .then(function (response) {
        if (response.ok) {
          return response.text();
        } else {
          console.log('网络错误，请稍后再试')
          return;
        }
      }).then(function (data) {
        let dataS = JSON.parse(data);
        success(dataS.filePath);
      }).catch(function (e) {
        console.log("发送失败： ", e);
        error&&error(e);
      })
  }

  // 发送
  handleSend = (type) => {
    let { messageValue, doctorData, userData, chatData } = this.state;
    if (type === "img") {
      let imagePickerDom = document.getElementById("imagePicker");
      let loadingImg = {
        pictureLoading: true,
        direction: "right",
        msgType: "1",
        isWithdraw: true,
        key: chatData.length + 1,
        msgID: "loading" + (chatData.length + 1)
      }
      this.setState({chatData: [...chatData, {...loadingImg}]}, () => {
        this.messageWrapperScrollBottom();
        this.imageUpload(imagePickerDom.files[0], (filePath) => {
          this.fileToBase64(imagePickerDom.files).then(res => {
            this.handleSaveImgInfo(filePath, res)
          })
        }, (error) => {
          Toast.info('发送失败：' + error, 3, () => { }, false);
          this.deleteLoading()
        })
      })
    } else if (type === "text") {
      let data = {
        params: [{
          signRecordID: doctorData.signRecordID || '',
          frUser: userData.imUserID || '',
          toUser: doctorData.imUserID || '',
          consultText: type === "text" ? messageValue : "",
          picture: "",
        }]
      }
      $http.post("urlS", this, {
        code: "03070072",
        data: data,
        namespace: "HIS",
        success: function (res) {
          if (+res.errorCode === 0) {
            this.handleSendText(res)
          } else {
            Toast.info(res.errorMessage, 3, () => { }, false)
          }
        }
      })
    }
  }

  // 保存图片信息
  handleSaveImgInfo = (filePath, fileBase64) => {
    let {doctorData, userData} = this.state;
    let data = {
      params: [{
        signRecordID: doctorData.signRecordID || '',
        frUser: userData.imUserID || '',
        toUser: doctorData.imUserID || '',
        consultText: "",
        picture: userData&&userData.downLoadUrl ? userData.downLoadUrl + filePath : "",
        pictureBase64: fileBase64
      }]
    }
    $http.post("urlS", this, {
      code: "03070072",
      data: data,
      namespace: "HIS",
      success: function (res) {
        if (+res.errorCode === 0) {
          this.handleSendImage(res.result && res.result.msgID ? res.result.msgID : "", fileBase64);
        } else {
          Toast.info(res.errorMessage, 3, () => { }, false)
        }
      }
    })
  }

  // 发送图片
  handleSendImage = (msgID, fileBase64) => {
    let { doctorData } = this.state;
    try {
      this.message = this.tim.createImageMessage({
        to: doctorData.imUserID,
        conversationType: TIM.TYPES.CONV_C2C,
        payload: {
          // file: res,
          file: document.getElementById("imagePicker")
        },
        onProgress: function (event) {
          console.log(event);
        }
      });
      // 2. 发送消息
      let promise = this.tim.sendMessage(this.message);
      if (promise) {
        promise.then((imResponse) => {
          // 发送成功
          if (imResponse && imResponse.code === 0) {
            let chatData = JSON.parse(JSON.stringify(this.state.chatData));
            let imgPath = imResponse.data.message.payload.imageInfoArray[0].imageUrl;
            let obj = {
              picture: imgPath,
              pictureBase64: fileBase64,
              direction: "right",
              msgType: "1",
              isWithdraw: true,
              key: chatData.length,
              msgID,
            }
            console.log(obj)
            this.setState({ chatData: this.replaceLoading([...this.state.chatData], obj) }, () => {
              console.log(this.state.chatData)
              // this.getChatData("isScroll", "", ""); // 获取消息
              this.messageWrapperScrollBottom();
              this.monitorRecallTime(obj, "isWithdraw"); // 发送信息成功之后多少秒后修改撤回状态
              // this.setState({})
            })
            // this.getChatData("isScroll", "", ""); // 获取消息
          }
        }).catch((imError) => {
          // 发送失败
          Toast.info('发送失败：' + imError, 3, () => { }, false);
          this.deleteChatData(msgID);
          this.deleteLoading()
        });
      }
    } catch (e) {
      Toast.info("发送失败: " + e.message, 3, () => { }, false)
    }
  }

  // 发送文字
  handleSendText = (res) => {
    let { messageValue, doctorData } = this.state;
    try {
      this.message = this.tim.createTextMessage({
        to: doctorData.imUserID,
        conversationType: TIM.TYPES.CONV_C2C,
        payload: {
          text: messageValue
        }
      });
      // 2. 发送消息
      let promise = this.tim.sendMessage(this.message);
      if (promise) {
        promise.then((imResponse) => {
          if (imResponse && imResponse.code === 0) {
            let chatData = JSON.parse(JSON.stringify(this.state.chatData));
            let text = imResponse.data.message.payload.text;
            let obj = {
              consultText: text,
              direction: "right",
              msgType: "1",
              isWithdraw: true,
              key: chatData.length + 1,
              msgID: res.result && res.result.msgID ? res.result.msgID : "",
            }
            chatData.push(obj)
            this.setState({ messageValue: "", chatData }, () => {
              // this.getChatData("isScroll", "", ""); // 获取消息
              this.messageWrapperScrollBottom();
              this.monitorRecallTime(obj, "isWithdraw");  // 发送信息成功之后多少秒后修改撤回状态
              // this.setState({})
            })
          }
        }).catch((imError) => {
          // 发送失败 --- 调接口改变消息状态
          Toast.info('发送失败：' + imError, 3, () => { }, false);
          this.deleteChatData(res.result.msgID)
        });
      }
    } catch (error) {
      Toast.info(error.message, 3, () => { }, false);
    }
  }

  // 过滤发送失败的图片loading
  deleteLoading = () => {
    if (this.state.chatData && this.state.chatData.length > 1) {
      let obj = {}
      this.setState({ chatData: this.replaceLoading([...this.state.chatData], obj) }, () => {
        this.messageWrapperScrollBottom();
      })
    }
  }

  // 图片加载成功之后替换加载中占位图
  replaceLoading(arr, obj) {
    let newArr = JSON.parse(JSON.stringify(arr));
    if (obj&&obj.key) {
      let msgID = "loading" + obj.key;
      newArr = newArr.map(item => item.msgID === msgID ? obj : item)
      return newArr;
    } else {
      let key = newArr[newArr.length - 1].key
      return newArr.filter(item => item.key !== key)
    }
  }

  // 删除图文咨询聊天记录
  deleteChatData = (msgID) => {
    let data = {
      params: [{
        msgID
      }]
    }
    $http.post("urlS", this, {
      code: "03070076",
      data: data,
      namespace: "HIS",
      success: function (res) {
        if (+res.errorCode === 0) {
          console.log(res)
        }
      }
    });
  }

  getTitle = () => {
    let promise = this.tim.getMessageList({ conversationID: 'C2Cuser2', count: 15 });
    promise.then(function (imResponse) {
      const messageList = imResponse.data.messageList; // 消息列表。
      const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉，分页续拉时需传入该字段。
      const isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。
      console.log(messageList, nextReqMessageID, isCompleted)
    });
  }

  // 选择图片
  handleOpenSelectImage = () => {
    // e.preventDefault();
    let imgDom = document.getElementById('imagePicker');
    imgDom.click();
  }

  // 开始录音 - 
  handleOnTouchStart = () => {
    let { userData } = this.state;
    let url = window.location.href.indexOf("#") !== -1 ? String(window.location.href).split("#")[0] : String(window.location.href);
    let data = {
      params: [{
        url,
        pubAccCode: userData.pubAccCode || "",
      }]
    }
    $http.post("urlS", this, {
      code: "01020008",
      data: data,
      success: (res) => {
        if (+res.errorCode === 0) {
          let data = res.result;
          // 生成签名后，开始使用微信的  wx.config 。其中jsApiList就是我们要用的API的列表，因为只需要取经纬度，所以用getLocation就可以了
          window.wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。   
            appId: data.appId, // 必填，公众号的唯一标识
            timestamp: data.timestamp, // 必填，生成签名的时间戳
            nonceStr: data.nonceStr, // 必填，生成签名的随机串
            signature: data.signature, // 必填，签名，见附录1
            jsApiList: [
              "startRecord",
              "stopRecord"
            ]
          });
          window.wx.error((res) => {
            Toast.info(JSON.stringify(res), 3, () => { }, false)
          });
          // wx.config 检测无误后，会进入到  ready 方法 。 注意type参数。微信多数的坐标体系都为gcj02
          window.wx.ready(() => {
            window.wx.startRecord();
          });
        }
      }
    });
  }

  // 录音结束
  handleOnTouchend = () => {
    window.wx.stopRecord({
      success: (res) => {
        console.log(res)
        this.handleSendAudio(res)
      }
    })
  }

  // 发送语音
  handleSendAudio = (res) => {
    // 示例：使用微信官方的 RecorderManager 进行录音，参考 RecorderManager.start(Object object)
    // 1. 获取全局唯一的录音管理器 RecorderManager

    // 2.2 监听录音结束事件，录音结束后，调用 createAudioMessage 创建音频消息实例
    const message = this.tim.createAudioMessage({
      to: 'user10',
      conversationType: TIM.TYPES.CONV_C2C,
      payload: {
        file: res
      }
    });

    // 5. 发送消息
    let promise = this.tim.sendMessage(message);
    promise.then(function (imResponse) {
      // 发送成功
      Toast.info("录音成功", 3, () => { }, false);
    }).catch(function (imError) {
      // 发送失败
      Toast.info('录音失败', 3, () => { }, false);
    });

  }

  // 点击消息提示重新查询数据
  handleNewMessage = () => {
    this.setState({ newMessage: "" }, () => {
      this.getSendHeight();
      this.messageWrapperScrollBottom();
    })
  }

  // 上拉加载更多数据
  handleOnrefresh = () => {
    let { moreMsgFlag, chatData, newMessage } = this.state;
    if (moreMsgFlag === "N") {
      if (chatData && chatData[0].sendTime === "没有更多消息记录了。") {
        return;
      }
      let obj = {
        direction: "right",
        msgType: "3",
        sendTime: "没有更多消息记录了。"
      }
      chatData.unshift(obj);
      this.setState({ chatData });
      return;
    }
    this.setState({ lastMsgID: chatData && chatData.length > 0 ? chatData[0].msgID : "" }, () => {
      this.getChatData("", "isLoading", newMessage, "isRefresh")
    })
  }

  handleShowModal = (imgPath) => {
    this.setState({ visible: true, imgPath })
  }

  handleClose = (type) => {
    this.setState({ [type]: false })
  }

  nameSlice = (str, type) => {
    if (str && str.length < 3) {
      return str;
    } else if (str.length === 3) {
      return str.slice(1)
    } else if (str.length === 4) {
      return str.slice(2)
    } else {
      return str.slice(4)
    }
  }

  hideMoticonVisible = () => {
    this.closeBubble("navBarVisible");
    this.setState({ emoticonVisible: false })
  }

  handleEmoticonClick = (e) => {
    e.nativeEvent.stopImmediatePropagation();
    this.setState({ emoticonVisible: true })
  }

  handleEmojiClick = (item, e) => {
    e.nativeEvent.stopImmediatePropagation();
    let messageValue = this.state.messageValue ? this.state.messageValue + item : item;
    this.setState({ messageValue });
  }

  // 渲染文字以及表情
  randerWordsAndExpressions = (text) => {
    let renderDom = decodeText(text);
    return renderDom && renderDom.map((item, index) => {
      return item.name === "text" ? <span key={index}>{item.text}</span> : <img src={item.src} alt="" key={index} className="img-expression" />
    })
  }

  // 开始按消息
  handleMsgTouchStart = (item, e) => {
    e.nativeEvent.stopImmediatePropagation();
    this.timeOutEvent = setTimeout(() => this.handleVisibleChange(item), 500)
  }

  // 手释放，如果在500毫秒内就释放，则取消长按事件，此时可以执行onclick应该执行的事件
  handleMsgTouchEnd = () => {
    clearTimeout(this.timeOutEvent);
    if (this.timeOutEvent !== 0) {
      // 可以是点击操作执行函数
    }
    return false;
  }

  // 如果手指有移动，则取消所有事件，此时说明用户只是要移动而不是长按
  handleMsgTouchMove = () => {
    clearTimeout(this.timeOutEvent);
    this.timeOutEvent = 0;
  }

  // 修改气泡弹窗状态
  handleVisibleChange = (item) => {
    let { chatData } = this.state;
    for (var i = 0; i < chatData.length; i++) {
      chatData[i].navBarVisible = false;
      if (chatData[i].key === item.key) {
        chatData[i].navBarVisible = true;
      }
    }
    this.setState({
      chatData
    });
  }

  closeBubble = (type) => { // 关闭气泡以及修改别的消息状态 -- 是否可以撤回 
    let { chatData } = this.state;
    for (var i = 0; i < chatData.length; i++) {
      chatData[i][type] = false;
    }
    this.setState({
      chatData
    });
  }

  onSelect = (item, opt) => {
    switch (opt.props.value) {
      case 'copy':
        if (copy(item.consultText)) {
          console.log("复制成功");
        } else {
          console.log("复制失败");
        }
        break
      case 'withdraw':
        if (!(this.message && this.message.ID)) return;
        this.tim.revokeMessage(this.message).then(() => {
          let obj = {
            ...item,
            msgType: "2",
            direction: "right",
            isModity: true
          }
          this.replaceMsg(obj);
          this.handleUndoChat(obj);
          this.closeBubble("navBarVisible");
        }).catch((err) => {
          Toast.info(err, 3, () => { }, false)
        })
        break
      default:
        break
    }
  };

  // 撤回图文咨询聊天记录
  handleUndoChat = (item) => {
    let data = {
      params: [{
        msgID: item.msgID || ""
      }]
    }
    $http.post("urlS", this, {
      code: "03070079",
      data: data,
      namespace: "HIS",
      success: (res) => {
        if (+res.errorCode === 0) {
          console.log(res)
        }
      }
    });
  }

  // 替换聊天 数据中的某一个对象
  replaceMsg = (obj) => {
    let { chatData } = this.state;
    for (var i = 0; i < chatData.length; i++) {
      if (chatData[i].key === obj.key) {
        chatData[i] = obj;
        break;
      }
    }
    this.setState({ chatData }, () => {
      this.monitorRecallTime(obj, "isModity")
    })
  }

  // 监听撤回时间以及编辑时间
  monitorRecallTime = (obj, type, time) => {
    setTimeout(() => {
      let { chatData } = this.state;
      for (var i = 0; i < chatData.length; i++) {
        if (chatData[i].key === obj.key) {
          chatData[i][type] = false;
          break;
        }
      }
      this.setState({ chatData })
    }, time ? time : 60000)
  }

  // 重新编辑
  handleReEdit = item => {
    this.setState({ messageValue: item.consultText })
  }

  render() {
    let { messageValue, sendHeight, chatData, doctorData, newMessage, visible, imgPath, userData, emoticonVisible } = this.state;
    return (
      <div className="chat-room-consultation chronic-disease-management">
        <div className="message-wrapper" style={{ height: "calc(100% - " + sendHeight + ")", overflow: "hidden" }}>
          <PullToRefresh
            damping={60}
            // ref={el => this.pullToRefreshRef = el}
            indicator={{ deactivate: '上拉加载更多' }}
            direction={'down'}
            refreshing={this.state.refreshing}
            onRefresh={this.handleOnrefresh}
          >
            {chatData && chatData.map((item, index) => {
              return (
                <div key={index} className={item.msgType === "1" && item.direction === "right" ? "mw-content mw-content-right mw-message" : (item.msgType === "1" && item.direction === "left" ? "mw-content mw-message" : "mw-message mw-content-content")}>
                  <div className="col-1" style={{ display: item.msgType === "1" ? "block" : "none" }}>
                    {/* 头像 */}
                    {item.direction === "left" ? this.nameSlice(doctorData.doctorName) : this.nameSlice(userData.patDesc)}
                    {/* {item.direction === "left" ? this.nameSlice(doctorData.doctorName || "", "doc") : this.nameSlice(userData.patDesc || "")} */}
                    {/* {item.direction === "left" ? <img src={logo1} alt="" /> : <img src={logo2} alt="" />} */}
                  </div>
                  {/* msgType === 1 正常消息， 2为撤回 ，3 为时间 */}
                  <Popover
                    overlayClassName="fortest"
                    overlayStyle={{ color: 'currentColor' }}
                    visible={item.navBarVisible}
                    overlay={[
                      (<Item key="4" value="copy" data-seed="logId">复制</Item>),
                      (item.isWithdraw ? <Item key="5" value="withdraw">撤回</Item> : ""),
                      // (<Item key="6" value="retransmission" >重发</Item>),
                    ]}
                    align={{
                      overflow: { adjustY: 0, adjustX: 0 },
                      offset: [-10, 10],
                    }}
                    // onVisibleChange={() => this.handleOnVisibleChange(item)}
                    onSelect={(e) => this.onSelect(item, e)}
                  >
                    <div className="col-2" style={{ display: item.msgType === "1" ? "block" : "none" }} onTouchStart={(e) => this.handleMsgTouchStart(item, e)} onTouchEnd={this.handleMsgTouchEnd} onTouchMove={this.handleMsgTouchMove}>
                      {/* 主题消息 */}
                      {/* <i className={item.direction === "left"&&item.picture ? "iconfont icon-juxingbeifen icon-color-fff icon-left" : (item.direction === "right"&&item.picture ? "iconfont icon-juxingbeifen icon-color-fff" : (item.direction === "left" ? "iconfont icon-juxingbeifen icon-color-fff icon-left" : "iconfont icon-juxingbeifen"))}></i> */}
                      <span className={item.direction === "left" && item.pictureBase64 ? "message-content message-received background-color-fff" : (item.direction === "right" && (item.pictureBase64 || item.pictureLoading) ? "message-content message-send background-color-fff" : (item.direction === "left" ? "message-content message-received" : "message-content message-send"))}>
                        {item.consultText ? this.randerWordsAndExpressions(item.consultText) : (item.pictureBase64 ? <img className="image" src={item.pictureBase64} onClick={() => this.handleShowModal(item.picture)} alt="" /> : (item.pictureLoading ? <div className="image img-loading">
                          <ActivityIndicator size="large" />
                          <span style={{ marginTop: 8 }}>图片加载中...</span>
                        </div> : ""))}
                      </span>
                    </div>
                  </Popover>
                  <div className="col-3" style={{ display: item.msgType === "2" || item.msgType === "3" ? "block" : "none" }}>
                    {/* 消息状态 */}
                    {item.msgType === "2" ? (<span>
                      {item.direction === "left" ? "对方撤回了一条消息" : "你撤回了一条消息"}
                      <strong className="re-edit" style={{ display: item.direction === "right" && item.isModity ? "inline-block" : "none" }} onClick={() => this.handleReEdit(item)}>重新编辑</strong>
                    </span>) : (item.msgType === "3" ? <span>{item.sendTime}</span> : "")}
                  </div>
                </div>
              )
            })}
          </PullToRefresh>
        </div>
        <div className="message-send-box-wrapper border-top-before" id="message-send-box-wrapper">

          {newMessage ? <div className="new-message-alert" onClick={this.handleNewMessage}>{doctorData && doctorData.doctorName + " ："}<span>{newMessage}</span></div> : ""}
          <div className="message-send-box-wrapper-content">
            {/* .jpg, .jpeg, .png, .gif */}
            <input accept="image/*" type="file" id="imagePicker" style={{ display: 'none' }} onChange={() => this.handleSend("img")} placeholder="截图后粘贴到输入框中" />
            <i className="iconfont icon-tupian" title="图片" onClick={this.handleOpenSelectImage}></i>
            {/* <Popover
              overlayClassName="fortest"
              overlayStyle={{ color: 'currentColor' }}
              visible={textareaItemVisible}
              overlay={[
                (<Item key="1" value="paste" data-seed="logId">粘贴</Item>)
                // (<Item key="6" value="retransmission" >重发</Item>),
              ]}
              placement="topLeft"
              align={{
                overflow: { adjustY: 0, adjustX: 0 },
                offset: [10, 0],
              }}
              onVisibleChange={this.handleTextareaIteOnVisibleChange}
              onSelect={this.handleTextareaItemOnSelect}
            > */}
            <TextareaItem
              placeholder=""
              data-seed="logId"
              autoHeight
              value={messageValue}
              ref={el => this.customFocusInst = el}
              onChange={this.messageValueOnChange}
            // onTouchStart={this.handleTextareaItemTouchStart} 
            // onTouchEnd={this.handleTextareaItemTouchEnd} 
            // onTouchMove={this.handleTextareaItemTouchMove}
            />
            {/* </Popover> */}
            <i className="iconfont icon-biaoqing" title="表情"
              // onTouchStart={this.handleOnTouchStart} 
              // onTouchEnd={this.handleOnTouchend}
              style={{ position: "relative" }}
              onClick={this.handleEmoticonClick}
            >
              {emoticonVisible ? (<div className="crc-emoticon-modal">
                <div className="emojis">
                  {emojiName instanceof Array && emojiName.map((item, index) => {
                    return (<div className="emoji" key={index} onClick={(e) => this.handleEmojiClick(item, e)}>
                      <img src={emojiUrl + emojiMap[item]} style={{ width: "30px", height: "30px" }} alt="" />
                    </div>)
                  })}
                </div>
              </div>) : ""}
            </i>
            {/* <i style={{display: messageValue ? "none" : "inline-block"}} title="更多" className="iconfont icon-tianjia"></i> */}
            {/* <span className="send-btn" onClick={() => this.setState({emoticonVisible: true})}>发送</span> */}
            <span className="send-btn" onClick={() => this.handleSend("text")}>发送</span>
          </div>
        </div>
        <Modal
          visible={visible}
          onClose={() => this.handleClose("visible")}
          className="crc-modal"
        >
          <div className="crc-m-content" onClick={() => this.handleClose("visible")}>
            <img src={imgPath} alt="" />
          </div>
        </Modal>
      </div>
    )
  }
}