<template>
  <!-- 客服聊天 -->
  <view
    id="input-height"
    class="chat-container page-my-chat"
    :class="{ chatad: modelType }"
    :style="{position:(modelType || fixedFlag)?'static':'fixed'}"
  >
    <view class="content">
      <!-- #ifdef H5 -->
      <view
        class="shop-info"
        @touchmove.stop.prevent="discard"
      >
        <image
          class="back-icon"
          src="@/package-user/static/images/down-arrow.png"
          @tap="backToPre"
        />
        <view
          v-if="shopInfo"
          class="shop-tit"
        >
          <view class="shop-name">
            {{ shopInfo.shopName }}
          </view>
          <view :class="['shop-status', isOnline?'in':'out']">
            {{ isOnline ? $t('chat.onLine') : $t('chat.offLine') }}
          </view>
        </view>
        <view
          v-else
          class="shop-tit"
        >
          {{ sendType === 2 ? $t('chat.MCS') : $t('chat.PCS') }}
          <text :class="['shop-status', isOnline?'in':'out']">
            {{ isOnline ? $t('chat.onLine') : $t('chat.offLine') }}
          </text>
        </view>
      </view>
      <!-- #endif -->
      <scroll-view
        id="input-text"
        class="msg-list"
        scroll-y="true"
        :style="{height: screenHeight+'px'}"
        :scroll-with-animation="scrollAnimation"
        :scroll-top="chatScrollTop"
        @scrolltoupper="changeScollY"
        @scroll="bindscroll"
        @touchstart="hideKeyboard"
        @touchmove="touchMove"
        @touchend="touchEnd"
      >
        <view
          v-if="showRefresh"
          style="width:100%;position:relative;padding:60rpx 0;"
        >
          <view
            class="text-gray"
            style="position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);"
          >
            <view class="flex">
              <view class="lzy-loading" />
            </view>
          </view>
        </view>
        <view
          v-for="(row, index) in msgItems"
          id="index"
          :key="index"
          class="row"
          @touchmove="touchMove"
        >
          <!-- <view
            v-if="index>0&&msgItems[index].employeeId&&msgItems[index-1].employeeId&&msgItems[index].employeeId!==msgItems[index-1].employeeId"
            class="divider-box"
          >
            <text class="divider" />
            <text class="divider-txt">
              以上是{{ msgItems[index-1].nickName || msgItems[index-1].shopName }}客服聊天记录
            </text>
            <text class="divider" />
          </view> -->
          <!-- 用户消息 -->
          <blockquote>
            <view
              v-if="row.timeStr"
              class="topTime"
            >
              {{ row.timeStr }}
            </view>
            <!-- 用户发出的消息 -->
            <view
              v-if="row.source === 2"
              class="my"
            >
              <!-- 左-消息 -->
              <view class="left">
                <!-- 文字消息 -->
                <view
                  v-show="row.employeeUnread"
                  class="unread"
                >
                  {{ $t('chat.read') }}
                </view>
                <view
                  v-show="!row.employeeUnread&&!row.sendFail"
                  class="unread"
                >
                  {{ $t('chat.unRead') }}
                </view>
                <view
                  v-show="!row.employeeUnread&&row.sendFail"
                  class="unread unusual"
                >
                  网络异常，对方可能没接收到该消息
                </view>

                <view
                  v-if="row.type === 0 && !row.prodInfo"
                  :class="['bubble',{'is-unusual':row.sendFail}]"
                >
                  <rich-text :nodes="row.content" />
                </view>
                <!-- 图片消息 -->
                <view
                  v-if="row.type === 1 && !row.prodInfo"
                  :class="['bubble',{'is-unusual':row.sendFail}]"
                  @tap="showPic(row.content)"
                >
                  <img-show
                    :src="row.content"
                    :class-list="['longimage']"
                    img-mode="widthFix"
                  />
                </view>
                <!-- 商品链接 -->
                <view
                  v-if="row.prodInfo"
                  :class="['prod-link',{'is-unusual':row.sendFail}]"
                  @tap="toProdDetail(row.prodInfo,row.prodInfo.orderFlag?1:0)"
                >
                  <view
                    v-if="row.prodInfo.orderFlag"
                    class="prod-number"
                  >
                    {{ $t('chat.orderNumber') }}：{{ row.prodInfo.orderId }}
                  </view>
                  <view class="link-prod prod-no">
                    <img-show
                      :src="row.prodInfo.imgs"
                      :class-list="['img']"
                    />
                    <view class="link-detail">
                      <view class="prod-name">
                        {{ row.prodInfo.prodName || row.prodInfo.spuName }}
                      </view>
                      <view class="prod-price">
                        <text>
                          <text>{{ row.prodInfo.actualTotal ? '￥' : '' }}</text>
                          <text>
                            {{
                              row.prodInfo.actualTotal ? wxs.parsePrice(row.prodInfo.actualTotal)[0] + '.' + wxs.parsePrice(row.prodInfo.actualTotal)[1] : ''
                            }}
                          </text>
                          <text>{{ (row.prodInfo.actualTotal && row.prodInfo.scoreFee) ? '+' : '' }}</text>
                          <text v-if="row.prodInfo.scoreFee">
                            {{ row.prodInfo.scoreFee }} {{ '积分' }}
                          </text>
                        </text>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
              <!-- 右-头像 -->
              <view class="right">
                <image
                  v-if="!row.userHeadUrl"
                  src="@/package-user/static/images/userImg.jpg"
                />
                <image
                  v-else
                  :src="row.userHeadUrl.indexOf('http') > -1 ? row.userHeadUrl : resourcesUrl + row.userHeadUrl"
                  @error="row.userHeadUrl=''"
                />
              </view>
            </view>
            <!-- 平台或者商家发出的消息 -->
            <view
              v-if="(row.source === 0 || row.source === 1)"
              class="other-box"
            >
              <view class="service-name">
                {{ row.nickName || row.shopName }}
              </view>
              <view class="other">
                <!-- 左-头像 -->
                <view class="left">
                  <image
                    :src="shopInfo && shopInfo.shopLogo ? util.addDomain(shopInfo.shopLogo) : customerService"
                    @error="shopInfo.shopLogo=''"
                  />
                </view>
                <!-- 右-用户名称-时间-消息 -->
                <view class="right">
                  <!-- 文字消息 -->
                  <view
                    v-if="row.type === 0"
                    class="bubble"
                  >
                    <text>{{ row.content }}</text>
                  </view>
                  <!-- 图片消息 -->
                  <view
                    v-if="row.type === 1"
                    class="bubble"
                    @tap="showPic(row.content)"
                  >
                    <img-show
                      :src="row.content"
                      :class-list="['longimage']"
                      img-mode="widthFix"
                    />
                  </view>
                </view>
              </view>
            </view>

            <!-- 发送链接 -->
            <view
              v-if="row.source === 3"
              class="link-box"
            >
              <view
                v-if="row.prodInfo.orderFlag"
                class="prod-number"
              >
                {{ $t('chat.orderNumber') }}：{{ row.prodInfo.orderNumber }}
              </view>
              <view
                class="link-prod"
                @tap="toProdDetail(row.prodInfo,row.prodInfo.orderFlag ? row.prodInfo.orderFlag : '')"
              >
                <img-show
                  :src="row.prodInfo.imgs"
                  :class-list="['img']"
                />
                <view class="link-detail">
                  <view class="prod-name">
                    {{ row.prodInfo.prodName }}
                  </view>
                  <view class="prod-price">
                    <text>
                      {{
                        row.prodInfo.price ? '￥' : ''
                      }}{{
                        row.prodInfo.price ? (wxs.parsePrice(row.prodInfo.price)[0] + '.' + wxs.parsePrice(row.prodInfo.price)[1]) : ''
                      }}
                      {{ (row.prodInfo.price && row.prodInfo.scoreFee) ? '+' : '' }}
                      <text v-if="row.prodInfo.scoreFee">
                        {{ row.prodInfo.scoreFee }} {{ '积分' }}
                      </text>
                    </text>
                  </view>
                </view>
              </view>
              <view
                class="link-send"
                @click="sendText(2)"
              >
                {{ $t('chat.sendLink') }} <i class="link-send-right" />
              </view>
            </view>

            <!-- 系统提示: 客服接入/转接、客户离线、用户状态异常-->
            <view
              v-if="(row.source === -1 && row.tipsType) || row.type === 2"
              class="sys-tips"
            >
              <text
                v-if="row.type === 2"
                class="tips-content"
              >
                {{ row.content }}
              </text>
              <text
                v-else
                class="tips-content"
              >
                {{
                  row.tipsType === 1 ? $t('chat.customerOffline') : row.tipsType === 2 ? $t('chat.loginOtherSide') : $t('chat.reLogin')
                }}
              </text>
            </view>
          </blockquote>
        </view>
      </scroll-view>
    </view>
    <view class="bottom-input">
      <!-- 底部输入栏 -->
      <view
        class="input-box"
        @touchmove.stop.prevent="discard"
      >
        <view class="textbox">
          <view
            class="text-mode"
            @tap="chatFocus"
          >
            <view class="box">
              <input
                v-model="textMsg"
                type="text"
                confirm-type="send"
                style="width:100%"
                cursor-spacing="15"
                @confirm="sendText(1)"
                @blur="listeningfocus"
              >
            </view>
          </view>
        </view>
        <view
          class="more"
          @tap="showMore"
        >
          <image
            class="icon add"
            src="@/package-user/static/images/add.png"
          />
        </view>
        <view
          class="send"
          @tap="sendText(1)"
        >
          <view class="btn">
            {{ $t('chat.send') }}
          </view>
        </view>
      </view>

      <!-- 抽屉栏 -->
      <view
        class="popup-layer"
        @touchmove.stop.prevent="discard"
      >
        <!-- 更多功能 相册-拍照-红包 -->
        <view
          class="more-layer"
          :class="{ hidden: hideMore }"
        >
          <view class="list">
            <view
              class="box"
              @tap="chooseImage"
            >
              <view class="icon tupian2" />
            </view>
            <view
              class="box"
              @tap="camera"
            >
              <view class="icon paizhao" />
            </view>
          </view>
        </view>
      </view>
    </view>
    <!-- 未读消息提醒-->
    <view
      v-if="totalUserUnread > 0"
      class="un-read-tips"
    >
      <image
        src="@/package-user/static/images/unread-up.png"
        class="un-read-icon"
      />
      {{ `${totalUserUnread}${$t('newMessage')}` }}
    </view>
    <helang-compress ref="hCompressRef" />
  </view>
</template>

<script setup>
import util from '@/utils/util.js'
import { Base64 } from 'js-base64'
import number from '@/wxs/number'
import customerService from '@/static/images/chat/customer-service.png'

const wxs = number()
const scrollAnimation = ref(false)
const resourcesUrl = ref(import.meta.env.VITE_APP_RESOURCES_URL)

const isOnline = ref(false)// 判断有无在线
// more参数
const hideMore = ref(true)
let sendType = 1 // 发送消息类型(客服类型)  1-平台  2-商家  默认平台
watch(() => hideMore.value, () => {
  if (sendType === 1) {
    uni.setNavigationBarTitle({
      title: `${sendType === 2 ? $t('chat.MCS') : $t('chat.PCS')}  ${isOnline.value ? $t('chat.onLine') : $t('chat.offLine')}`
    })
  }
})
watch(() => isOnline.value, () => {
  uni.setNavigationBarTitle({
    title: `${sendType === 2 ? $t('chat.MCS') : $t('chat.PCS')}  ${isOnline.value ? $t('chat.onLine') : $t('chat.offLine')}`
  })
})

let shopId = null
let prodId = null
let routeQuery = {}
onLoad((option) => {
  routeQuery = option
  shopId = Number(option.shopid)
  prodId = option.prodid
  getSysInfo()
  getUserInfo()
  if (shopId !== 0) {
    // 店铺客服消息
    getShopInfo()
    sendType = 2
  } else {
    /* #ifndef H5 */
    uni.setNavigationBarTitle({
      title: `${sendType === 2 ? $t('chat.MCS') : $t('chat.PCS')}  ${isOnline.value ? $t('chat.onLine') : $t('chat.offLine')}`
    })
    /* #endif */

    /* #ifdef H5 */
    uni.setNavigationBarTitle({
      title: `${sendType === 2 ? $t('chat.MCS') : $t('chat.PCS')}`
    })
    /* #endif */
    shopId = 0
  }
})

onUnload(() => {
  closeWs()
})

onUnmounted(() => {
  if (isShowPreview) {
    uni.closePreviewImage({
      success: () => {
        isShowPreview = false
      }
    })
  }
})

let scollTopTag = ''
const changeScollY = () => {
  scollTopTag = 0
}

const modelType = ref(null)
const softKeyboards = false
const screenHeight = ref(712) // 消息内容盒子默认高度
let oldScreenHeight = null
const screenOnce = 0
/**
 * 获取屏幕高度
 */
const getSysInfo = () => {
  uni.getSystemInfo({
    success: (sysInfo) => {
      // #ifdef H5
      if (sysInfo.platform === 'ios') {
        modelType.value = true
      }
      if (softKeyboards) {
        screenHeight.value = oldScreenHeight
      } else {
        screenHeight.value = sysInfo.screenHeight - 100
        if (!screenOnce) {
          oldScreenHeight = screenHeight.value
        }
      }
      // #endif
      // #ifdef MP-WEIXIN
      screenHeight.value = sysInfo.screenHeight - 105 - sysInfo.statusBarHeight
      oldScreenHeight = screenHeight.value
      // #endif
      // #ifdef APP-PLUS
      screenHeight.value = sysInfo.windowHeight - 100
      oldScreenHeight = screenHeight.value
      // #endif
    }
  })
}

/**
 * 点击外面盒子获取焦点
 */
const chatFocus = () => {
  textareaFocus()
}

/**
 * 返回上一页
 */
const backToPre = () => {
  if (shopId === 0 || prodId) {
    uni.navigateBack({
      delta: 1
    })
  } else {
    uni.navigateBack({
      url: '/pages/message-platform/message-platform'
    })
  }
}

const shopInfo = ref(null)
/**
 * 获取店铺信息
 */
const getShopInfo = () => {
  http.request({
    url: '/mall4cloud_admin/ua/shop_detail/head_info',
    method: 'GET',
    data: {
      shopId
    }
  }).then((res) => {
    shopInfo.value = res
    if (res.shopName == null) {
      res.shopName = '店铺已下线'
      uni.showModal({
        title: '提示',
        content: '店铺已下线',
        showCancel: false
      })
    }
    /* #ifndef H5 */
    const timer = setTimeout(() => {
      uni.setNavigationBarTitle({
        title: `${res.shopName}  ${isOnline.value ? $t('chat.onLine') : $t('chat.offLine')}`
      })
      clearTimeout(timer)
    }, 500)
    /* #endif */

    /* #ifdef H5 */
    uni.setNavigationBarTitle({
      title: res.shopName
    })
    /* #endif */
  })
}

// 判断是否为JSON格式
const isJSON = (str) => {
  if (typeof str == 'string') {
    try {
      JSON.parse(str)
      return true
    } catch (e) {
      return false
    }
  }
}

let current = 1 // 聊天记录页数
let imSocketTask = null
/**
 * 获取聊天记录
 */
const getMsgItems = () => {
  const messageInfo = {
    history: 1,
    current,
    size: 10,
    sendType,
    toId: shopId
  }
  imSocketTask.send({
    data: JSON.stringify(messageInfo)
  })
}

// 获取当前商家在线离线状态
const getOnlineStatus = () => {
  const status = {
    onlineOrOffline: true,
    sendType,
    toId: shopId
  }
  try {
    imSocketTask.send({ data: JSON.stringify(status) })
  } catch (error) {
    uni.showToast({
      title: '连接已断开请刷新一下页面',
      icon: 'none'
    })
  }
}

let userInfo = null
/**
 * 获取用户信息
 */
const getUserInfo = () => {
  http.request({
    url: '/mall4cloud_user/user/ma/user_detail_info',
    method: 'GET',
    data: {},
    dontTrunLogin: true
  }).then((res) => {
    userInfo = res
    openWs()
  })
}

let prodInfo = null
const msgItems = ref([])
const chatScrollTop = ref(0)
/**
 * 获取商品或订单信息并生成相应的链接
 */
const getProdInfo = (id, type) => {
  // type 1 = 商品链接  type 2 = 订单链接
  const data = type === 1 ? { spuId: id } : { orderId: id }
  http.request({
    url: type === 1 ? '/mall4cloud_product/ma/spu/prod_info' : '/mall4cloud_order/my_order/order_detail',
    method: 'GET',
    data
  }).then((res) => {
    let prodInfoPar
    if (type === 1) {
      prodInfoPar = {
        imgs: res.mainImgUrl,
        spuId: res.spuId,
        prodName: res.spuName,
        spuName: res.spuName,
        skuName: res.skuName,
        price: res.priceFee,
        orderType: res.orderType,
        actualTotal: res.priceFee
      }
    } else {
      const orderItem = res.orderItems[0]
      prodInfoPar = {
        imgs: orderItem.pic,
        spuId: orderItem.spuId,
        orderId: routeQuery.orderNumber,
        orderNumber: routeQuery.orderNumber,
        skuName: orderItem.skuName,
        spuName: orderItem.spuName,
        prodName: orderItem.spuName,
        price: orderItem.price,
        actualTotal: res.actualTotal,
        useScore: res.orderScore,
        status: res.status,
        orderType: res.orderType,
        orderFlag: true, // 订单判断
        deliveryType: res.deliveryType
      }
    }

    prodInfo = prodInfoPar

    const msgItem = {
      source: 3, // 表示产品链接
      timestamp: new Date().getTime(),
      toId: shopId,
      prodInfo, // 产品链接详情
      msgType: 0,
      sendType // 1发给平台   2发给商家
    }
    msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
    msgItems.value.push(msgItem)
    nextTick(function () {
      chatScrollTop.value = chatScrollTop.value + 1000 * msgItems.value.length
    })
  })
}

let lockReconnect = false
let loginOtherSide = false // 判断用户是否在别处登录
const totalUserUnread = ref(0)// 有多少条未读新消息
let pages = 1 // 聊天记录页码数
const showRefresh = ref(false) // 是否显示下拉刷新组件
/**
 * 创建ws
 */
// eslint-disable-next-line max-lines-per-function
const openWs = () => {
  imSocketTask = uni.connectSocket({
    url: import.meta.env.VITE_APP_WS_IM_API + '/mall4cloud_im/ua/im/websocket/' +
      Base64.encode(uni.getStorageSync('cloudToken')) + '/' + userInfo.userId, // 仅为示例，并非真实接口地址。
    complete: () => {}
  })

  imSocketTask.onOpen(() => {
    heartCheck.reset().start() // 成功建立连接后，重置心跳检测
    lockReconnect = true
    // 发送信息获取聊天记录
    getMsgItems()
    getOnlineStatus()
  })
  // eslint-disable-next-line max-lines-per-function
  imSocketTask.onMessage((res) => {
    // code 1 是新消息 code 2 是聊天记录 code 3 是转接客服
    // code 10~12是错误信息
    heartCheck.reset().start() // 成功建立连接后，重置心跳检测
    const result = JSON.parse(res.data)
    if (result.code !== '00000') {
      result.code = Number(result.code)
    }
    heartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测
    if (result.code === 10 || result.code === 11 || result.code === 12) {
      // source: -1  系统提示;    tipsType: 1客服不在线    2用户在别处登陆    3无法获取用户信息
      const tipsItem = {
        source: -1,
        tipsType: result.code === 12 ? 1 : result.code === 11 ? 2 : 3
      }
      imSocketTask.close()

      let flag = false
      let delIndex = 0
      msgItems.value.forEach((item, index) => {
        if (item.tipsType === tipsItem.tipsType) {
          flag = true
          delIndex = index
        }
      })
      if (flag) {
        msgItems.value.splice(delIndex, 1)
      }
      msgItems.value.push(tipsItem)
      loginOtherSide = true
      return
    }

    if (!result.data) {
      return
    }

    /**
     * 新的聊天信息
     */
    if (result.code === '00000' || result.code === 4) {
      // 时间转换
      if (msgItems.value.length && result.data !== 'ok') {
        const prevTime = util.tsToDate(msgItems.value[msgItems.value.length - 1].timestamp, 'M月D日 h:m')
        const nowTime = util.tsToDate(result.data.timestamp, 'M月D日 h:m')
        if (prevTime.slice(0, prevTime.indexOf(' ')) === nowTime.slice(0, nowTime.indexOf(' '))) {
          result.data.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
        } else {
          result.data.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
        }
        const timeFlag = util.timeBeApart(msgItems.value[msgItems.value.length - 1].timestamp, new Date().getTime())
        if (timeFlag) {
          delete result.data.timeStr
        }
      }

      // 首次新消息不做添加
      if (result.data !== 'ok') {
        const readed = {
          read: 1,
          msgIds: [result.data.itemId],
          toId: shopId,
          sendType,
          readNoticeEmployeeId: result.data.employeeId
        }
        imSocketTask.send({
          data: JSON.stringify(readed)
        })
      }

      // 接受新传过来的消息，加入到聊天栏
      const msgItem = result.data
      if (msgItem.type === 1) {
        msgItem.content = resourcesUrl.value + msgItem.content
      }
      if (sendType === msgItem.chatType) {
        msgItems.value.push(msgItem)
      }

      shopId = msgItem.shopId ? msgItem.shopId : shopId

      nextTick(function () {
        setTimeout(() => {
          chatScrollTop.value = chatScrollTop.value + 1000 * msgItems.value.length
        }, 300)
      })
    }

    // 聊天记录
    if (result.code === 2) {
      const msgIds = []

      if (!result.data.pages) {
        // 进行商品链接或订单的判断
        if (routeQuery.prodid && current === 1) {
          getProdInfo(routeQuery.prodid, 1)
        }
        if (routeQuery.orderNumber && current === 1) {
          getProdInfo(routeQuery.orderNumber, 2)
        }
        return
      }

      if (result && result.data.pages) {
        result.data.list = result.data.list.reverse()

        // 进行是否是商品链接的判断
        result.data.list.forEach(item => {
          const a = isJSON(item.content)

          if (a && JSON.parse(item.content) instanceof Object) {
            item.prodInfo = JSON.parse(item.content)
          }

          item.timeStr = util.tsToDate(item.timestamp, 'M月D日 h:m')

          if (item.type === 1 && !a) {
            item.content = item.content.indexOf(resourcesUrl.value) === 0 ? item.content : resourcesUrl.value + item.content
          }

          // 往已读列表添加
          if (!item.userUnread) {
            msgIds.push(item.itemId)
            totalUserUnread.value = totalUserUnread.value - 1
          }
        })

        result.data.list.reduce((prev, cur) => {
          // 将时间更换为某某月某某日 要是是当天即去掉月日
          const now = util.tsToDate(prev.timestamp, 'M月D日 h:m')
          const next = util.tsToDate(cur.timestamp, 'M月D日 h:m')
          if (now.slice(0, now.indexOf(' ')) === next.slice(0, next.indexOf(' '))) {
            cur.timeStr = util.tsToDate(cur.timestamp, 'h:m')
          }

          // 历史记录进行时间段显示判断
          if (result.data.list.length > 2) {
            const timeFlag = util.timeBeApart(prev.timestamp, cur.timestamp)
            if (timeFlag) {
              delete cur.timeStr
            }
          }
          return cur
        })
        totalUserUnread.value = result.data.totalUserUnread
      }

      // 将消息变更为已读
      const readed = {
        read: 1,
        msgIds,
        toId: shopId,
        sendType
      }
      imSocketTask.send({
        data: JSON.stringify(readed)
      })

      if (current === 1) {
        msgItems.value = result.data.list

        pages = result.data.pages

        nextTick(function () {
          setTimeout(() => {
            chatScrollTop.value = chatScrollTop.value + 1200 * result.data.list.length
          }, 300)
        })
      }

      if (current !== 1) {
        result.data.list = result.data.list.reverse()
        // 数组反转拼接
        result.data.list.forEach(item => {
          msgItems.value.unshift(item)
        })
      }

      // 进行商品链接或订单的判断
      if (routeQuery.prodid && current === 1) {
        getProdInfo(routeQuery.prodid, 1)
      }
      if (routeQuery.orderNumber && current === 1) {
        getProdInfo(routeQuery.orderNumber, 2)
      }

      uni.stopPullDownRefresh()
      showRefresh.value = false
    }

    /**
     * 未读信息转成已读
     */
    if (result.code === 5) {
      msgItems.value.forEach((item) => {
        item.employeeUnread = 1
      })

      nextTick(function () {
        chatScrollTop.value = chatScrollTop.value + 1000 * msgItems.value.length
      })
    }

    /**
     * 在线离线状态变更
     */
    if (result.code === 16) {
      isOnline.value = result.data.onlineOrOffline
    }

    loginOtherSide = false
  })

  // 心跳检测, 每隔一段时间检测连接状态，如果处于连接中，就向server端主动发送消息，来重置server端与客户端的最大连接时间，如果已经断开了，发起重连。
  const heartCheck = {
    timeout: 19000, // 50s发一次心跳，比server端设置的连接时间稍微小一点，在接近断开的情况下以通信的方式去重置连接时间。
    serverTimeoutObj: null,
    reset () {
      clearTimeout(heartCheck.serverTimeoutObj)
      return heartCheck
    },
    start () {
      heartCheck.serverTimeoutObj = setTimeout(function () {
        if (!imSocketTask) {
          return
        }
        if (imSocketTask.readyState === 1 || imSocketTask._webSocket.readyState === 1) {
          imSocketTask.send({
            data: JSON.stringify({
              sendType,
              content: 'HEART_BEAT',
              msgType: 0,
              toId: shopId
            })
          })
          heartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测
        } else {
          // eslint-disable-next-line no-console
          console.log('断线了~~~')
          imSocketTask.close()
          imSocketTask = null
          lockReconnect = false
          onReconnect()
        }
      }, heartCheck.timeout)
    }
  }

  imSocketTask.onError = () => {
    onReconnect()
  }
}

/**
 * ws关闭
 */
const closeWs = () => {
  imSocketTask.close()
  imSocketTask = null
}

// websock断线重连
const onReconnect = () => {
  if (lockReconnect) return
  lockReconnect = true
  // 没连接上会一直重连，设置延迟避免请求过多
  setTimeout(() => {
    openWs()
    lockReconnect = false
  }, 2000)
}

// 文字消息
const textMsg = ref('')
/**
 * 发送信息
 */
const sendText = (type) => {
  // type 1 = 发送消息  type 2 = 发送商品链接
  if (type === 1) {
    if (textMsg.value === '' || textMsg.value.match(/^\s+$/)) {
      return
    }
  }
  const messageInfo = {
    toId: shopId,
    content: type === 1 ? textMsg.value : JSON.stringify(prodInfo),
    msgType: 0,
    sendType // 0发给平台   1发给商家
  }
  addMessage(messageInfo)
  textMsg.value = ''
}

/**
 * @param {Object} messageInfo
 * 将新发送的消息添加至页面
 */
const addMessage = (messageInfo) => {
  let sendFail = false
  imSocketTask.send({
    data: JSON.stringify(messageInfo),
    fail: () => {
      sendFail = true
    }
  })

  if (messageInfo.msgType === 1) {
    messageInfo.content = resourcesUrl.value + messageInfo.content
  }

  // 发送商品链接需要由JSON格式转换为对象
  const a = isJSON(messageInfo.content)

  if (a && JSON.parse(messageInfo.content) instanceof Object) {
    messageInfo.prodInfo = JSON.parse(messageInfo.content)
  }

  const userInfoPar = userInfo
  const msgItem = {
    userName: userInfoPar.nickName,
    userHeadUrl: userInfoPar.pic,
    employeeUnread: 0,
    sendFail,
    type: messageInfo.msgType,
    source: 2,
    timestamp: new Date().getTime(),
    content: messageInfo.content,
    prodInfo: messageInfo.prodInfo
  }

  if (!msgItems.value.length) {
    msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  } else {
    const prevTime = util.tsToDate(msgItems.value[msgItems.value.length - 1].timestamp, 'M月D日 h:m')

    const nowTime = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
    if (prevTime.slice(0, prevTime.indexOf(' ')) === nowTime.slice(0, nowTime.indexOf(' '))) {
      msgItem.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
    } else {
      msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
    }

    const timeFlag = util.timeBeApart(msgItems.value[msgItems.value.length - 1].timestamp, new Date().getTime())
    if (timeFlag) {
      delete msgItem.timeStr
    }
  }

  msgItem.timestamp = new Date().getTime()

  msgItems.value.push(msgItem)

  nextTick(function () {
    setTimeout(() => {
      chatScrollTop.value = chatScrollTop.value + 1000 * msgItems.value.length
    }, 300)
  })
}

/**
 * 更多功能(点击+弹出)
 */
const showMore = () => {
  if (hideMore.value) {
    openDrawer()
  } else {
    hideDrawer()
  }
}

/**
 * 打开抽屉
 */
const openDrawer = () => {
  hideMore.value = false
  nextTick(() => {
    screenHeight.value = oldScreenHeight - 90
    chatScrollTop.value += 1
  })
}

/**
 * 隐藏抽屉
 */
const hideDrawer = (wxNeedSub, noSliding) => {
  // #ifdef H5
  nextTick(() => {
    screenHeight.value = oldScreenHeight
  })
  // #endif

  // #ifdef MP-WEIXIN || APP-PLUS
  nextTick(() => {
    if (wxNeedSub) {
      screenHeight.value = oldScreenHeight - 90
    } else {
      screenHeight.value = oldScreenHeight
    }
  })
  // #endif
  hideMore.value = true

  //  防止滑动时页面触底
  if (!noSliding) {
    nextTick(() => {
      chatScrollTop.value += 1
    })
  }
}

const fixedFlag = ref(null)
/**
 * 获取焦点，如果不是选表情ing,则关闭抽屉
 */
const textareaFocus = () => {
  // #ifdef H5
  fixedFlag.value = true
  // #endif

  hideDrawer(!hideMore.value)
}

// 失去焦点软键盘变回原样
const listeningfocus = () => {
  fixedFlag.value = null
  hideDrawer(false)
}

/**
 * 选择图片发送
 */
const chooseImage = () => {
  getImage('album')
}

/**
 * 拍照发送
 */
const camera = () => {
  getImage('camera')
}

let startY = ''
let freshStatus = 'more' // 当前刷新的状态
// 触摸开始
const hideKeyboard = (e) => {
  uni.hideKeyboard()
  hideDrawer(false, true)
  startY = e.changedTouches[0].pageY
  freshStatus = 'more'
}

// 触摸结束
const touchEnd = () => {
  if (freshStatus === 'end') {
    // 延迟 500 毫秒，显示 “刷新中”，防止请求速度过快不显示
    current += 1
    if (loginOtherSide) {
      uni.stopPullDownRefresh()
      uni.showToast({
        title: $t('chat.loginOtherSide'),
        icon: 'none'
      })
      showRefresh.value = false
    } else if (current <= pages) {
      freshStatus = 'fresh'
      getMsgItems()
    } else {
      uni.stopPullDownRefresh()
      uni.showToast({
        title: $t('chat.allLoaded'),
        icon: 'none'
      })
      showRefresh.value = false
    }
  } else {
    showRefresh.value = false
  }
}

// 滚轮移动
const bindscroll = (e) => {
  nextTick(() => {
    scollTopTag = e.detail.scrollTop
  })
}

// 触摸移动
const touchMove = (e) => {
  if (scollTopTag !== 0) {
    const query = uni.createSelectorQuery()
    query.select('#input-text').scrollOffset()
    query.exec(res => {
      scollTopTag = res[0].scrollTop
    })
  }
  if (scollTopTag > 0) {
    return
  }
  e.preventDefault()
  const endY = e.changedTouches[0].pageY
  const dis = endY - startY
  // 判断是否下拉
  if (dis <= 0) {
    return
  }
  if (dis > 20) {
    showRefresh.value = true
    if (dis > 50) {
      freshStatus = 'end'
    } else {
      freshStatus = 'more'
    }
  } else {
    showRefresh.value = false
  }
}

let tempFiles = null
/**
 * 上传图片
 * @param type
 */
const getImage = (type) => {
  hideDrawer()
  uni.chooseImage({
    sourceType: [type],
    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
    success: res => {
      tempFiles = res.tempFiles
      uploadImg()
    }
  })
}

let ossList = [] // 上传发送图片
const hCompressRef = ref(null)
/**
 * 上传图片
 */
const uploadImg = () => {
  const fileNames = []
  for (const item of tempFiles) {
    let _type = item.type
    // #ifdef APP-PLUS || MP-WEIXIN
    fileNames.push(item.path)
    // #endif
    // #ifdef H5
    fileNames.push(item.name)
    // #endif

    // #ifndef H5
    const _path = item.path
    _type = _path.substring(_path.lastIndexOf('.'))
    // #endif

    // 限制图片上传格式
    if (_type.indexOf('png') === -1 && _type.indexOf('jpg') === -1 && _type.indexOf('jpeg') === -1) {
      uni.showToast({
        title: '只能是图片类型',
        icon: 'none'
      })
      return
    }
  }
  const params = {
    url: '/mall4cloud_biz/ua/oss/get_batch_pre_sign_url',
    method: 'GET',
    data: {
      fileNames: fileNames.join(',')
    }
  }
  http.request(params).then((res) => {
    ossList = res
    confirmUpload()
  })
}

/**
 * 确认上传
 */
const confirmUpload = () => {
  if (ossList.length <= 0) {
    uni.showToast({
      title: '数据异常，请刷新后重试'
    })
  }
  // 文件上传
  util.awsUpload(ossList, tempFiles).then(() => {
    ossList.forEach((item) => {
      const filePath = item.dir + item.fileName
      onUploadSuccess(filePath)
    })
  })
}

const onUploadSuccess = (filePath) => {
  const messageInfo = {
    toId: shopId,
    content: '/' + filePath,
    sendType,
    msgType: 1
  }
  addMessage(messageInfo)
}

let isShowPreview = false
/**
 * @param {Object} msg
 * 预览图片
 */
const showPic = (msg) => {
  const list = []
  list.push(msg)
  uni.previewImage({
    indicator: 'none',
    current: 0,
    urls: list,
    success: () => {
      isShowPreview = true
    }
  })
}

/**
 * 用于阻止滚动的空方法
 */
const discard = () => {}

/**
 * 链接点击去往商品详情
 */
const toProdDetail = (prodInfo, type) => {
  if (type) {
    uni.navigateTo({
      url: '/package-user/pages/order-detail/order-detail?orderId=' + prodInfo.orderId + '&deliveryType=' + prodInfo.deliveryType
    })
  } else {
    if (prodInfo.spuType !== 3) {
      uni.navigateTo({
        url: '/pages/detail/detail?spuId=' + prodInfo.spuId
      })
    } else {
      uni.navigateTo({
        url: '/package-activities/pages/score-prod-detail/score-prod-detail?spuId=' + prodInfo.spuId
      })
    }
  }
}

</script>

<style lang="scss" scoped>
@use "my-chat";
</style>
