<template>
  <div align="center" class="rtc-page cover-bg" :style="{height: pageData.height + 'px'}">
    <!-- video 容器 -->
    <div class="video-wrapper" id="videoRef" :style="{width: pageData.videoWidth + 'px', height: pageData.videoHeight + 'px'}"></div>
    
    <!-- 三menu键 -->
    <div id="foot-menu-wrap" :style="`height: ${pageData.footMenuHeight}px`">
      <div @click.stop="sendKey(187)"><van-icon name="wap-nav" size="24px"/></div>
      <div @click.stop="sendKey(3)"><van-icon name="wap-home-o" size="24px"/></div>
      <div @click.stop="sendKey(4)"><van-icon name="arrow-left" size="24px"/></div>
    </div>

    <!-- 悬浮按钮 -->
    <FloatBtn :width="pageData.width" :height="pageData.height" :latency="rtcNetwork.currentRoundTripTime" @onClick="levitatedSphereVisible = true"/>

    <!-- 左侧popup -->
    <LeftMenuPopup
      ref="leftMenuPopupRef"
      :engine="engine"
      :userCardId="activeCloud.userCardId"
      :levitatedSphereVisible.sync="levitatedSphereVisible"
      :latency="rtcNetwork.currentRoundTripTime"
      :groupList="groupList"
      :cloudList="cloudList"
      :mealTypeObj="mealTypeObj"
      :imgFun="imgFun"
      @funcHandle="funcHandle"
      @changeCloud="changeCloudHandle"
      @exit="exit"
    />
    
    <!-- 右侧popup -->
    <!-- <RightPopup ref="rightPopupRef" :engine="engine" :userCardId="activeCloud.userCardId" :levitatedSphereVisible.sync="levitatedSphereVisible" @shearplate="shearplate" @exit="exit"/> -->

    <!-- 输入并复制到粘贴板 -->
    <InputCopy ref="inputCopyRef" @openPasteboard="openPasteboard"/>

    <!-- 云机内部的粘贴板内容 -->
    <CloudPhoneClipboard ref="cloudPhoneClipboardRef"/>

    <!-- 超时无操作 -->
    <TimeoutNoOps ref="timeoutNoOpsRef" />

    <!-- 计时卡计时 | 计费规则 | 应用推荐 -->
    <TimeBalance ref="timeBalanceRef" :parametersData="parametersData" :userCardId="activeCloud.userCardId" :userCardType="parametersData.userCardType" @downline="$refs.rightPopupRef.downline()"/>
  </div>
</template>

<script>
import meta from './config/meta.js';
import request from './config/request.js';
import logReport from './config/logReport.js';
import publicMixin from './mixins/public.js';
import * as uni from '../../static/static/js/uni.webview.1.5.2.js';

import FloatBtn from './components/FloatBtn.vue';
import RightPopup from './components/RightPopup.vue';
import LeftMenuPopup from './components/LeftMenuPopup.vue';
import InputCopy from './components/InputCopy.vue';
import CloudPhoneClipboard from './components/CloudPhoneClipboard.vue';
import TimeoutNoOps from './components/TimeoutNoOps.vue';
import TimeBalance from './components/TimeBalance.vue';

/**
 * @description: 判断当前页面运行环境
 * @return {Object} 返回当前页面运行环境
 */
 const isBrowserEnvironment = function() {
  // 判断是否在浏览器环境中
  const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';

  // 判断是否在微信环境中
  const isWechat = /MicroMessenger/i.test(navigator.userAgent);

  // 判断是否在微信小程序的 web-view 中
  const isMiniProgramWebview = isWechat && /miniProgram/i.test(navigator.userAgent);

  // 判断是否是 iPhone 设备
  const isIPhone = /iPhone/i.test(navigator.userAgent);

  // 判断是否是顶级窗口（不是嵌套在 iframe 中）目前只有ios的浏览器中才会是顶级窗口
  const isTopWindow = window.parent === window.self;

  return {
    isBrowser, // 是否在浏览器环境中
    isWechat, // 是否在微信环境中
    isMiniProgramWebview, // 是否在微信小程序的 web-view 中
    isIPhone, // 是否是 iPhone 设备
    isTopWindow, // 是否是顶级窗口
  };
}

export default {
  auth: false,
  name: 'webRTC',
  layout: 'cloudPhone',
  components: {
    FloatBtn,
    RightPopup,
    InputCopy,
    CloudPhoneClipboard,
    TimeoutNoOps,
    TimeBalance,
    LeftMenuPopup,
  },
  head() {
    return {
      title: '云手机',
      meta: [ ...meta ],
      script: [
        {
          // ./ 路径指向nuxt.config.js同级目录的static文件夹
          src: './rtcEngine/config/js/SDK.min.js', // sdk 2.0文件
          type: 'text/javascript',
          async: false,
          defer: false,
          onload: '$_script_loadHandler()', // 加载成功回调created生命周期中定义的方法
          onerror: '$_script_errHandler()', // 加载失败回调created生命周期中定义的方法
        },
        // {
        //   // ./ 路径指向nuxt.config.js同级目录的static文件夹
        //   src: './static/js/uni.webview.1.5.2.js', // uniapp webview 1.5.2文件
        //   type: 'text/javascript',
        //   async: true,
        //   defer: false,
        //   onload: '$_script_uni_loadHandler()', // 加载成功回调created生命周期中定义的方法
        // }
      ]
    }
  },
  mixins: [publicMixin],
  data() {
    return {
      // 日志上报实例
      logReportObj: null,
      // SDK加载状态
      sdkLoadStatus: 'loading', // sdk 加载状态 [loading|success|error]
      // 页面数据
      pageData: {
        width: 0, // 页面宽度
        height: 0, // 页面高度
        footMenuHeight: 40, // 底部菜单高度
        videoWidth: 0, // 视频宽度
        videoHeight: 0, // 视频高度
      },
      // 是否支持webRTC
      isSupportRtc: !!(
        typeof RTCPeerConnection !== 'undefined' &&
        typeof RTCIceCandidate !== 'undefined' &&
        typeof RTCSessionDescription !== 'undefined'
      ),
      // url 问号后的参数
      parametersData: {
        /**
         * @description: 传递的参数
         * @param {String} record 数据id
         * @param {Number} userCardId 必传 云机的id
         * @param {String} mealType 云机套餐类型 eg: VIP、STARBALL...
         * @param {Number} sourceType 云机来源： 0：购买  1试用 2:免费激活码 3:免费活动抽奖 4：ar app注册 5：9.9元套餐年卡 ',
         * @param {Number} userCardType 必传 云机的类型  0 普通套餐 1、2、3：年卡、普通计时、自动续费普通计时 
         * @param {Number} validTime 卡的有效期
         * @param {String} rm 卡所在的机房
         * @param {Number} isShowCountdown 是否显示倒计时 0：否 1：是
         * @param {Number} isShowRule 是否显示规则 0：否 1：是
         * @param {Number} timingStatus 卡的计时状态 0：停止计时 1：开始计时 2:待确认开始计时"
         * @param {String} isFirstConnect 是否是首次连接
         * @param {Number} authPhone  0自身购买的云手机 1获取得到的云手机
         * @param {String} username 用户名
         * @param {String} token 必传 token
         * @param {Number} isTips 必传 是否显示提示 0：否 1：是
         * @param {Number} isWeixin 必传 是否是微信小程序环境 0：否 1：是
         * @param {String} merchantSign 必传 商户标识
         */
      },

      // 当前使用的云机数据
      activeCloud: {},

      // 卡的连接信息
      connectData: {},
      // 云手机引擎 播放器实例
      engine: {},
      // webRtc网络分析数据
      rtcNetwork: {
        currentRoundTripTime: 0, // 当前往返时间(网络延迟)
      },
      doConnectDirectivesWs: null, // 云手机指令通道
      doConnectDirectivesIntervalerPing: null, // 业务通道定时标识 云手机指令通道心跳
      doConnectDirectivesRequestNum: 1, // 业务通道重连次数
      doConnectDirectivesRequestNumMax: 6, // 业务通道重连次数上限

      // 右侧popup显隐
      levitatedSphereVisible: false,
    }
  },
  // 页面初始化后触发
  async fetch() {
    // 获取页面传递参数
    this.parametersData = this.$route.query;

    // 获取用户所有云机列表
    await this.getCloudList();

    // 获取当前云机信息
    this.activeCloud = this.cloudList.find(item => item.userCardId === +this.parametersData.userCardId) ?? {};

    // 获取所有云机套餐信息
    await this.getMealIconInfo();
    // 获取云机分组
    await this.getCloudGroupId();

    if(this.sdkLoadStatus === 'success') {
      // 开始运行程序
      if(Object.keys(this.activeCloud).length) {
        this.start(this.activeCloud);
      }else {
        this.$toast('云手机不存在');
      }
    }else {
      console.log('SDK加载失败');
      this.$toast('加载失败');
    }
  },
  computed: {
    // 是否为微信浏览器环境
    isWeChatBrowser() {
      return this.$userAgent.isWx;
    },
  },
  created() {
    // 设置html标签的背景为黑色
    document.body.style.background = '#000';

    // 定义全局变量 用于监听sdk加载状态
    window.$_script_loadHandler = async ()=> {
      console.log('$_script_loadHandler: SDK加载成功');
      this.sdkLoadStatus = 'success';
    };

    window.$_script_errHandler = ()=> {
      console.log('SDK加载失败');
      this.sdkLoadStatus = 'error';
    }
  },
  mounted() {
    // 获取窗口尺寸
    this.getInitSize();
    window.onresize = () => {
        console.log('窗口尺寸变化');
        this.getInitSize()
    };
    // 初始化页面监听事件
    this.initListener();
  },
  // 页面销毁前触发
  beforeDestroy() {
    // 关闭通道
    this.closeChannel();
    // 销毁页面监听事件
    this.destroyListener();
  },
  methods: {
    // 初始化页面监听事件
    initListener() {
      // 禁止双击缩放
      document.addEventListener('dblclick', this.preventDefault);
      // 添加监听 页面显示或隐藏 事件
      document.addEventListener('visibilitychange', this.visibilitychanged);
    },
    // 销毁页面监听事件
    destroyListener() {
      // 允许双击缩放
      document.removeEventListener('dblclick', this.preventDefault);
      // 移除监听 页面显示或隐藏 事件
      document.removeEventListener('visibilitychange', this.visibilitychanged);
    },
    // 阻止默认事件
    preventDefault(e) {
      e.preventDefault();
    },
    // 监听 页面显示或隐藏 执行的函数
    visibilitychanged() {
      // 获取当前环境
      const env = isBrowserEnvironment();

      // 获取当前页面的可见性状态
      const visibilityState = document.visibilityState;

      if (visibilityState === 'visible') {
        // 页面显示时的逻辑
        // 网页重载
        if (env.isBrowser && env.isTopWindow && env.isIPhone) {
          location.reload();
        }
      } else if (visibilityState === 'hidden') {
        // 页面隐藏时的逻辑
        // video.pause();
      } else if (visibilityState === 'prerender') {
        // 页面预渲染时的逻辑
        console.log('页面处于预渲染状态');
      } else if (visibilityState === 'unloaded') {
        // 页面即将卸载时的逻辑 移除监听
        document.removeEventListener('visibilitychange', this.visibilitychanged);
      }
    },
    // 获取初始化尺寸
    getInitSize() {
      // 获取窗口尺寸
      this.pageData.height = window.innerHeight;
      this.pageData.width = window.innerWidth;

      // 计算视频尺寸 webRTC需要做成16:9的画面
      let videoWidth = this.pageData.width;
      let videoHeight = this.pageData.height - this.pageData.footMenuHeight;

      // 计算当前视口的宽高比
      const currentRatio = videoWidth / videoHeight;
      console.log(`当前视口的宽高比: ${currentRatio}`);

      // 9:16 的目标比例
      const targetRatio = 9 / 16;

      // 判断当前视口的宽高比与目标比例的关系
      if (currentRatio > targetRatio) {
        // 当前视口的宽高比大于目标比例，说明宽度“过宽”，需要以高度为基准
        console.log("当前视口宽度过宽，应以高度为基准调整宽度");
        this.pageData.videoWidth = videoHeight * targetRatio;
        this.pageData.videoHeight = videoHeight;
        console.log(`1目标: 宽${this.pageData.videoWidth},高${this.pageData.videoHeight}`);
      } else {
        // 当前视口的宽高比小于目标比例，说明高度“过高”，需要以宽度为基准
        console.log("当前视口高度过高，应以宽度为基准调整高度");
        this.pageData.videoWidth = videoWidth;
        this.pageData.videoHeight = videoWidth / targetRatio;
        console.log(`2目标: 宽${this.pageData.videoWidth},高${this.pageData.videoHeight}`);
      }
    },
    // 获取卡的信息
    async getConnectData({isWeixin, merchantSign}) {
      let userCardId = this.activeCloud.userCardId;
      try {
        // 设置上报参数
        this.logReportObj.setParams({userCardId});

        let isWx = this.$userAgent.isWx;
        let clientType = (+isWeixin || isWx) ? 'wx' : undefined;

        // 设置上报参数
        this.logReportObj.setParams({userCardId});
        clientType && this.logReportObj.setParams({clientType});

        const res = await this.$axios.$post('/resources/user/cloud/connect', { userCardId }, {
          headers: {
            merchantSign,
          },
        });
        if (!res.success) {
          // 设置日志 推流状态为失败,和链接状态
          this.logReportObj.setParams({plugFowStatus: 2, linkWay: this.logReportObj.RESPONSE_CODE[res.status] || 0, linkEndTime: this.logReportObj.formatDate(new Date())});

          // 日志上报
          this.logReportObj.collectLog(
            `接口获取数据失败:
            url: /api/resources/user/cloud/connect
            method: post
            参数: ${JSON.stringify({ userCardId })}
            响应: ${JSON.stringify(res)}`
          );

          // res.status状态码枚举值 0: 正常
          const statusEnum = {
            // 5200：RBD资源挂载中
            5200: '网络异常，请稍后重试',
            // 入使用排队9.9，年卡
            5220: '云手机正在一键修复中',
            5203: '正在排队中，请稍等',
            // 9.9年卡连接异常，重新进入排队
            5204: '云机异常，正在为你重新分配云机',
            5228: '卡的网络状态为差',
            5229: '接口返回链接信息缺失',
          };
          // NOTE 这里可设置重连机制, 重连次数上限6次, 每次重连间隔3秒, 暂不做重连

          // 提示错误信息
          this.$toast(statusEnum[res.status] || '网络异常，请稍后重试');
          return Promise.reject(new Error(statusEnum[res.status] || '网络异常，请稍后重试'));
        }
        return res.data;
      }catch (error) {
        // 设置上报参数
        this.logReportObj.setParams({linkWay: 4, plugFowStatus: 2, linkEndTime: this.logReportObj.formatDate(new Date())});
        // 日志上报
        this.logReportObj.collectLog(
          `接口获取数据失败:
          url: /api/resources/user/cloud/connect
          method: post
          参数: ${JSON.stringify({ userCardId })}
          响应: ${JSON.stringify(error)}`
        );
        console.log('error connectAxios:', error);
        return Promise.reject(error);
      }
    },
    // 判断卡的连接方式
    async judgeConnectType(cardData) {
      try {
        // 设置上报参数
        this.logReportObj.setParams({videoType: cardData.videoCode.toLowerCase(), resourceId: cardData.resourceId});

        // 不支持webRTC跳转到指定的页面进行拉流
        if (!cardData.isWebrtc) {
          // 关闭日志上报
          this.logReportObj?.destroy();

          // 跳转指定页面
          location.replace(`${location.origin}/h5/webRtcYJ/WXtrialInterface.html${location.search}`)
          return Promise.reject();
        }

        // 是否支持webRTC
        if (!this.isSupportRtc) {
          // 设置日志 推流状态为失败
          this.logReportObj.setParams({plugFowStatus: 2, linkEndTime: this.logReportObj.formatDate(new Date())});
          // 日志上报
          this.logReportObj.collectLog(`${+this.parametersData.isWeixin ? '微信小程序' : ''}当前版本暂不支持使用`);

          this.$dialog.alert({
            title: '提示',
            message: '当前环境不支持使用，可下载谷歌浏览器或客户端进行使用',
            confirmButtonText: '确定',
            confirmButtonColor: '#3cc51f',
            callback: (_, done) => {
              done();
              this.exit();
            }
          })
          return Promise.reject(new Error('当前浏览器不支持webRTC'));
        }

        // webRtc连接,需获取连接中转地址
        if (cardData.webrtcNetworkAnalysis) {
          // 如果有网络分析的请求地址, 则请求,否则失败
          const { data: webrtcNetworkAnalysisReq }= await request.get(cardData.webrtcNetworkAnalysis); // 这个接口单独使用axios请求, 因为返回的数据跟封装的数据结构不一统一,是其他平台的接口,所以单独请求

          if (webrtcNetworkAnalysisReq !== null && webrtcNetworkAnalysisReq.success && webrtcNetworkAnalysisReq.data) {
              // 保存获取的连接地址到connect的请求的响应中, 方便后面使用
              cardData.webrtcNetwork = webrtcNetworkAnalysisReq.data;
              // 设置上报参数
              this.logReportObj.setParams({transferServerIp: webrtcNetworkAnalysisReq.data});
              return cardData;
          }else{
            // 设置上报参数
            this.logReportObj.setParams({linkWay: 4, plugFowStatus: 2, linkEndTime: this.logReportObj.formatDate(new Date())});
            // 日志上报
            this.logReportObj.collectLog(
              `webRtc连接,获取中转地址失败:
              url: ${cardData.webrtcNetworkAnalysis}
              method: get
              参数: 无
              响应: ${JSON.stringify(webrtcNetworkAnalysisReq)}`
            );

            // 弹窗并退出
            this.$dialog.alert({
              title: '提示',
              message: '访问失败,请稍后重试',
              confirmButtonText: '确定',
              confirmButtonColor: '#3cc51f',
              beforeClose: (action, done) => {
                done()
                this.exit();
              }
            })
            
            return Promise.reject(new Error('网络分析请求失败'));
          }
        }else{
          // 设置上报参数
          this.logReportObj.setParams({linkWay: 4, plugFowStatus: 2});
          // 日志上报
          this.logReportObj.collectLog(
            `webRtc连接,获取请求中转地址为空:
            url: /api/resources/user/cloud/connect
            method: post
            参数: ${JSON.stringify({ userCardId: this.activeCloud.userCardId })}
            响应: ${JSON.stringify(res)}`
          );
          return Promise.reject(new Error('网络分析请求地址不存在'));
        }
      } catch (error) {
        console.log('判断卡的连接方式', error);
        return Promise.reject(error);
      }
    },
    // 初始化webRTC及相关配置
    initWebRtc() {
      try {
        // 获取挂载的容器元素
        const videoRef = document.getElementById("videoRef");

        // 解构connectData中的数据
        const { sn: topic, cardToken: authToken, localIp, internetHttps, internetHttp, webrtcNetwork, webrtcTransferCmnet, webrtcTransferTelecom, webrtcTransferUnicom, videoCode } = this.connectData;
        // 判断长连接的协议方式
        const isWss = location.protocol === 'https:';
        
        // 生成连接地址
        const url = `${isWss ? 'wss://' : 'ws://'}${isWss ? internetHttps : internetHttp}/nats`;

        let quality = localStorage.getItem('definitionValue') ?? '自动';

        // 统一使用三网解析地址
        const ICEServerUrl = [
            { "CMNET": webrtcNetwork }, // 移动
            { 'CHINANET-GD': webrtcNetwork  }, // 电信
            { 'UNICOM-GD': webrtcNetwork }, // 联通
        ];

        // 配置连接参数
        const connection = {
          mount: videoRef,
          displaySize: { // 视频在页面显示的尺寸  必填
              width: Math.round(this.pageData.videoWidth),
              height: Math.round(this.pageData.videoHeight),
          },
          topic, // SN号  必填
          url,  //信令服务地址  必填
          ICEServerUrl,
          forwardServerAddress: '', // 转发服务器地址
          ip: localIp, // 实例ip
          controlToken: '', // 控制token
          width: 720, // 推流视频宽度  必填
          height: 1280,  // 推流视频高度  必填
          cardWidth: 0,  // 云机系统分辨率 宽  必填
          cardHeight: 0, // 云机系统分辨率 高  必填
          cardDensity: 0, // 云机系统显示 密度  必填
          authToken,  //拉流鉴权 token  必填
          quality, // 画质(码率)  超清 | 高清 | 标清 | 流畅
          fps: 30, //必填
          videoCodec: videoCode, // 视频编码格式  必填
          videoCodecMethod: true, // 硬编true | 软编false
          isMuted: false, // 是否静音
          isAllowedOpenCamera: true, // 是否允许打开摄像头
          sendFollow: true, // 是否允许主控转发文本到实例
          callback: (event)=> {}
        };

        // 设置日志参数 推流质量 
        this.logReportObj.setParams({imageQuality: quality});

        // 获取SDK类
        const MediaSdk = window.rtc_sdk.MediaSdk;
        // 初始化 SDK
        this.engine = new MediaSdk();
        console.log('RtcEngineConfig==', connection)
        // 初始化 SDK 并传入连接参数
        this.engine.RtcEngine(connection);

        // 监听回调方法
        this.eventCallbackFunction();
      } catch (error) {
        console.log('webRTC初始化失败', error);
      }
    },
    // webRTC状态回调监听回调方法
    eventCallbackFunction() {
      const engine = this.engine;

      // 连接成功
      engine.on('CONNECT_SUCCESS', (r) => {
        console.log("webrtc连接成功====★★★★★", r);
        if (r.code === 1005) { // 1005: 拉流鉴权成功
          // 清除loading
          this.$toast.clear();

          // 设置日志 推流状态为成功
          let now = new Date();
          this.logReportObj.setParams({plugFowStatus: 1, linkWay: 1, timeConsuming: now.getTime() - this.logReportObj.timeStartTime, linkEndTime: this.logReportObj.formatDate(now)});
          // 日志上报
          this.logReportObj.collectLog(`拉流成功`);

          // 初始化业务指令通道
          this.initControlChannel();
          
          // 查询超过指定触碰时间是否提示关闭弹窗
          this.$refs.timeoutNoOpsRef.pushflowPopup();
          // 获取云机剩余时长
          this.$refs.timeBalanceRef.getResidueTime();
        }
      });

      // 连接关闭
      engine.on('CONNECT_CLOSE', (r) => {
        console.log("webrtc关闭====★★★★★", r);
      });
      
      // 网络连接统计信息监听
      engine.on('NETWORK_STATS', (r) => {
        // console.log("webrtc网络连接统计信息监听====★★★★★", r);
        this.rtcNetwork = r;
      });

      // 连接异常
      engine.on('CONNECT_ERROR', (r) => {
        console.log("webrtc异常状态====★★★★★", r);
        // 异常状态枚举值
        const statusEnum = {
          10011: '连接超时',
          10012: '连接失败',
          1002: 'rtc连接失败',
          1003: 'rtc异常断开',
          1004: 'rtc连接失败',
          1006: '鉴权失败',
        };

        // 设置日志 推流状态为失败
        this.logReportObj.setParams({plugFowStatus: 2, linkWay: 0, linkEndTime: this.logReportObj.formatDate(new Date())});
        // 日志上报
        this.logReportObj.collectLog( `${statusEnum[r.code] || '连接异常'}: 消息: ${JSON.stringify(r)}` );

        this.$dialog.alert({
          title: '提示',
          message: '链接超时',
          confirmButtonText: '确定',
          confirmButtonColor: '#3cc51f',
          beforeClose: (action, done) => {
            done()
            this.exit()
          }
        })
      });

      // 显示区域大小发生改变 响应
      engine.on('RECEIVE_RESOLUTION', (r) => {
        // 分辨率大小发生改变,响应
        console.log("分辨率大小发生改变,响应 => RECEIVE_RESOLUTION", r);
      });
    },
    // 业务指令通道初始化
    initControlChannel() {
      try {
        // 初始化业务指令通道
        let { internetHttps, internetHttp, localIp, cardToken } = this.connectData;
        const isWss = location.protocol === 'https:';
        let cUrl = `${isWss ? 'wss' : 'ws'}://${isWss ? internetHttps : internetHttp}/businessChannel?cardIp=${localIp}&token=${cardToken}&type=directives`;
        this.doConnectDirectivesWs = new WebSocket(cUrl);
        this.doConnectDirectivesWs.binaryType = 'arraybuffer';
        // 清除定时器
        if (this.doConnectDirectivesIntervalerPing) {
          clearInterval(this.doConnectDirectivesIntervalerPing);
        }

        // 链接成功
        this.doConnectDirectivesWs.onopen = (e) => {
          // 日志上报
          this.logReportObj.collectLog( `消息: 业务通道连接成功` );

          // 重置重连次数
          this.doConnectDirectivesRequestNum = 1;

          // v5.9.5需求: 华为荣耀渠道包应用隐藏，进入其他客户端推流应用全部展示包含（IOS，H5，小程序，PC，安卓其他包）; 
          // H5发送指令显示所有应用
          this.sendWsCommand({ type: 'hideApp', data: {
            action: 2, // 1: 隐藏 2: 显示
          } });


          // 设置定时器 每3秒发送一次心跳
          this.doConnectDirectivesIntervalerPing = setInterval(() => {
            if (this.doConnectDirectivesWs.readyState === 1) {
              this.sendWsCommand({ type: 'ping' });
            } else {
              clearInterval(this.doConnectDirectivesIntervalerPing);
            }
          }, 3000);

          // 输入法: 本地输入法 1 云机输入法 2 
          this.sendWsCommand({ type: 'InputMethod', data: { type: 2 } });
        }

        // 接受到的消息
        this.doConnectDirectivesWs.onmessage = res => {

          const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
          switch (result.type) {
            case 'reProduceText':
              this.$native.clipboard.writeText(result.data.text);
              break
            case 'downAdnInstallRep':
              this.$toast(result.data.msg)
              break
            // 接受到这个消息就自动退出云机
            case 'exitPhone':
              this.exit();
              break
          }
        }

        // 链接报错的回调
        this.doConnectDirectivesWs.onerror = res => {
          // 设置日志
          this.logReportObj.setParams({plugFowStatus: 1, linkWay: 0, linkEndTime: this.logReportObj.formatDate(new Date())});
          // 日志上报
          this.logReportObj.collectLog(
            `业务指令通道报错:
            url: ${res.target.url}
            type: ${res.type}
            消息: ${JSON.stringify(res)}`
          );

          if (this.doConnectDirectivesRequestNum > this.doConnectDirectivesRequestNumMax) {
            return this.exit();
          }else{
            // 重连次数加1
            ++this.doConnectDirectivesRequestNum;
            // 重连
            this.initControlChannel();
          }
        }
      } catch (error) {
        console.log('initControlChannel error', error);
      }
    },
    /**
     * popup 功能按钮点击事件
     * @param {Object} val 传递的参数
     * @description 传递的参数格式: { code: 'hideKey', label: '隐藏虚拟键', icon: 'icon-hide' } 
     */
    funcHandle({code}) {
      console.log('funcHandle code:', code);
      switch (code) {
        case 'hideKey':
          // 隐藏虚拟按键
          document.getElementById('foot-menu-wrap').style.display = 'none';
          this.pageData.footMenuHeight = 0; // 设置底部菜单高度为0
          this.getInitSize(); // 重新计算视频尺寸
          this.changeVideoStyle(); // 重新设置视频尺寸
          break;
        case 'showKey':
          // 显示虚拟按键
          document.getElementById('foot-menu-wrap').style.display = 'flex';
          this.pageData.footMenuHeight = 40; // 设置底部菜单高度为40px
          this.getInitSize(); // 重新计算视频尺寸
          this.changeVideoStyle(); // 重新设置视频尺寸
          break
        case 'shearplate':
          // 粘贴板按钮
          this.shearplate();
          break;
        case 'shake':
          // 摇一摇
          if(this.sendWsCommand({ type: 'shakeit' })) {
            this.$toast('操作成功,如有异常请联系客服');
          } else {
            this.$toast('操作失败,请联系客服');
          }
          break;
        case 'blow':
          // 吹一吹
          if(this.sendWsCommand({ type: 'blow' })) {
            this.$toast('操作成功,如有异常请联系客服');
          } else {
            this.$toast('操作失败,请联系客服');
          }
          break;
      }
    },
    // 切换云机
    async changeCloudHandle(cloudData) {
      try {
        // 保存当前云机数据
        this.activeCloud = cloudData;

        // 重置相关数据
        this.closeChannel();
        // 重置重连次数
        this.doConnectDirectivesRequestNum = 1;
        // 重置 end


        if(this.sdkLoadStatus === 'success') {
          // 开始运行程序
          this.$nextTick(()=> this.start(cloudData) );
        }else {
          console.log('SDK加载失败');
        }
      } catch (error) {
        console.log('changeCloud error', error);
      }
    },
    // 重新设置视频尺寸
    changeVideoStyle() {
      this.$nextTick(() => {
        // 获取video元素
        const video = document.getElementById("videoRef").getElementsByTagName('video')[0];
        video.style.width = this.pageData.videoWidth + 'px';
        video.style.height = this.pageData.videoHeight + 'px';
      });
    },
    // 三键
    sendKey (keyCode) {
      try {
        this.engine?.sendKey(keyCode);
        // 重置超时无操作定时器
        this.$refs.timeoutNoOpsRef?.noOperationSetTimeout();
      } catch (error) {
        console.log('sendKey error', error);
      }
    },
    // popup粘贴板按钮点击事件
    shearplate(){
      // 调用InputCopy组件的pasteText方法读取粘贴板
      this.$refs.inputCopyRef.pasteText();
    },
    // 打开去取云机内的粘贴板内容
    openPasteboard(text){
      this.$refs.cloudPhoneClipboardRef.init(text);
    },
    // 退出功能
    exit() {
      // 关闭通道
      this.closeChannel();

      // 获取当前环境
      const env = isBrowserEnvironment();

      // ios环境下 直接使用浏览器api返回上一页
      if(env.isBrowser && !env.isMiniProgramWebview && env.isIPhone && env.isTopWindow) {
        // 上面的方法执行未生效就走这里
        if (window.history.length > 1) {
          return window.history.back();
        }
      }
      uni && uni.reLaunch({ url: '/pages/index/index' });
    },
    // 发送业务指令通道消息
    sendWsCommand(data) {
      if(this.doConnectDirectivesWs.readyState === 1) {
        this.doConnectDirectivesWs.send(JSON.stringify(data));
        return true;
      }

      return false;
    },
    // 初始化日志上报实例
    initLogReport() {
      // 初始化日志上报实例
      this.logReportObj = new logReport({ request: this.$axios });

      uni.getEnv((res) => {
        // 设置上报参数
        this.logReportObj.setParams({ clientType: Object.keys(res)[0] });
      })
    },
    // 关闭通道
    async closeChannel() {
      try {
        // 关闭日志上报
        this.logReportObj?.destroy();
        // 关闭webRTC
        this.engine?.disconnect && this.engine?.disconnect();
        // 关闭业务指令通道
        this.doConnectDirectivesWs?.close();
      } catch (error) {
        console.log('closeChannel error', error);
      }
    },
    // 开始运行程序
    async start(activeCloud) {
      console.log('start activeCloud', activeCloud);
      try {
        this.$toast.loading({
          className: 'rtc-loading',
          duration: 0, // 持续展示 toast
          message: `设备(${activeCloud.userCardId})正在获取...`,
        });

        // 初始化日志上报
        this.initLogReport();

        // 调用接口获取卡连接数据
        const cardData = await this.getConnectData(this.parametersData);
        
        // // 判断卡的连接方式
        const connectData = await this.judgeConnectType(cardData);

        // 保存卡连接信息
        this.connectData = connectData;

        this.initWebRtc();
      } catch (error) {
        console.log('start error', error);
      }
    },
  }
}
</script>
<style lang="scss" scoped>
html{
  background-color: #000;
}
// 动态生成 从 0 到 100px 的样式
@for $i from 0 through 100 {
  .mb-#{$i} {
    margin-bottom: #{$i}px;
  }

  .mt-#{$i} {
    margin-top: #{$i}px;
  }

  .ml-#{$i} {
    margin-left: #{$i}px;
  }

  .mr-#{$i} {
    margin-right: #{$i}px;
  }
}
$-radeus-12: 12px;
$-bg-yellow: rgb(255, 253, 241);

.rtc-page{
  position: relative;
  font-size: 14px;
  
  .video-wrapper{
    position: relative;
  }
}

.cover-bg{
  background-color: #000;
}

#foot-menu-wrap{
  border-width: 0px;
  position: absolute;
  left: 0px;
  bottom: 0px;
  width: 100%;
  // height: 40px; // 三大功能键高度,通过vue动态添加
  background: inherit;
  background-color: rgba(0, 12, 23, 1);
  border: none;
  border-radius: 0px;
  -moz-box-shadow: none;
  -webkit-box-shadow: none;
  box-shadow: none;
  z-index: 1;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  color: #fff;
}

// 
.rtc-page >>> .van-toast.rtc-loading{
  white-space: nowrap;
}
</style>