<template>
  <view
    class="page-live-room"
    :style="{width:sysInfo.windowWidth+'px',height:liveHeight+'px'}"
  >
    <!-- 直播背景 -->
    <image
      v-if="liveStatus!==1"
      class="bg-img"
      :style="{width:sysInfo.windowWidth+'px',height:liveHeight+'px'}"
      :src="util.addDomain(liveInfo.coverImg)"
      mode=""
    />

    <!-- 小程序或APP直播播放 -->
    <video
      v-if="liveType===2 && liveStatus===1 && (appType==='MP-WEIXIN' || appType==='APP')"
      id="myVideo"
      :style="{width:sysInfo.windowWidth+'px',height:liveHeight+'px'}"
      class="myVideo"
      autoplay
      :enable-progress-gesture="false"
      :src="util.addDomain(liveUrl)"
      :is-live="true"
      :play-strategy="2"
      :controls="false"
    />

    <!--#ifdef H5-->
    <video-player
      v-if="liveType===2 && liveStatus===1"
      ref="videoPlayerRef"
      @play="isVideoInteract=true"
    />
    <img
    v-if="[1,2].includes(liveStatus) && !isVideoInteract"
    class="play-icon"
    src="@/static/images/play-red.png"
    alt=""
    @tap="onPlay"
    >
    <!--#endif-->

    <!-- 播流 -->
    <!-- <live-player
      v-if="liveType===2&& appType==='MP-WEIXIN'"
      id="myLivePlayer"
      :src="liveUrl"
      mode="live"
      autoplay
      @statechange="onStatechange"
      @netstatus="onNetstatus"
    /> -->
    <!-- 推流 -->
    <live-pusher
      v-if="liveType===1 && liveStatus===1 && appType!=='H5'"
      id="myLivePusher"
      ref="myLivePusher"
      :style="{width:sysInfo.windowWidth+'px',height:liveHeight+'px'}"
      :url="liveUrl"
      mode="FHD"
      autoplay
      @statechange="onStatechange"
      @netstatus="onNetstatus"
      @error="onError"
    />

    <!-- 直播未开播|主播还未来|中途离开遮罩 -->
    <view
      v-if="liveStatus!==1"
      class="live-mask"
      :style="{width:sysInfo.windowWidth+'px',height:liveHeight+'px'}"
    >
      <view :class="['live-con',appType==='APP'?'app':'not-app']">
        <text class="live-title">
          {{ liveInfo.name }}
        </text>
        <text
          v-if="liveStatus===0&&!countdownToZero"
          class="live-countdown"
        >
          直播倒计时
        </text>
        <text
          v-if="liveStatus===0&&!countdownToZero"
          class="live-desc"
        >
          {{ `${min}分钟${second}秒` }}
        </text>
        <text
          v-if="countdownToZero"
          class="live-desc"
        >
          {{ liveStatusText }}
        </text>
      </view>
    </view>

    <view
      class="fallback-btn"
      :style="{top:sysInfo.safeArea?.top + 24 + 'px'}"
      @tap="onGoBack"
    />
    <view
      class="live-info-pop"
      :style="{top:sysInfo.safeArea?.top + 10 + 'px'}"
    >
      <img-show
        :img-style="{
          width: '54rpx',
          height: '54rpx',
          borderRadius: '54rpx',
          overflow: 'hidden'
        }"
        :src="liveInfo.shopLogo"
        @handle-tap="onGoShop"
      />
      <view
        class="live-info"
        @handle-tap="onGoShop"
      >
        <text class="shop-name">
          {{ liveInfo.shopName }}
        </text>
        <text class="view-num">
          {{ viewLiveNum }}观看
        </text>
      </view>
      <text
        class="follow-btn"
        @tap="onFollowShop"
      >
        {{ isFollowed?'已关注':'关注' }}
      </text>
    </view>

    <view
      class="bar-box"
      :style="{bottom:sysInfo.safeAreaInsets?.bottom+'px'}"
    >
      <view class="bar-info">
        <!-- 弹幕信息 -->
        <scroll-view
          :class="['barrage-box',{'bgc-img':barrageList.length>0}]"
          :show-scrollbar="false"
          scroll-y
          :scroll-top="scrollTop"
        >
          <view style="height: 100rpx;" />
          <view
            v-for="(barItem,barInx) in barrageList"
            :key="barInx"
            :class="['chat-area-line',{'fl-d-row':(barItem.nickName.length + barItem.content.length)<15}]"
          >
            <view class="msg-detail">
              <!-- userType 0用户 1主播 -->
              <img-show
                v-if="barItem.userType===1"
                :img-style="{
                  width: '40rpx',
                  height: '40rpx',
                  borderRadius: '40rpx',
                  overflow: 'hidden',
                  marginRight: '8rpx'
                }"
                :src="liveInfo.shopLogo"
              />
              <text
                v-for="(uName,uInx) in barItem.nickName"
                :key="`u_${uInx}`"
                :class="[barInx===0?'sys-notice':'username']"
              >
                {{ uName }}
              </text>
              <text class="gap" />
              <text
                v-for="(con,cInx) in barItem.content"
                :key="`c_${cInx}`"
                class="content"
              >
                {{ con }}
              </text>
            </view>
          </view>
        </scroll-view>
        <!-- 当前正在讲解商品弹窗 -->
        <view :class="['explain-prod-pop',{show:explainProdShow&&liveStatus===1}]">
          <view class="prod-img">
            <img-show
              :img-style="{width:'220rpx',height:'220rpx'}"
              :src="explainProdInfo.pic"
              mode=""
            />
          </view>
          <view class="top-flag">
            <view class="live">
              <image
                class="living_icon"
                src="/static/live-broadcast/icon-explain.png"
                mode=""
              />
              <text class="living_txt">
                讲解中
              </text>
            </view>
            <image
              class="close"
              src="/static/live-broadcast/icon_close.png"
              mode=""
              @tap="explainProdShow = false"
            />
          </view>
          <text class="prod-name">
            {{ explainProdInfo.spuName }}
          </text>
          <view class="btn-box">
            <view class="price-con">
              <text class="sign">
                ￥
              </text>
              <text class="txt">
                {{ wxs.floatPrice(explainProdInfo.price) }}
              </text>
            </view>
            <text
              class="btn-txt"
              @tap="onGoBuy(explainProdInfo.spuId)"
            >
              抢
            </text>
          </view>
        </view>
      </view>
      <view class="bar-con">
        <view class="bar-inp">
          <input
            v-model="msgText"
            class="inp-class"
            placeholder-class="place-class"
            type="text"
            maxlength="50"
            :placeholder="inpPlaceholder"
            confirm-type="send"
            :adjust-position="false"
            @confirm="onHandleSend()"
          >
        </view>
        <image
          class="more-prod-btn"
          src="/static/live-broadcast/icon_shopping.png"
          mode=""
          @tap="onShowProdList"
        />
      </view>
    </view>

    <!-- 防止键盘弹起时遮挡输入框 -->
    <view
      v-if="showInput"
      class="inp-box"
      :style="inpStyle"
    >
      <view class="inp-con">
        <input
          v-model="msgText"
          class="inp-class"
          placeholder-class="place-class"
          type="text"
          maxlength="50"
          :placeholder="inpPlaceholder"
          confirm-type="send"
          :adjust-position="false"
          @blur="onBlur"
          @confirm="onHandleSend()"
        >
      </view>
      <text
        class="send-btn"
        @tap="onHandleSend"
      >
        发送
      </text>
    </view>

    <live-prod-list
      v-model="liveProdShow"
      :explain-prod-id="explainProdId"
      :is-anchor="liveType===1"
      :live-status="liveStatus"
      :prod-list="prodList"
      :is-load-all="isLoadAll"
      :is-webview="isWebview"
      @scrolltolower="onScrolltolower"
      @change-explain="onChangeExplain"
    />
  </view>
</template>

<script setup>
import permision from '../../static/js_sdk/permission.js' // 权限
import liveProdList from '../../components/live-prod-list/index.vue'
import { Base64 } from 'js-base64'
import { ref, reactive, computed, nextTick, getCurrentInstance } from 'vue'
import http from '@/utils/http.js'
import util from '@/utils/util.js'
import number from '@/wxs/number.js'
import {
  onLoad,
  onShow,
  onReady,
  onUnload
} from '@dcloudio/uni-app'
// #ifdef H5
import '@/utils/jwx/index.js'
import videoPlayer from '../../components/video-player/index.vue'
// #endif

const wxs = number()

const instance = getCurrentInstance() // 获取组件实例
let isPlay = false // 是否可播放
let roomId = 0 // 直播间id
let curUserId = 0 // 当前用户id
const liveUrl = ref('') // 直播地址
const liveType = ref(1) // 1直播推流 2直播播流
const appType = ref('H5') // 应用类型
const barrageList = ref([{
  nickName: '系统公告：',
  content: '倡导健康的直播环境。若发布违法、违规、低俗等不良信息，我们将会对违规内容及帐号进行封禁处理。'
}]) // 弹幕信息列表
let liveUserId = '' // 当前主播间的主播id
const isWebview = ref(false) // 是否为小程序web-view嵌套
onLoad(options => {
  if (options.isWebview) {
    // 用于小程序web-view的内嵌处理
    isWebview.value = Boolean(options.isWebview)
    const liveWebViewInfo = JSON.parse(options.liveWebViewInfo)
    uni.setStorageSync('cloudToken', liveWebViewInfo.token)
    uni.setStorageSync('cloudUserInfo', liveWebViewInfo.userInfo)
    userType = liveWebViewInfo?.token && liveWebViewInfo?.userInfo ? 1 : 0
  }
  uni.setNavigationBarTitle({
    title: '观看直播'
  })
  liveType.value = +options.liveType // 1直播播流 2直播推流
  roomId = options.roomId || 0
  liveUserId = options.liveUserId || 0
  // #ifdef APP-PLUS
  appType.value = 'APP'
  // #endif
  // #ifdef MP-WEIXIN
  appType.value = 'MP-WEIXIN'
  // #endif

  // 加载页面信息
  onLoadData()

  // 获取缓存的弹幕信息
  if (uni.getStorageSync('cloudBarrageList')) {
    barrageList.value = JSON.parse(uni.getStorageSync('cloudBarrageList'))
    onChangeScrollTop()
  }
})

let userType = ''
const inpPlaceholder = ref('')
// 加载页面信息
const onLoadData = async () => {
  userType = uni.getStorageSync('cloudToken') ? 1 : 0 // 1.用户 0.游客
  inpPlaceholder.value = '跟xxx说点什么...'.replace('xxx', liveType.value === 1 ? '观众' : '主播')
  if (liveType.value === 1) {
    if (appType.value === 'H5' || appType.value === 'MP-WEIXIN') {
      onHandleModal('请前往APP进行直播')
      return
    }
    const checkRes = await checkLive()
    if (!checkRes) {
      return
    }
  }
  onGetLiveInfo() // 获取直播间信息
}

let isCheckPermission = true // 是否检查手机直播相关权限
onShow(() => {
  // 是否重新加载页面数据
  if (uni.getStorageSync('cloudLiveRoomReload')) {
    uni.removeStorageSync('cloudLiveRoomReload')
    const userId = uni.getStorageSync('cloudUserDetails')?.userId
    liveType.value = String(userId) === String(liveUserId) ? 1 : 2
    onLoadData()
  }
  // 检测直播手机权限问题
  // #ifdef APP-PLUS
  if (liveType.value === 1 && isCheckPermission) {
    const type = +uni.getStorageSync('cloudAppType')
    isCheckPermission = false
    // 5.安卓 6.苹果
    if (type === 5) {
      onCheckAndroidPermission()
    } else if (type === 6) {
      onCheckIosPermission()
    }
  }
  // #endif
  if (isPlay && liveStatus.value === 1) {
    videoPlayerRef.value.playVideo()
  }
  if (isPusher) {
    livePusherCtx.stop({
      success: () => {
        livePusherCtx.start()
      },
      fail: () => {
        livePusherCtx.start()
      }
    })
  }
})

const showInput = ref(false)
const inpStyle = reactive({
  position: 'fixed',
  bottom: 0,
  zIndex: 101
})

// 键盘监听的回调
const keyboardListener = res => {
  if (res.height) {
    showInput.value = true
    inpStyle.bottom = res.height + 'px'
  } else {
    showInput.value = false
  }
}
// 窗体发生变化的回调
const windowResizeCallback = res => {
  if (sysInfo.value.windowHeight !== res.size.windowHeight) {
    // 键盘打开了
    showInput.value = true
  } else {
    showInput.value = false
  }
}

const liveHeight = ref(0) // 直播高度
const sysInfo = ref({}) // 设备信息
onReady(() => {
  sysInfo.value = uni.getSystemInfoSync()
  liveHeight.value = sysInfo.value.screenHeight
  // #ifdef H5
  liveHeight.value = sysInfo.value.windowHeight
  uni.onWindowResize(windowResizeCallback) // 监听窗口高度变化
  // #endif
  // #ifndef H5
  uni.onKeyboardHeightChange(keyboardListener) // 监听键盘高度变化
  // #endif
})

onUnload(() => {
  if (liveType.value === 1 && explainProdId.value) {
    // 情况讲解的商品
    getApp().globalData.imSocketTask.send({
      data: JSON.stringify({
        msgType: 2,
        spuId: explainProdId.value,
        explainStatus: 0
      }),
      complete: () => {
        closeWs() // 关闭websocket
      }
    })
  } else {
    closeWs() // 关闭websocket
  }
  pusherTimer && clearTimeout(pusherTimer) // 清除开播倒计时
  liveTimer && clearTimeout(liveTimer) // 清除直播倒计时
  uni.removeStorageSync('cloudBarrageList') // 清除缓存的弹幕信息
  // #ifndef H5
  uni.offKeyboardHeightChange(keyboardListener) // 取消监听键盘高度变化
  // #endif
  // #ifdef H5
  uni.offWindowResize(windowResizeCallback) // 取消监听窗口尺寸变化
  // #endif
  if (isPusher) {
    livePusherCtx?.stop() // 停止推流
  }
})

// 获取直播间信息
const liveInfo = ref({}) // 直播间信息
const liveStatus = ref(0) // 直播状态 0.未开始 1.直播中 2.已结束 3.暂停中 -1.违规下架
const onGetLiveInfo = () => {
  http.request({
    url: '/tmerclub_marketing/ua/live_room/get_live_room_info',
    method: 'GET',
    data: {
      roomId,
      userType // 1.用户 0.游客
    }
  }).then(data => {
    data.coverImg = util.checkFileUrl(data.coverImg) // 直播背景图
    data.shareImg = util.checkFileUrl(data.shareImg) // 主播分享图
    data.feedsImg = util.checkFileUrl(data.feedsImg) // 直播封面图
    data.shopLogo = util.checkFileUrl(data.shopLogo) // 店铺logo
    liveInfo.value = data
    liveStatus.value = data.liveStatus
    handleLiveStatus()
    // 直播倒计时
    onLiveCountdown()
    // 区分游客还是用户 1.用户 0.游客
    if (userType === 1) {
      curUserId = uni.getStorageSync('cloudUserDetails').userId
      queryShopCollection() // 查询店铺是否被关注
    } else {
      curUserId = data.uuid
    }
    getLiveProdList()
    // 重连ws前先关闭之前的ws，防止自己顶号操作
    if (getApp().globalData.imSocketTask) {
      getApp().globalData.imSocketTask.close({
        success: () => {
          getApp().globalData.imSocketTask = null
          openWs()
        },
        fail: () => {
          getApp().globalData.imSocketTask = null
          openWs()
        }
      })
    } else {
      openWs()
    }
  }).catch(err => {
    onHandleModal(err.msg)
  })
}

// 打开websocket
const openWs = () => {
  let wsUrl = ''
  // liveType 1.主播 2.用户
  if (liveType.value === 1) {
    // 主播直播
    wsUrl = `${import.meta.env.VITE_APP_WS_IM_API}/tmerclub_marketing/ua/im/websocket/live/anchor/${Base64.encode(uni.getStorageSync('cloudToken'))}/${curUserId}/${roomId}`
  } else {
    const token = Base64.encode(uni.getStorageSync('cloudToken')) || null
    // 用户观看直播
    wsUrl = `${import.meta.env.VITE_APP_WS_IM_API}/tmerclub_marketing/ua/im/websocket/live/user/${userType}/${token}/${curUserId}/${roomId}`
  }

  getApp().globalData.imSocketTask = uni.connectSocket({
    url: wsUrl,
    complete: () => {}
  })

  // 连接打开事件
  getApp().globalData.imSocketTask.onOpen(() => {
    heartCheck.reset().start() // 成功建立连接后，重置心跳检测
    // 主播开播
    if (liveType.value === 1) {
      liveStatus.value = 1
      onGetPushUrl()
    }
  })

  getApp().globalData.imSocketTask.onMessage((res) => {
    heartCheck.reset().start() // 成功建立连接后，重置心跳检测
    const result = JSON.parse(res.data)
    result.code = Number(result.code)
    if (result.code === 0 && result.data) {
      onHandleWsInfo(result.data)
    }
    // 用户被封禁
    if (result.code === 10) {
      closeWs()
      onHandleModal('当前用户状态异常，请重试')
    }
    // 商品列表变更--出现商品被下架的情况
    if (result.code === 15) {
      pageNum = 1
      getLiveProdList()
    }
    // 账户已在别处登录,退出直播间
    if (result.code === 11) {
      closeWs()
      onHandleModal(result.data)
    }
    // 直播间违规下架
    if (result.code === 12) {
      if (liveType.value === 1) {
        closeWs()
        onHandleModal(result.data)
      } else if (liveType.value === 2) {
        liveStatus.value = -1
        handleLiveStatus()
      }
    }
  })

  // 心跳检测, 每隔一段时间检测连接状态，如果处于连接中，就向server端主动发送消息，来重置server端与客户端的最大连接时间，如果已经断开了，发起重连。
  const heartCheck = {
    timeout: 19000, // 50s发一次心跳，比server端设置的连接时间稍微小一点，在接近断开的情况下以通信的方式去重置连接时间。
    serverTimeoutObj: null,
    reset: function () {
      clearTimeout(this.serverTimeoutObj)
      return this
    },
    start: function () {
      this.serverTimeoutObj = setTimeout(function () {
        if (!getApp().globalData.imSocketTask) {
          return
        }
        if (
          getApp().globalData.imSocketTask.readyState === 1 ||
              getApp().globalData.imSocketTask._webSocket.readyState === 1
        ) {
          getApp().globalData.imSocketTask.send({
            data: JSON.stringify({
              content: 'HEART_BEAT',
              msgType: 0
            })
          })
          heartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测
        } else {
          getApp().globalData.imSocketTask.close()
          openWs()
        }
      }, this.timeout)
    }
  }
}
const closeWs = () => {
  if (getApp().globalData.imSocketTask) {
    getApp().globalData.imSocketTask.close({
      success: () => {
        getApp().globalData.imSocketTask = null
      }
    })
  }
}
// 处理ws返回的信息
// 当前讲解的商品信息
const explainProdId = ref(0) // 当前讲解的商品id
const explainProdInfo = ref({}) // 当前讲解的商品id
const explainProdShow = ref(false) // 是否显示正在讲解商品弹窗
let liveStatusTimer = null // 直播状态定时器
const viewLiveNum = ref(0) // 观看直播人数
const onHandleWsInfo = (dataRes) => {
  // 弹幕信息
  if (dataRes.msgType === 1) {
    barrageList.value.push({
      userType: dataRes.userType, // 0.用户 1.主播
      nickName: dataRes.nickName,
      content: onHandleMsg(dataRes.content)
    })
    uni.setStorageSync('cloudBarrageList', JSON.stringify(barrageList.value))
    onChangeScrollTop()
  }
  // 商品讲解状态变更 explainStatus 1.讲解中 0.未讲解
  if (dataRes.msgType === 2) {
    if (dataRes.explainStatus === 1) {
      explainProdId.value = dataRes.spuId
      explainProdInfo.value = dataRes
      explainProdShow.value = true
    } else {
      explainProdId.value = 0
      explainProdInfo.value = {}
      explainProdShow.value = false
    }
  }
  // 直播状态变更
  if (dataRes.msgType === 3) {
    if (dataRes.liveStatus === 1) {
      clearTimeout(liveStatusTimer)
      liveStatusTimer = setTimeout(() => {
        liveStatus.value = dataRes.liveStatus
        handleLiveStatus()
      }, 3000)
    } else {
      liveStatus.value = dataRes.liveStatus
      handleLiveStatus()
    }
  }

  // 直播观看人数变更
  if (dataRes.msgType === 4) {
    viewLiveNum.value = dataRes.liveUserCount
  }
}

// 弹幕消息处理
const onHandleMsg = (str) => {
  const rex = /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g
  const msgArr = str.replace(rex, 'x').split('')
  const matchArr = str.match(rex)
  msgArr.forEach((item, index) => {
    if (item === 'x') {
      msgArr[index] = matchArr.shift()
    }
  })
  return msgArr
}

// 直播状态处理
const liveStatusText = ref('')
const handleLiveStatus = () => {
  switch (liveStatus.value) {
    case 0:
      // 直播未开始
      onCountdown()
      break
    case 1:
      // 用户观看且直播直播中
      if (liveType.value === 2) {
        onGetPullUrl()
      }
      break
    case 2:
      liveStatusText.value = '直播已结束'
      break
    case 3:
      liveStatusText.value = '主播暂时离开，请稍等片刻...'
      break
      // 直播违规下架
    case -1:
      liveStatusText.value = '直播已结束'
      break
  }
}

// 获取推流
let livePusherCtx = null
let isPusher = false // 是否可推流
const onGetPushUrl = () => {
  http.request({
    url: '/tmerclub_marketing/live/liveRoom/get_push_url',
    method: 'GET'
  }).then(res => {
    liveUrl.value = res
    // 开启直播推流
    nextTick(() => {
      isPusher = true
      livePusherCtx = uni.createLivePusherContext('myLivePusher', instance.proxy)
      livePusherCtx.start() // 开始推流
    })
  }).catch(err => {
    onHandleModal(err.msg)
  })
}

// 获取播流地址
const onGetPullUrl = () => {
  // playBackType 播放类型 1.rtmp 2.flv 3.m3u8
  const playBackType = getApp().globalData.livePlayType
  http.request({
    url: '/tmerclub_marketing/ua/live_room/get_pull_url',
    method: 'GET',
    data: {
      roomId,
      playBackType
    }
  }).then(res => {
    liveUrl.value = res
    // #ifdef H5
    onHandleH5Play()
    // #endif
  }).catch(err => {
    // eslint-disable-next-line no-console
    console.error('获取直播播流失败:', err)
  })
}

// 是否显示直播商品弹窗
const liveProdShow = ref(false)
const onShowProdList = () => {
  liveProdShow.value = !liveProdShow.value
}

const onBlur = () => {
  uni.hideKeyboard()
}
const onHandleSend = () => {
  if (!msgText.value) {
    return
  }
  if (isWebview.value) {
    if (uni.getStorageSync('cloudToken')) {
      sendText()
    } else {
      wx.miniProgram.navigateTo({
        url: '/package-user/pages/user-login/user-login?isWebview=true'
      })
    }
    return
  }
  util.checkAuthInfo(sendText)
}
// 弹幕发送消息
const msgText = ref('')
const sendText = () => {
  const data = {
    msgType: 1,
    nickName: uni.getStorageSync('cloudUserDetails').nickName,
    content: msgText.value
  }
  getApp().globalData.imSocketTask.send({
    data: JSON.stringify(data)
  })
  msgText.value = ''
  onBlur()
}
// 检测直播间是否存在且可开播
const checkLive = () => {
  // eslint-disable-next-line no-unused-vars
  return new Promise((resolve, reject) => {
    http.request({
      url: '/tmerclub_marketing/live/liveRoom/get_user_living_room',
      method: 'GET'
    }).then(res => {
      roomId = res.roomId
      resolve(true)
    }).catch(err => {
      resolve(false)
      onHandleModal(err.msg)
    })
  })
}

// 播放状态变化事件
const onStatechange = () => {
  // console.log('播放状态变化事件', e)
}
// 网络状态通知
const onNetstatus = () => {
  // console.log('网络状态通知', e)
}
// 渲染错误事件
const onError = () => {
  // console.log('渲染错误事件', e)
}

// 安卓手机权限检测
const onCheckAndroidPermission = async () => {
  const perList = [{
    key: 'CAMERA',
    name: '摄像头'
  }, {
    key: 'RECORD_AUDIO',
    name: '麦克风'
  }]
  for (const item of perList) {
    // res 1.已获得授权 0.未获得授权 -1.被永久拒绝权限
    const res = await permision.requestAndroidPermission(`android.permission.${item.key}`)
    if (res === -1) { // '被永久拒绝权限'
      uni.showModal({
        content: `${item.name}权限被永久拒绝权限，请前往手机设置界面打开摄像头权限`,
        success: (res) => {
          if (res.confirm) {
            isCheckPermission = true
            permision.gotoAppPermissionSetting() // 打开App权限设置界面
          } else {
            onGoBack()
          }
        }
      })
      break
    }
  }
}
// 苹果手机权限检查
const onCheckIosPermission = () => {
  for (const item of ['camera', 'record']) {
    permision.judgeIosPermission(item)
  }
}

// 处理h5播放器
const videoPlayerRef = ref(null)
const onHandleH5Play = () => {
  nextTick(() => {
    videoPlayerRef.value?.initVideo(liveUrl.value)
    isPlay = true
  })
}

// 模态框处理
const onHandleModal = (content) => {
  uni.showModal({
    title: '',
    showCancel: false,
    content,
    confirmText: '确定',
    success: () => {
      if (isWebview.value) {
        wx.miniProgram.switchTab({
          url: '/pages/live-broadcast/live-broadcast'
        })
      } else {
        uni.switchTab({
          url: '/pages/live-broadcast/live-broadcast'
        })
      }
    }
  })
}

// 直播倒计时
let liveTimer = null
const onLiveCountdown = () => {
  // 获取当前时间
  const date = new Date()
  const now = date.getTime() // 当前时间
  const end = util.dateToTimestamp(liveInfo.value.endTime) // 设置截止时间
  const leftTime = end - now // 时间差

  if (leftTime >= 0) {
    // 递归每秒调用countTime方法，显示动态时间效果,
    liveTimer = setTimeout(onLiveCountdown, 1000)
  } else {
    if (liveType.value === 1) {
      // 主播端直播结束处理
      closeWs()
      livePusherCtx.stop()
    }
    liveStatus.value = 2
    handleLiveStatus()
    liveTimer && clearTimeout(liveTimer)
  }
}
// 开播倒计时
const countdownToZero = computed(() => Number(hour.value) === 0 && Number(min.value) === 0 && Number(second.value) === 0) // 判断倒计时是否为0
let pusherTimer = null
const hour = ref(0)
const min = ref(0)
const second = ref(0)
const onCountdown = () => {
  // 获取当前时间
  const date = new Date()
  const now = date.getTime() // 当前时间
  const end = util.dateToTimestamp(liveInfo.value.startTime) // 设置截止时间
  const leftTime = end - now // 时间差

  // 定义变量 d,h,m,s保存倒计时的时间
  if (leftTime >= 0) {
    const h = Math.floor(leftTime / 1000 / 60 / 60) // 时
    const m = Math.floor((leftTime / 1000 / 60) % 60) // 分
    const s = Math.floor((leftTime / 1000) % 60)// 秒
    hour.value = h < 10 ? '0' + h : h
    min.value = m < 10 ? '0' + m : m
    second.value = s < 10 ? '0' + s : s
  } else {
    hour.value = '00'
    min.value = '00'
    second.value = '00'
  } // 等于0的时候不调用
  if (countdownToZero.value) {
    liveStatusText.value = '主播在来的路上~'
    pusherTimer && clearTimeout(pusherTimer)
  } else {
    // 递归每秒调用countTime方法，显示动态时间效果,
    pusherTimer = setTimeout(onCountdown, 1000)
  }
}

const onGoBack = () => {
  if (isWebview.value) {
    wx.miniProgram.navigateBack()
  } else {
    // #ifdef H5
    history.back()
    // #endif
    // #ifndef H5
    uni.navigateBack()
    // #endif
  }
}

// 直播间讲解商品状态变更
const onChangeExplain = (spuId) => {
  if (explainProdId.value) {
    getApp().globalData.imSocketTask.send({
      data: JSON.stringify({
        msgType: 2,
        spuId: explainProdId.value,
        explainStatus: 0
      })
    })
  }
  if (explainProdId.value !== spuId) {
    getApp().globalData.imSocketTask.send({
      data: JSON.stringify({
        msgType: 2,
        spuId,
        explainStatus: 1
      })
    })
  }
}

const isLoadAll = ref(false) // 是否加载全部
const onScrolltolower = () => {
  if (pageNum < pages) {
    pageNum++
    getLiveProdList()
  } else {
    isLoadAll.value = true
  }
}
// 获取直播商品列表
let pageNum = 1
const pageSize = 5
let pages = 1
const prodList = ref([])
const getLiveProdList = () => {
  http.request({
    url: '/tmerclub_marketing/ua/live_room/page_living_room_prod',
    method: 'GET',
    data: {
      roomId,
      pageNum,
      pageSize
    },
    dontTrunLogin: true
  }).then(res => {
    pages = res.pages
    if (pageNum === 1) {
      prodList.value = res.list
    } else {
      prodList.value = prodList.value.concat(res.list)
    }
  })
}

// 前往店铺
const onGoShop = () => {
  if (isWebview.value) {
    wx.miniProgram.navigateTo({
      url: '/package-shop/shop-page/shop-index/shop-index?shopId=' + liveInfo.value.shopId
    })
  } else {
    uni.navigateTo({
      url: '/package-shop/shop-page/shop-index/shop-index?shopId=' + liveInfo.value.shopId
    })
  }
}

const isFollowed = ref(false) // 是否已关注
const onFollowShop = () => {
  const shopId = liveInfo.value.shopId
  util.checkAuthInfo(() => {
    http.request({
      url: '/tmerclub_admin/mua/app/userFavorite/add_or_cancel',
      method: 'post',
      data: shopId
    }).then((res) => {
      isFollowed.value = res
    })
  })
}
// 查询店铺是否已收藏
const queryShopCollection = () => {
  const shopId = liveInfo.value.shopId
  http.request({
    url: '/tmerclub_admin/mua/app/userFavorite/ma/is_collection',
    method: 'get',
    data: {
      shopId
    }
  }).then(res => {
    isFollowed.value = res
  })
}

// 购买商品
const onGoBuy = (spuId) => {
  if (liveType.value === 2) {
    if (isWebview.value) {
      wx.miniProgram.navigateTo({
        url: '/pages/detail/detail?spuId=' + spuId
      })
    } else {
      uni.navigateTo({
        url: '/pages/detail/detail?spuId=' + spuId
      })
    }
  }
}
// 弹幕滚动到底部
const scrollTop = ref(1000)
const onChangeScrollTop = () => {
  nextTick(() => {
    scrollTop.value = scrollTop.value + barrageList.value.length * 100
  })
}
const isVideoInteract = ref(getApp().globalData.$isVideoInteract)
const onPlay = () => {
  util.videoInteract()
  isVideoInteract.value = getApp().globalData.$isVideoInteract
  videoPlayerRef.value.playVideo()
}
</script>

<style lang="scss" scoped>
@import "./live-room.scss";
</style>
<style>
.place-class{
  color: rgba(255,255,255,0.6);
}
</style>
