<template>
  <!-- 聊天界面展示https://www.bilibili.com/video/BV1hT4y1P75N?p=22  搭建1和2 -->
  <view class="content" @click="clickContent">
    <view class="top_po">
      <view class="" @click="goback()">
        <u-icon name="arrow-left" color="#fff" size="20"></u-icon>
      </view>
      <view style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
        <!-- 标题居中 -->
        <text style="flex: 1; text-align: center;">{{ info.title }}</text>

        <!-- 右侧内容 -->
        <view style="display: flex; align-items: center;">
          <view v-if="info.conversation == 'Translator'" class="sm-text" @click="chooseSayLang">
            {{ sayLangStr }}
            <u-icon style="margin-top: 6rpx; margin-left: 5rpx;" name="arrow-down" color="#fff" size="12"></u-icon>
          </view>
          <view v-if="info.conversation == 'Translator'" style="margin: 0 15rpx">
            <u-icon name="arrow-rightward" color="#fff" size="20"></u-icon>
          </view>
          <view v-if="info.conversation == 'Translator'" class="sm-text" @click="chooseLang">
            {{ lang }}
            <u-icon style="margin-top: 6rpx; margin-left: 5rpx;" name="arrow-down" color="#fff" size="12"></u-icon>
          </view>
        </view>
      </view>

      <view class="right_top"></view>
    </view>
    <!-- 聊天内容 -->
    <scroll-view class="chat" scroll-y="true" scroll-with-animation="true" :scroll-into-view="scrollToView">
      <view class="chat-main" :style="{paddingBottom:inputh+'px'}">
        <view class="chat-ls" v-for="(item,index) in messagesList" :key="index" :id="'msg'+ index">
          <view class="msg-m msg-right">
            <image class="user-img" :src="imagesUrl+userAvatar"></image>
            <view class="message" v-if="item.inputs.type == 'text'">
              <!-- 文字 -->
              <view class="msg-text">
                <text>{{ item.query }}</text>
              </view>
            </view>
            <view class="message" v-if="item.inputs.type == 'image'">
              <image :src="'data:image/png;base64,'+item.query" class="msg-img" mode="widthFix"></image>
            </view>
            <view class="message" v-if="item.inputs.type == 'voice'" @tap="playVoice(item.filePath)">
              <!-- 音频 -->
              <view class="msg-text voice" :style="{width:item.time*4+'rpx'}">
                <image src="/static/chat/sy.png" class="voice-img"></image>
                {{ item.time }}″
              </view>
            </view>
          </view>
          <view class="msg-m msg-left" v-if="item.answer">

            <image class="user-img" :src="info.icon"></image>
            <view class="msg-text" @click="clickSprinkImage(index)"
                  v-if="item.inputs.type == 'image' && info.conversation == 'Translator'">

              <view class="po_i" v-if="show=='2'&&clickIdx==index">
                <view class="size_" @click="showTxt(item)">text</view>
              </view>
              <view class="po_i" v-if="!item.showImage&&clickIdx==index">
                <view class="size_" @click="showImageFunction (item)">image</view>
              </view>
              <image :src="'data:image/png;base64,'+item.answer" v-if="item.showImage" class="msg-img"
                     mode="widthFix"></image>
              <text v-else>{{ item.imageText }}</text>
            </view>

            <view class="msg-text" @click="clickSprink(index)" id="po_" v-else>
              <view class="po_z" v-if="show=='1'&&clickIdx==index">
                <view class="size_" @click="voiceTxt(item.answer)">Voice</view>

              </view>
              {{ item.answer }}
              <br/>
              <text v-if="item.answerCh">{{ item.answerCh }}</text>
            </view>
          </view>
        </view>
        <span id="bottomId"></span>
      </view>
    </scroll-view>
    <submit @inputs="inputs" @heights="heights" :title="this.info.title"></submit>
    <u-picker :show="langShow" ref="langPicker" :defaultIndex="[11]" :columns="columns" @confirm="langConfirm"
              @cancel="langCancel"></u-picker>
    <u-picker :show="sayLangShow" ref="langPicker" :defaultIndex="[1]" keyName="label" :columns="[sayLangColumns]"
              @confirm="sayLangConfirm"
              @cancel="sayLangCancel"></u-picker>
  </view>
</template>

<script>
import dateTime from './newChat/dateTime.js';
import submit from './newChat/submit.vue';
import config from '@/config'
import {
  startMsgSocket,
  msgSocketConnect,
  sendMsg,
  closeMsgSocket
} from './msgSocket'
import requestChat from '../../utils/requestChat'
import permision from "@/js_sdk/wa-permission/permission.js"
import request from '../../utils/request'
//音频播放
const innerAudioContext = uni.createInnerAudioContext();
// 录音
const recorderManager = uni.getRecorderManager();
export default {
  data() {
    return {
      audioSrc: '', // 用于存储音频的 URL
      clickIdx: null,
      //是否长按事件
      timer: null,//长按计时器
      show: '0',
      columns: [
        ['Arabic-阿拉伯语',
          'German-德语',
          'English-英语',
          'Spanish-西班牙语',
          'French-法语',
          'Hindi-印地语',
          'Indonesian-印度尼西亚语',
          'Italian-意大利语',
          'Japanese-日语',
          'Korean-韩语',
          'Russian-俄语',
          "Chinese-简体中文"
        ]
      ],
      sayLangColumns: [
        {
          value: "zh-CHS",
          label: "Mandarin (China)-普通话（中国）"
        },
        // {
        //   value: 'en',
        //   label: 'Arabic-阿拉伯语',
        // },
        // {
        //   value: 'in',
        //   label: 'Bahasa (Indonesia)-巴哈萨语（印度尼西亚）',
        // },
        // {
        //   value: 'yue',
        //   label: 'Cantonese-粤语',
        // },
        // {
        //   value: 'ca',
        //   label: 'Catalan-加泰隆语',
        // },
        // {
        //   value: 'cs',
        //   label: 'Czech-捷克语',
        // },
        // {
        //   value: 'da',
        //   label: 'Danish-丹麦语',
        // },
        // {
        //   value: 'nl',
        //   label: 'Dutch-荷兰语',
        // },
        // {
        //   value: 'nl-BEL',
        //   label: 'Dutch (Belgium)-荷兰语（比利时',
        // },
        // {
        //   value: 'en-AUS',
        //   label: 'English (Australia)-英语（澳大利亚）',
        // },
        // {
        //   value: 'en-GBR',
        //   label: 'English (GB)-英语（英国）',
        // },
        // {
        //   value: 'en-IND',
        //   label: 'English (India)-英语（印度）'
        // },
        // {
        //   value: 'en-IRL',
        //   label: 'English (Ireland)-英语（爱尔兰）'
        // },
        // {
        //   value: 'en-SCT',
        //   label: 'English (Scotland)-英语（苏格兰）'
        // },
        // {
        //   value: 'en-ZAF',
        //   label: 'English (South Africa)-英语（南非）'
        // },
        {
          value: 'en',
          label: 'English (US)-英语'
        },
        {
          value: 'ja',
          label: 'Japanese (US)-日语）'
        },
      ],
      langShow: false,
      sayLangShow: false,
      sayLang: 'en',
      sayLangStr: 'English',
      lang: 'Chinese',
      imagesUrl: config.imagesUrl,
      msgSocket: null,
      // 反转数据接收
      messagesList: [],
      imgMsg: [],
      scrollToView: '',
      showImageTextIndex: null,
      showImage: true,
      oldTime: new Date(),
      inputh: '60',
      info: {},
      userId: null,
      userAvatar: null,
      firstId: null,
      limit: 20,
      socketId: null,
      // 请求参数
      ajax: {
        rows: 20, //每页数量
        page: 1, //页码
        flag: true, // 请求开关
        sendFlag: false
      },
      scrollId: 'bottomId',
      storeList: 'msgHisList'
    }
  },
  onLoad(option) {
    if (option) {
      let infoData = JSON.parse(option.data)
      let tempInfo = {
        icon: infoData.icon,
        token: infoData.token,
        conversation: infoData.conversation,
        userId: infoData.userId,
        userAvatar: infoData.userAvatar,
        title: infoData.title
      }
      uni.setStorageSync('userId', infoData.userId)
      this.info = tempInfo
      this.userId = infoData.userId
      this.userAvatar = infoData.userAvatar
      this.getMessageByStore()
    }
    this.getRecordsToken()

  },
  components: {
    submit,
  },
  methods: {
    async voiceTxt(text) {
      let res = await request({
        url: 'youDaoApi/tts',
        method: 'post',
        data: {
          q: text,
          voiceName: this.lang,
        }
      })
      this.playBase64Mp3(res.data)
      this.show = false

    },
    showTxt(item) {
      item.showImage = false
      // this.showImageTextIndex = index
      // console.log('触发',this.showImageTextIndex)
      // this.showImage = false
      this.show = false

    },
    showImageFunction(item) {
      item.showImage = true
      // this.showImageTextIndex = index
      // console.log('触发',this.showImageTextIndex)
      // this.showImage = false
      this.show = false

    },
    // 播放 base64 编码的 MP3 文件
    playBase64Mp3(base64Data) {
      innerAudioContext.src = config.baseUrl + base64Data; // 不推荐，仅用于演示
      innerAudioContext.play();
      // 注意：如果你使用的是音频组件，确保在模板中正确绑定和使用它
    },
    clickContent(index) {
      if (this.info.conversation == 'Translator') {
        // 非长按
        this.show = '0'
        this.clickIdx = null
      }
    },
    //点击事件
    clickSprink(index) {
      if (this.info.conversation == 'Translator') {
        // 非长按
        setTimeout(() => {
          this.show = '1'
          this.clickIdx = index
        }, 10); // 延时200毫秒，即0.2秒

      }
    },
    //点击事件
    clickSprinkImage(index) {
      if (this.info.conversation == 'Translator') {
        // 非长按
        setTimeout(() => {
          this.show = '2'
          this.clickIdx = index
        }, 10); // 延时200毫秒，即0.2秒

      }
    },
    // 回调参数为包含columnIndex、value、values
    langConfirm(e) {
      this.lang = e.value[0].split('-')[0]
      this.langShow = false
    },
    langCancel() {
      this.langShow = false
    },
    // 回调参数为包含columnIndex、value、values
    sayLangConfirm(e) {
      this.sayLangStr = e.value[0].label.split('-')[0]
      this.sayLang = e.value[0].value
      this.sayLangShow = false
    },
    sayLangCancel() {
      this.sayLangShow = false
    },
    chooseLang() {
      //选择语言
      this.langShow = true
    },
    chooseSayLang() {
      //选择录音语言
      this.sayLangShow = true
    },
    async getRecordsToken() {
      var result = await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
      console.log(result, 124);
      var strStatus
      if (result == 1) {
        strStatus = "已获得授权"
      } else if (result == 0) {
        strStatus = "未获得授权"

      } else {
        strStatus = "被永久拒绝权限"

      }


    },
    startSocket() {
      this.socketId = this.userId + "_" + Date.now()
      this.msgSocket = startMsgSocket(this.socketId)
      this.msgInfo()
      //追加心跳机制
    },
    msgInfo() {
      if (this.msgSocket) {
        this.msgSocket.onMessage(res => {
          if (this.info.conversation == 'Translator') {
            if (this.messagesList[this.messagesList.length - 1].inputs.type != 'image') {
              this.messagesList[this.messagesList.length - 1].answer = this.messagesList[this
                  .messagesList.length - 1].answer + res.data
              //调用api翻译成中文
              request({
                url: 'chatHttpApi/getChatInfo',
                method: 'post',
                data: {
                  q: this.messagesList[this.messagesList.length - 1].answer,
                  lang: this.lang
                }
              }).then(res => {
                this.$nextTick(() => {
                  this.messagesList[this.messagesList.length - 1].answerCh = this.messagesList[this.messagesList.length - 1].answerCh + res.msg
                })
              })
            } else {
              //将res.data 转为json
              let json = JSON.parse(res.data)
              this.messagesList[this.messagesList.length - 1].answer = this.messagesList[this
                  .messagesList.length - 1].answer + json.answer
              this.messagesList[this.messagesList.length - 1].imageText = this.messagesList[this
                  .messagesList.length - 1].imageText + json.tranContent
            }
            this.goBottom()
            uni.setStorageSync(this.storeList + '_' + this.info.conversation, this.messagesList)
          } else {
            if (res.data.indexOf("conversation_id") > -1) {
              uni.setStorageSync(this.info.conversation, JSON.parse(res.data).conversation_id);
            } else if (res.data.indexOf("workflow_finished") > -1) {
              //代表结束
              uni.setStorageSync(this.storeList + '_' + this.info.conversation, this.messagesList)

            } else {
              this.messagesList[this.messagesList.length - 1].answer = this.messagesList[this
                  .messagesList.length - 1].answer + res.data
              this.goBottom()
            }
          }


        })
      }
    },
    //缓存中获取历史消息
    getMessageByStore() {
      let tempList = uni.getStorageSync(this.storeList + '_' + this.info.conversation) || []
      if (tempList && tempList.length > 30) {
        //截取最新的30条
        this.messagesList = tempList.slice(-30);
      } else {
        this.messagesList = tempList
      }

      // 数据挂载后执行，不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
      this.$nextTick(() => {
        this.$forceUpdate()
        // 设置当前滚动的位置
        this.scrollToView = this.scrollId;
      })
    },
    // 获取历史消息
    getMessage() {

      if (!uni.getStorageSync(this.info.conversation)) {
        return;
      }
      console.log(uni.getStorageSync(this.info.conversation), 136);
      let url = 'v1/messages?user=' + this.userId + '&conversation_id=' + uni.getStorageSync(this.info
          .conversation) + '&limit=' + this.limit
      if (this.firstId) {
        url = url + "&first_id=" + this.firstId
      }
      let that = this
      let get = async () => {
        that.ajax.flag = false;
        let res = await requestChat({
          url: url,
          method: 'get',
          token: that.info.token
        })
        let data = res.data
        // 获取待滚动元素选择器，解决插入数据后，滚动条定位时使用。取当前消息数据的第一条信息元素
        console.log(res, 144);
        for (var i = 0; i < data.length; i++) {
          if (i == 0) {
            that.firstId = data[i].id
          }
          that.messagesList.push(data[i])
        }
        that.$set(that.messagesList, that.messagesList.length - 1, that.messagesList[that.messagesList
            .length - 1])
        // 数据挂载后执行，不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
        that.$nextTick(() => {
          that.$forceUpdate()
          // 设置当前滚动的位置
          that.scrollToView = this.scrollId;
        })

      }
      get();
    },
    goback() {
      uni.navigateBack()
    },
    changeTime(date) {
      return dateTime.dateTime1(date);
    },
    // 进行图片的预览
    previewImg(e) {
      let index = 0;
      for (let i = 0; i < this.imgMsg.length; i++) {
        if (this.imgMsg[i] == e) {
          index = i;
        }
      }
      console.log("index", index)
      // 预览图片
      uni.previewImage({
        current: index,
        urls: this.imgMsg,
        longPressActions: {
          itemList: ['发送给朋友', '保存图片', '收藏'],
          success: function (data) {
            console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
          },
          fail: function (err) {
            console.log(err.errMsg);
          }
        }
      });
    },
    //音频播放
    playVoice(e) {
      console.log(e);
      innerAudioContext.src = e;

      innerAudioContext.play(() => {
        console.log('开始播放');
      });
    },
    //地图定位
    covers(e) {
      let map = [{
        latitude: e.latitude,
        longitude: e.longitude,
        iconPath: '/static/chat/sy.png'
      }]
      return (map);
    },
    //跳转地图信息
    openLocation(e) {
      uni.openLocation({
        latitude: e.latitude,
        longitude: e.longitude,
        name: e.name,
        address: e.address,
        success: function () {
          console.log('success');
        }
      });
    },
    //接受输入内容
    inputs(inputData) {
      console.log(inputData, 220);
      let that = this;
      if (this.msgSocket) {
        closeMsgSocket(this.msgSocket);
        this.msgSocket = null
      }

      this.startSocket()
      let typeStr = "text"
      let msgItem = {
        "inputs": {
          "type": typeStr
        },
        "query": inputData.message,
        "response_mode": 'streaming',
        "conversation_id": uni.getStorageSync(this.info.conversation) || null,
        "user": this.userId,
        'token': this.info.token,
        'answer': '',
        'answerCh': '',
        'showImageTextIndex': '',
        'showImage': '',
        'imageText': '',
        'time': inputData.time,
        'type': '',
        'filePath': inputData.filePath,
      };
      if (this.info.conversation == 'Translator') {
        msgItem.response_mode = 'blocking'
        msgItem.inputs.lang = this.lang
      }
      if (inputData.type == 0) {
        msgItem.inputs.type = "text"
      } else if (inputData.type == 1) {
        typeStr = "image"
        msgItem.inputs.type = "image"
        msgItem.showImage = true
        msgItem.query = inputData.base64
      } else if (inputData.type == 2) {
        typeStr = "voice"
        msgItem.inputs.type = "voice"
        msgItem.query = inputData.base64
      }
      this.messagesList.push(msgItem);
      // 数据挂载后执行，不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
      this.goBottom()
      //时间间隔处理
      let requestData = {
        "inputs": {
          "type": typeStr
        },
        "query": inputData.message,
        "response_mode": 'streaming',
        "conversation_id": uni.getStorageSync(this.info.conversation) || null,
        "user": this.userId,
        'token': this.info.token,
        'answer': '',
        'socketId': this.socketId,
      };
      if (this.info.conversation == 'Translator') {
        requestData.response_mode = 'blocking'
        requestData.inputs.lang = this.lang
        requestData.inputs.sayLang = this.sayLang
      } else if (this.info.conversation == 'Trip') {
        if (requestData.inputs.type == 'image') {
          requestData.query = "描述图片"
          // requestData.inputs = {}
          requestData.files = [
            {
              "type": "image",
              // "type": "image/jpeg",
              "transfer_method": "local_file",
              "url": '',
              "upload_file_id": inputData.message
            }
          ]
        }
        setTimeout(() => {
          sendMsg(that.msgSocket, JSON.stringify(requestData))
          requestData.query = inputData.base64
        }, 500)

        return
      }
      setTimeout(() => {
        sendMsg(that.msgSocket, JSON.stringify(requestData))

      }, 500)
    },
    //输入框高度
    heights(e) {
      console.log("高度:", e)
      this.inputh = e;
      this.goBottom();
    },
    // 滚动到底部
    goBottom() {
      this.scrollToView = '';
      this.$nextTick(() => {

        // 设置当前滚动的位置
        this.scrollToView = this.scrollId;
        this.$forceUpdate()
      })
    }
  }
}
</script>

<style lang="scss">
page {
  height: 100%;
}

#po_ {
  position: relative;
}

.po_z {
  position: absolute;
  top: -60px;
  left: 0px;
  box-sizing: border-box;
  padding: 10px;
  height: 50px;
  background: #3d3d3d;
  display: flex;
  align-items: center;

  color: #fff;
  border-radius: 8px;
}

.po_i {
  position: absolute;

  left: 0px;
  top: -55px;
  box-sizing: border-box;
  padding: 10px;
  height: 50px;
  background: #3d3d3d;
  display: flex;
  align-items: center;

  color: #fff;
  border-radius: 8px;
}

.size_ {
  margin-right: 10px;
}

.content {
  height: 100%;
  background-color: rgba(244, 244, 244, 1);
}

.top_po {
  position: fixed;
  z-index: 9999;
  width: 750rpx;
  height: 180rpx;
  box-sizing: border-box;
  padding-top: 80rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: bold;
  font-size: 36rpx;
  color: #FFFFFF;
  padding-left: 30rpx;
  padding-right: 30rpx;
  left: 0px;
  top: 0px;
  background: #32714f;
  overflow: hidden;
}

.right_top {
  width: 20px;
  height: 20px;
}

.chat {
  height: 90%;
  margin-top: 180rpx;
  margin-bottom: 30rpx;

  .chat-main {
    padding-left: 32rpx;
    padding-right: 32rpx;
    padding-top: 20rpx;
    // padding-bottom: 120rpx;  //获取动态高度
    display: flex;
    flex-direction: column;
  }

  .chat-ls {
    .chat-time {
      font-size: 24rpx;
      color: rgba(39, 40, 50, 0.3);
      line-height: 34rpx;
      padding: 10rpx 0rpx;
      text-align: center;
    }

    .msg-m {
      display: flex;
      padding: 20rpx 0;

      .user-img {
        flex: none;
        width: 80rpx;
        height: 80rpx;
        border-radius: 20rpx;
      }

      .message {
        flex: none;
        max-width: 480rpx;
      }

      .msg-text {
        max-width: 540rpx;
        font-size: 32rpx;
        color: rgba(39, 40, 50, 1);
        line-height: 44rpx;
        padding: 18rpx 24rpx;
        white-space: pre-wrap;
        word-wrap: break-word;
        position: relative;
      }

      .msg-img {
        max-width: 400rpx;
        border-radius: 20rpx;
      }

      .msg-map {
        background: #fff;
        width: 464rpx;
        height: 284rpx;
        overflow: hidden;

        .map-name {
          font-size: 32rpx;
          color: rgba(39, 40, 50, 1);
          line-height: 44rpx;
          padding: 18rpx 24rpx 0 24rpx;
          //下面四行是单行文字的样式
          display: -webkit-box;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 1;
          overflow: hidden;
        }

        .map-address {
          font-size: 24rpx;
          color: rgba(39, 40, 50, 0.4);
          padding: 0 24rpx;
          //下面四行是单行文字的样式
          display: -webkit-box;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 1;
          overflow: hidden;
        }

        .map {
          padding-top: 8rpx;
          width: 464rpx;
          height: 190rpx;
        }
      }

      .voice {
        // width: 200rpx;
        min-width: 100rpx;
        max-width: 400rpx;
      }

      .voice-img {
        width: 28rpx;
        height: 36rpx;
      }
    }

    .msg-left {
      flex-direction: row;

      .msg-text {
        max-width: 540rpx;
        margin-left: 16rpx;
        background-color: #fff;
        border-radius: 0rpx 20rpx 20rpx 20rpx;
        white-space: pre-wrap;
        word-wrap: break-word;
      }

      .ms-img {
        margin-left: 16rpx;
      }

      .msh-map {
        margin-left: 16rpx;
        border-radius: 0rpx 20rpx 20rpx 20rpx;
      }

      .voice {
        text-align: right;

      }

      .voice-img {
        float: left;
        transform: rotate(180deg);
        width: 28rpx;
        height: 36rpx;
        padding-bottom: 4rpx;
      }
    }

    .msg-right {
      flex-direction: row-reverse;

      .msg-text {
        max-width: 540rpx;
        margin-right: 16rpx;
        background-color: rgba(255, 228, 49, 0.8);
        border-radius: 20rpx 0rpx 20rpx 20rpx;
        white-space: pre-wrap;
        word-wrap: break-word;
      }

      .ms-img {
        margin-right: 16rpx;
      }

      .msh-map {
        margin-left: 16rpx;
        border-radius: 20rpx 0rpx 20rpx 20rpx;
      }

      .voice {
        text-align: left;

      }

      .voice-img {
        float: right;
        padding: 4rpx;
        width: 28rpx;
        height: 36rpx;
      }
    }
  }
}

.sm-text {
  font-size: 12px;
  margin-left: 5px;
  display: flex;
  align-items: center;
  line-height: 29px;
}
</style>
