//变量
var system = 'other' //系统版本
var socket = null // netty连接
var company_code = '' // 企业ID
var agent_id = '' //坐席ID
var ext_id = '' //分机ID
var nettyTimer = null // netty定时器心跳包
var logTimer = null //日志定时器
var pingCount = 0 //未收到回应次数
var clientip = '' //IPS
var nowUuid = '' // 正在通话的UUID
var consultUuid = '' //被咨询UUID
var callingPhone = '' //正在通话的Phone
var reqIdArr = [] //唯一ID数组
var disconnect = false //是否断开连接
var nowStatus = 'OFFLINE' //当前状态
var agent_pwd = null //坐席密码
var ext_pwd = null //分机密码
var ua = null //RTC对象
var pbx = null //pbx地址
var hasVideo = false
var hasAudio = true
var sessionall = null
var localStream_1 = null //本地流
var localStreamScreen = null //共享流
var switchStream = null // 切换视频流
var isAdmin = false //是否质检功能
var remoteStream = null //远端流
var callType = '' // 主叫被叫
var nowPixels = ''
var hasCameras = false
var ls_vt = null //共享屏幕原始视频流信息
var vague = false //是否开启模糊背景
var virtua = false //虚拟
var backgroundImgUrl = '' //背景图片
var getAgentListXhr = null 
var videoTrack = null //视频轨道
var token = null // 质检token
var linkUrl = null  //ws连接地址
// 创建WebSocket对象
function createSocket(){
  let linkObj = {
    "agent_id": company_code + '_' + agent_id,
    "company_code": company_code,
    "os": system
  }
  linkUrl = baseUrl + window.btoa(JSON.stringify(linkObj))
  socket = new WebSocket(linkUrl);
  socket.onopen = onopen
  socket.onmessage = onmessage
  socket.onerror = onerror
  socket.onclose = onclose
  addEventListener('onmessage',(data)=>{
      let backMsg = JSON.parse(data.detail.data)
      // if (window.event_cmdres){
      //   window.event_cmdres(JSON.stringify(backMsg))
      // }  
      if (reqIdArr.includes(backMsg.req_id) || ['change_status','connect','callin','callback'].includes(backMsg.msg_type)) {
        // 删除该值
        if (reqIdArr.indexOf(backMsg.req_id) > -1){
          reqIdArr.splice(reqIdArr.indexOf(backMsg.req_id), 1);
        }
        setLog('回复匹配唯一ID' + data.detail.data)
        switch(backMsg.msg_type){
          case 'pong':
            pingCount = 0
          break;
          case 'consult':
            if(backMsg.code == '0' && backMsg.consult_uuid){
              consultUuid = backMsg.consult_uuid
            }
          break;
          case 'call':
            if (backMsg.code == 0){
              nowUuid = backMsg.uuid
            }
          break;
          case 'connect':
            uploadLog()
          break;
          case 'eavesdrop':
            if (backMsg.code == 0){
              nowUuid = backMsg.uuid
            }
          break;
          case 'whisper':
            if (backMsg.code == 0){
              nowUuid = backMsg.uuid
            }
          break;
          case 'interrupt_call':
            if (backMsg.code == 0){
              nowUuid = backMsg.uuid
            }
          break;
          case 'force_call':
            if (backMsg.code == 0){
              nowUuid = backMsg.uuid
            }
          break;
          case 'substitute':
            if (backMsg.code == 0){
              nowUuid = backMsg.uuid
            }
          break;
          case 'change_status':
            if(['FREE','BUSY','ARRANGE','REST','OFFLINE'].includes(backMsg.agent_status)){
              callType = ''
              closeAllStream()
            }
          break;
          case 'callin':
              callType = 'callin'
              nowUuid = backMsg.uuid
              callingPhone = backMsg.caller_number
              // if (backMsg.video != 0){
              //   hasVideo = true
              //   if (backMsg.audio != 0){
              //       hasAudio = true
              //   }
              // } else {
              //     hasAudio = true
              //     hasVideo = false
              // }
          break;
          case 'checkin':
            if (backMsg.code == '0'){
              pbx = backMsg.pbx
              ext_pwd = backMsg.ext_pwd
              token = backMsg.token
              if (backMsg.ext_id && backMsg.ext_id.indexOf('_') > -1){
                ext_id = backMsg.ext_id.split('_')[1]
              }
              if (backMsg.login_type == '1'){
                registerRTC()
              }
            } else if (backMsg.code == '1012'){
              if (window.toast){
                toast(backMsg.msg)
              }
            }
          break;
          case 'checkout':
            if (backMsg.code == '0'){
              nowStatus = 'OFFLINE'
            }
          break;
          case 'change_media':
            if (backMsg.code == '0'){
              switch_video()
            }
            break
        }
        if (backMsg.agent_status){
          nowStatus = backMsg.agent_status
          if (['RINGING','CALLING'].includes(backMsg.agent_status) && backMsg.uuid){
            nowUuid = backMsg.uuid
          }
        }
        // 暴露报文
        if (window.event_cmdres){
          window.event_cmdres(JSON.stringify(backMsg))
        }
        if (msgEvent.event_cmdres){
          msgEvent.event_cmdres(JSON.stringify(backMsg))
        }
      } else {
        setLog('回复不匹配唯一ID' + data.detail.data)
      }
  })
}
function UAEvent(ua) {
  // 开始尝试连接
  ua.on('connecting', function (args) {
    console.log('%c connecting', 'color: #f00');
  });
  // 连接完毕
  ua.on('connected', function () {
    console.log('%c connected', 'color: #f00');
  });
  // 主动取消注册或注册后定期重新注册失败
  ua.on('unregistered', function (response, cause) {
    signOut()
    if (window.toastMessage){
      toastMessage('分机注册失败')
    }
  });
  // 注册成功
  ua.on('registered', function () {

  })
  // websocket 连接失败
  ua.on('transportError', function () {
    signOut()
    if (window.toastMessage){
      toastMessage('分机注册失败')
    }
  })
}
function onopen(){
  if (!nettyTimer){
    nettyTimer = setInterval(()=>{
      let msgObj = {
        msg_type: 'ping'
      }
      msgType(msgObj)
      pingCount++
      if (pingCount > 3){
        console.log('断开连接')
        setLog('断开连接')
        disconnect = true
        pingCount = 0
        socket.close()
        socket = null
        createSocket()
      }
    },15000)
  }
  //如果是断开连接 自动迁入
  if (disconnect){
    disconnect = false
    signIn()
  }
}
function onmessage(e){
  window.dispatchEvent(new CustomEvent('onmessage', {
    detail: {
      data: e.data
    }
  }))
}
function onerror(){
}
function onclose(){
}
function sendMsg(msg){
  if (socket && socket.readyState === 1) {
    socket.send(msg)
    setLog('已发出报文' + msg)
  } else {
    setLog('未发出的报文' + msg)
  }
}
function msgType(msg){
  let msgObj = {
    req_id: generateUUID(),
    company_code: company_code,
    agent_id: company_code + '_' + agent_id,
    ext_id: company_code + '_' + (ext_id || agent_id),
    os: system,
    token
  }
  let sendMsgObj = Object.assign(msgObj,msg)
  sendMsg(JSON.stringify(sendMsgObj))
}
//获取系统版本
function getPosType() {
  var userAgent = navigator.userAgent.toLowerCase();
  if (userAgent.indexOf('iphone') >= 0 || userAgent.indexOf('ipad') >= 0 || userAgent.indexOf('ipod') >= 0) {
    // IOS
    system = 'IOS'
  } else if (userAgent.indexOf('android') >= 0) {
    // Android
    system = 'Android'
  } else if (userAgent.indexOf('mac') >= 0) {
    // Mac
    system = 'Mac'
  } else if (userAgent.indexOf('win') >= 0) {
    // Windows
    system = 'Windows'
  } else {
    // 其他操作系统
    system = 'other'
  }
}
// 获取本地IP地址
function getLocalIPs() {
  var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
  var ips = []
  if (RTCPeerConnection) (()=>{
      var rtc = new RTCPeerConnection()
      rtc.createDataChannel(''); //创建一个可以发送任意数据的数据通道
      rtc.createOffer( offerDesc => { //创建并存储一个sdp数据
      rtc.setLocalDescription(offerDesc)
  }, e => { console.log(e)})
  rtc.onicecandidate = (evt) => { //监听candidate事件
      if (evt && evt.candidate && evt.candidate.candidate){
          let ip_rule = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
          let ip4 = /([0-9]{1,3}(\.[0-9]{1,3}){3})/
          var ip_addr = ip_rule.exec(evt.candidate.candidate)[1]
          if (!ips.includes(ip_addr) && ip4.test(ip_addr)){
            ips.push(ip_addr)
          }
          clientip = ips.join(',')
          console.log(clientip)
        }}
  })()
  else{console.log("没有找到")}
}
//生成唯一性ID
function generateUUID() {
  var d = new Date().getTime();
  if (window.performance && typeof window.performance.now === "function") {
    d += performance.now(); // use high-precision timer if available
  }
  var uuid = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  });
  reqIdArr.push(uuid)
  return uuid;
}
//上传日志本地存储 后续接口
function uploadLog(){
  if (!logTimer && token){
    setInterval(()=>{
      if (localStorage.getItem('SDKLOG')){
        ajax({
          type: 'POST',
          url: httpUrl + 'cloudcc-client-server/openapi/sdk-logger',
          data: {json: localStorage.getItem('SDKLOG'),empAccId:company_code + '_' + agent_id},
          success: function (res) {
            localStorage.setItem('SDKLOG','')
          }
        })
      }
    },60000)
  }
}
//生成LOG日志
function setLog(msg){
  let now = new Date()
  let msgText = now +'调用'+ msg + '\n/'
  let full = false
  let size = 0
  for(item in window.localStorage){
    if(window.localStorage.hasOwnProperty(item)) {
        size += window.localStorage.getItem(item).length;
    }
  }
  if ((size / 1024 / 1024).toFixed(2) > 4){
    full = true
  } else {
    full = false
  }
  if (localStorage.getItem('SDKLOG')){
    msgText = localStorage.getItem('SDKLOG') + msgText
  }
  if (full){
    localStorage.setItem('SDKLOG', '存储已满，删除记录')
  } else {
    localStorage.setItem('SDKLOG', msgText)
  }
  // console.log(msgText)
}
getPosType()
getLocalIPs()
/*
 * 以下内容方法为对外接口
 */
//初始化账号信息
function initialization(vccId,agent,extid,pwd){
    company_code = vccId
    agent_id = agent
    ext_id = extid||agent
    agent_pwd = pwd
    createSocket()
    setLog('初始化方法' + vccId + ',' + agent)
    if(!document.getElementById('localVideo')){
      creatVideoTags()
    }
 }
 // 初始化VIDEO标签
 function creatVideoTags(){
  var localVideo = document.createElement('video');
  var remoteVideo = document.createElement('video');
  // 设置 video 元素的 id
  localVideo.id = 'localVideo';
  localVideo.setAttribute('muted','muted')
  localVideo.setAttribute('autoplay','autoplay')
  remoteVideo.setAttribute('autoplay','autoplay')
  remoteVideo.id = 'remoteVideo';
  // 设置 video 元素不可见
  localVideo.style.display = 'none';
  remoteVideo.style.display = 'none';
  // 将 video 元素添加到 body 中
  document.body.appendChild(localVideo);
  document.body.appendChild(remoteVideo);
 }
// 签入分机
function signIn(startStatus){
  let msgObj = {
    msg_type: 'checkin',
    agent_ip: clientip,
    agent_pwd,
    start_status: startStatus||'free'
  }
  msgType(msgObj)
}
//复位
function reset(){
  closeAllStream()
  let msgObj = {
    msg_type: 'checkin',
    agent_ip: clientip,
    agent_pwd,
    start_status: '',
    reset: true
  }
  msgType(msgObj)
}
// 签出分机
function signOut(){
  let msgObj = {
    msg_type: 'checkout',
    agent_ip: clientip,
  }
  msgType(msgObj)
}
//切换状态(包含强制)
function changeStatus(action,rest_min,operated_ext_id,operated_agent_id){
  let msgObj = {
    msg_type: 'change_status',
    action,
    rest_min,
    operated_ext_id: company_code + '_' + operated_ext_id,
    operated_agent_id:  company_code + '_' + operated_agent_id
  }
  msgType(msgObj)
}
//呼出
function callOut(numbers,audio,video,pixels,line,max_ring_time,max_call_time,record_start,record_contact,is_stereo,file_name){
  return new Promise(function (resolve,reject) {
    if (!['FREE','BUSY','ARRANGE','REST'].includes(nowStatus)){
      resolve(nowStatus)
    } else {
      callType = 'callout'
      let number = numbers.replace(/\s/g, "")
      let callNumber = number
      let lineOut = callNumber.substring(0,1) == '#'?0:1
      callNumber.indexOf('_') > -1?lineOut=0:lineOut
      callNumber = (callNumber.substring(0,1) == '#'?company_code+'_'+callNumber.slice(1):number)
      nowPixels = pixels || ''
      callingPhone = callNumber
      if (audio!=0){
        hasAudio = true
      } else {
        hasAudio = false
      }
      if (video &&  video!=0){
        hasVideo = true
      } else {
        hasVideo = false
      }
      let msgObj = {
        msg_type: 'call',
        callee_number: callNumber,
        out_line: line || lineOut,
        audio: audio || 3,
        video: video || 0,
        pixels: pixels || '',
        max_ring_time: max_ring_time || '',
        max_call_time: max_call_time || '',
        record_start: record_start || '',
        record_contact: record_contact || '',
        is_stereo: is_stereo || '',
        file_name: file_name || '',
      }
      msgType(msgObj)
    }
  })
}
//保持/取消 1保持0取消
function hold(hold){
  let msgObj = {
    msg_type: 'hold',
    uuid: nowUuid,
    hold:hold
  }
  msgType(msgObj)
}
//静音/取消 1静音0取消 发报文
function mute(mute){
  let msgObj = {
    msg_type: 'mute',
    uuid: nowUuid,
    mute:mute
  }
  msgType(msgObj)
}
//切换服务模式
function toggleServiceMode(service_mode){
  let msgObj = {
    msg_type: 'toggle_service_mode',
    service_mode
  }
  msgType(msgObj)
}
// 本地操作是否有音频
function localMute(mute) {
  return new Promise(function (resolve,reject) {
    if (!sessionall) {
      reject('error');
    }
    var pc = sessionall.sessionDescriptionHandler.peerConnection;
    if (pc.getSenders) {
        pc.getSenders().forEach(function (sender) {
            if (sender.track.kind === 'audio') {
              if (mute == '1'){
                sender.track.enabled = false
                resolve('mute')
              } else {
                sender.track.enabled = true
                resolve('unmute')
              }
            }
        });
    } else {
        pc.getLocalStreams().forEach(function (stream) {
            stream.getAudioTracks().forEach(function (track) {
                if (track.kind === 'audio') {
                  if (mute == '1'){
                    track.enabled = false;
                    resolve('mute')
                  } else {
                    track.enabled = true;
                    resolve('unmute')
                  }
                }
            });
        });
    }
  })
}
// 本地关闭视频
function localHasVideo(val){
  return new Promise(function (resolve,reject) {
    if (!sessionall) {
      reject('error');
    }
    var pc = sessionall.sessionDescriptionHandler.peerConnection;
    if (pc.getSenders) {
        pc.getSenders().forEach(function (sender) {
            if (sender.track.kind == 'video') {
              if (val == '1'){
                sender.track.enabled = false
                resolve('close')
              } else {
                sender.track.enabled = true
                resolve('open')
              }
            }
        });
    } else {
        pc.getLocalStreams().forEach(function (stream) {
            stream.getAudioTracks().forEach(function (track) {
                if (track.kind == 'video') {
                  if (val == '1'){
                    track.enabled = false;
                    resolve('close')
                  } else {
                    track.enabled = true;
                    resolve('open')
                  }
                }
            });
        });
    }
  })
}
//关闭视频/取消 1关闭0打开
function change_video(video){
  let msgObj = {
    msg_type: 'video',
    uuid: nowUuid,
    video
  }
  msgType(msgObj)
}
//挂断电话
function hangUp(){
  let msgObj = {
    msg_type: 'hangup',
    uuid: nowUuid
  }
  msgType(msgObj)
}
//获取状态
function getStatus(){
  let msgObj = {
    msg_type: 'get_status',
  }
  msgType(msgObj)
}
//盲转/咨询中转
function transfer(){
  let msgObj = {
    msg_type: 'consult_to_trans',
    consult_uuid: consultUuid,
  }
  msgType(msgObj)
}
//转接|满意度
function transferCall(number,trans_type,type,audio,video,pixels,max_ring_time,max_call_time,record_start,record_contact,is_stereo,file_name){
  let msgObj = {
    msg_type: 'trans',
    uuid: nowUuid,
    type: type || '1',
    trans_type,
    trans_number: number || '',
    audio: audio || 3,
    video: video || 0,
    pixels: pixels || '',
    max_ring_time: max_ring_time || '',
    max_call_time: max_call_time || '',
    record_start: record_start || '',
    record_contact: record_contact || '',
    is_stereo: is_stereo || '',
    file_name: file_name || '',
  }
  msgType(msgObj)
}
//咨询/取消咨询
function consultingCall(number,consulting_type,type,audio,video,pixels,max_ring_time,max_call_time,record_start,record_contact,is_stereo,file_name){
  let msgObj = {
    msg_type: 'consult',
    uuid: nowUuid,
    type: type || '1',
    consult_type: consulting_type,
    consult_number: number || '',
    audio: audio || 3,
    video: video || 0,
    pixels: pixels || '',
    max_ring_time: max_ring_time || '',
    max_call_time: max_call_time || '',
    record_start: record_start || '',
    record_contact: record_contact || '',
    is_stereo: is_stereo || '',
    file_name: file_name || '',
  }
  msgType(msgObj)
}
//三方通话
function multiCall(number,three_way_type,type,audio,video,pixels,max_ring_time,max_call_time,record_start,record_contact,is_stereo,file_name){
  let msgObj = {
    msg_type: 'three_way',
    uuid: nowUuid,
    three_way_type: three_way_type,
    three_way_number: number || '',
    type: type || '1',
    audio: audio || 3,
    video: video || 0,
    pixels: pixels || '',
    max_ring_time: max_ring_time || '',
    max_call_time: max_call_time || '',
    record_start: record_start || '',
    record_contact: record_contact || '',
    is_stereo: is_stereo || '',
    file_name: file_name || '',
  }
  msgType(msgObj)
}
//dtmf
function dtmfCall(content){
  let msgObj = {
    msg_type: 'dtmf',
    uuid: nowUuid,
    content: content || '',
    dtmf_type: 3
  }
  msgType(msgObj)
}
//监听
function monitorCall(operated_ext_id,operated_agent_id){
  let msgObj = {
    msg_type: 'eavesdrop',
    operated_ext_id: company_code + '_' + operated_ext_id,
    operated_agent_id:  company_code + '_' + operated_agent_id,
    token
  }
  msgType(msgObj)
}
//耳语
function whisperCall(operated_ext_id,operated_agent_id){
  let msgObj = {
    msg_type: 'whisper',
    operated_ext_id: company_code + '_' + operated_ext_id,
    operated_agent_id:  company_code + '_' + operated_agent_id,
    token
  }
  msgType(msgObj)
}
//代接
function substituteCall(operated_ext_id,operated_agent_id){
  let msgObj = {
    msg_type: 'substitute',
    operated_ext_id: company_code + '_' + operated_ext_id,
    operated_agent_id:  company_code + '_' + operated_agent_id,
    token
  }
  msgType(msgObj)
}
//强拆
function interruptCall(operated_ext_id,operated_agent_id){
  let msgObj = {
    msg_type: 'interrupt_call',
    operated_ext_id: company_code + '_' + operated_ext_id,
    operated_agent_id:  company_code + '_' + operated_agent_id,
    token
  }
  msgType(msgObj)
}
//强插
function forceCall(operated_ext_id,operated_agent_id){
  let msgObj = {
    msg_type: 'force_call',
    operated_ext_id: company_code + '_' + operated_ext_id,
    operated_agent_id:  company_code + '_' + operated_agent_id,
    token
  }
  msgType(msgObj)
}
//音视频切换
function changeMedia(val){
  var pc = sessionall.sessionDescriptionHandler.peerConnection;
  if (val == 'video'){
    hasVideo = true
    if (localStream_1){
      navigator.mediaDevices.getUserMedia({ video: true,audio: true}).then((stream)=>{
        switchStream = stream
        videoTrack = stream.getVideoTracks()[0]
        pc.getSenders().forEach(function (sender) {
          if (sender.track && sender.track.kind == 'video') {
            sender.replaceTrack(videoTrack)
            localStream_1.addTrack(videoTrack)
          }
        });
      })
    }
  } else if (val == 'audio'){
    hasVideo = false
    if (localStream_1){
      localStream_1.removeTrack(videoTrack);
      videoTrack.stop()
      videoTrack = null
      pc.getSenders().forEach(function (sender) {
        var track = sender.track;
        if (track && track.kind && track.kind === "video") {
          track.stop()
        }
      });
    }
  }
  val == 'video'?hasVideo=true:hasVideo=false
  let msgObj = {
    msg_type: 'change_media',
    pixels: nowPixels,
    audio: 3,
    video: val == 'video'?3:0,
    uuid: nowUuid,
  }
  msgType(msgObj)
}
function callBackAudio(){
  hasVideo = false
  var pc = sessionall.sessionDescriptionHandler.peerConnection;
  if (localStream_1){
    pc.getSenders().forEach(function (sender) {
      var track = sender.track;
      if (track && track.kind && track.kind === "video") {
        track.stop()
      }
    });
  }
}
function registerRTC(){
  let config = {
    uri: "sip:" + company_code + '_' + ext_id + '@' + pbx,
    authorizationUser: company_code +'_' + ext_id,
    password: ext_pwd,
    displayName: company_code +'_' + ext_id,
    userAgentString: 'cloudcc_' + system,
    // rel100: SIP.C.supported.SUPPORTED,
    log: {
        builtinEnabled: true,
        level: 1 // log日志级别
    },
    transportOptions: {
       wsServers: (window.location.href.indexOf('https:')>-1?"wss://":"ws://") + pbx, // ws协议
       traceSip: false  //开启sip日志,用于排查问题
    },
    // iceServers: {urls: "stun:172.16.250.36:3478"},
    allowLegacyNotifications: true,
    hackWssInTransport: false, // 设置为true 则注册时 transport=wss; false:transport=ws;
    registerOptions: {
        expires: 60,
        // registrar: 'sip:registrar.' + company_code +'_' + ext_id + '.com'
    }
  }
  ua = new SIP.UA(config)
  UAEvent(ua)
  Incoming()
}
//初始化呼入
function Incoming(){
  // 接受入站（用户代理服务器）会话
  ua.on('invite', function (session) {
      var remoteVideo = document.getElementById('remoteVideo');
      var localVideo = document.getElementById('localVideo');
      sessionall = session
      // if (sessionall.request.body.indexOf('m=video 0 RTP') > -1){
      //   hasVideo = false
      // } else {
      //   hasVideo = true
      // }
        session.on('accepted', function (response, cause) {
            var pc = this.sessionDescriptionHandler.peerConnection;
            if (pc.getReceivers) {
                remoteStream = new window.MediaStream();
                pc.getReceivers().forEach(function (receiver) {
                    var track = receiver.track;
                    if (track) {
                        if (hasAudio && track.kind == 'audio'){
                          remoteStream.addTrack(track);
                        }
                        if (hasVideo && track.kind == 'video'){
                          remoteStream.addTrack(track);
                        }
                    }
                });
            } else {
              remoteStream = pc.getRemoteStreams()[0];
            }
            remoteVideo.srcObject = remoteStream;
            if (pc.getSenders) {
                localStream_1 = new window.MediaStream();
                pc.getSenders().forEach(function (sender) {
                    var track = sender.track;
                    if (track && track.kind === "video") {
                      if (hasVideo){
                        // track.enabled = false
                        localStream_1.addTrack(track);
                      } else {
                        track.stop()
                      }
                    }
                });
            }
            else {
                localStream_1 = pc.getLocalStreams()[0];
            }
            localVideo.srcObject = localStream_1;
	          localVideo.volume = 0;
        })
        sessionall = session;
        if (callType == 'callout' || (setParam && setParam.agentAnswerMode == '2')){
          pickUp()
        }
  });
}
//应答
function pickUp(){
  // let constraints = {}
  // if (basic_monitor_obj){
  //   if (basic_monitor_obj.microphone_id){
  //     constraints.audio = {deviceId:basic_monitor_obj.microphone_id}
  //   } else {
  //     constraints.audio = true
  //   }
  //   if (hasVideo){
  //     if (basic_monitor_obj.camera_id){
  //       constraints.video = {deviceId:basic_monitor_obj.camera_id,width: 640,height: 480}
  //     } else {
  //       constraints.video = {width: 640,height: 480}
  //     }
  //   } else {
  //     constraints.video = hasVideo
  //   }
  // } else {
  //   if (hasVideo){
  //     constraints = {
  //       audio: hasAudio,
  //       video: {width: 640,height: 480}
  //     }
  //   } else{
  //     constraints = {
  //       audio: hasAudio,
  //       video: hasVideo
  //     }
  //   }
  // }
  sessionall.accept({
    sessionDescriptionHandlerOptions: {
      audio: hasAudio,
      video: hasVideo
    }
  });
}
/**
 * 截图
 * @param {string} fileName                             -图片名称
 * @param {string} picType                              -图片类型(png,jpeg)
 * @param {boolean} isDownload                          -是否下载
 * @memberof Stream
 */
function  takeSnapshot(fileName, picType, isDownload = true, isAddWaterMark = false) {
      let photo_dom = document.getElementById('remoteVideo');
      // if (this._virtualBackground && this._virtualBackground._canvasPerson) {
      //     photo_dom = this._virtualBackground._canvasPerson;
      // }
      let canvas = document.createElement('canvas');
      canvas.width = document.getElementById('remoteVideo').offsetWidth
      canvas.height = document.getElementById('remoteVideo').offsetHeight

      let ctx = canvas.getContext('2d');
      // if (this._virtualBackground) {
      //     ctx.drawImage(this._virtualBackground.getCanvas(), 0, 0, canvas.width, canvas.height);
      // } else {
      ctx.drawImage(photo_dom, 0, 0, canvas.width, canvas.height);
      // }
      if (isAddWaterMark) {
          let curdateString = getCurDateStringWithFormat('yyyy-MM-dd hh:mm:ss');
          let fontSize = 12;
          let bottomSpace = 20;
          let textHeight = 20;
          let textWidth = 30;
          let rightSpace = 20;
  
          ctx.fillStyle = '#7F7F7F';
          ctx.textBaseline  = 'middle';
          ctx.textAlign = 'left';
          ctx.font = fontSize + 'px normal';
          let text = ctx.measureText(curdateString);
          let name = ctx.measureText(fileName);
  
          while (canvas.width < text.width) {
              fontSize = fontSize - 1;
              ctx.font = fontSize + 'px normal';
              text = ctx.measureText(curdateString);
              name = ctx.measureText(fileName);
          }
          textWidth = text.width;
          textHeight = text.actualBoundingBoxAscent + text.actualBoundingBoxDescent;
          if (name.width > text.width) {
              textWidth = name.width;
              textHeight = name.actualBoundingBoxAscent + name.actualBoundingBoxDescent;
          }
  
          ctx.fillText(curdateString, canvas.width - textWidth - rightSpace, canvas.height - textHeight * 2 - bottomSpace * 2);
          ctx.fillText(fileName, canvas.width - textWidth - rightSpace,  canvas.height - textHeight - bottomSpace);
      }

      let imgURL = canvas.toDataURL('image/' + picType);
      if (isDownload) {
          let dlLink = document.createElement('a');
          dlLink.download = fileName  + '_' + Date.parse(new Date());
          dlLink.href = imgURL;
          document.body.appendChild(dlLink);
          dlLink.click();
          document.body.removeChild(dlLink);
      }
      return imgURL;
}
//录屏
let mediaRecorder = null;
let recordedChunks = [];
function  startRecording(){
const options = { mimeType: 'video/webm;codecs=h264' }; //文件格式
mediaRecorder = new MediaRecorder(remoteStream, options);
mediaRecorder.ondataavailable = function (e) {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
};

mediaRecorder.onstop = function (e) {
const blob = new Blob(recordedChunks, { type: 'video/mp4' });
recordedChunks = [];
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = url;
a.download = agent_id + '_recorded_' + getCurDateStringWithFormat('yyyy-MM-dd hh:mm:ss') + '.mp4';
a.click();
window.URL.revokeObjectURL(url);
// const index =findNthIndex(str,"/",3);
// let newurl = str.slice(index, str.length-1)+".mp4";
// console.log(newurl)
};

mediaRecorder.start();
};

function stopRecording (){
console.log("stopRecording")
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
}
};
function getCurDateStringWithFormat(fmt) {
    //yyyy-MM-dd hh:mm:ss 或者 yyyy-MM-dd
    let date = new Date();
    let o = { 
        'M+': date.getMonth() + 1,                 //月份 
        'd+': date.getDate(),                    //日 
        'h+': date.getHours(),                   //小时 
        'm+': date.getMinutes(),                 //分 
        's+': date.getSeconds(),                 //秒 
        'q+': Math.floor((date.getMonth() + 3) / 3), //季度 
        'S': date.getMilliseconds()             //毫秒 
    }; 
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); 
    }
    for (let k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
        }
    }
    return fmt; 
}

// 屏幕共享
function share_screen() {
  return new Promise(function (resolve,reject) {
    let option = {
      audio: true,
      video: true,
      screen: true,
    };
    localStreamScreen = RTC.createStream(option);
    ls_vt = localStream_1.getVideoTracks()[0];
    localStreamScreen.isAdapterDevice = true;
    //该回调通知应用已获取本地摄像头／麦克风使用权限。
    localStreamScreen.on(RTC.Events.AccessAllowed, event => {
    });
    //该回调通知应用已禁止本地摄像头／麦克风使用权限
    localStreamScreen.on(RTC.Events.AccessDenied, event => {
    });
    //该回调通知应用屏幕共享已停止
    localStreamScreen.on(RTC.Events.StopScreenSharing, streamId => {
      var pc = sessionall.sessionDescriptionHandler.peerConnection;
      let svt = localStreamScreen.getVideoTrack();
      localStream_1.removeTrack(svt)
      localStream_1.addTrack(ls_vt)
      pc.getSenders().forEach(sender => {
        if (sender.track.kind == 'video') {
            sender.replaceTrack(ls_vt)
        }
      });
      if (window.stop_screen_back){
        stop_screen_back()
      }
    });

    //1080p_2高清  720p_2较清晰  480p_2不太清晰
    // if(true) {
    //     localStreamScreen.setScreenProfile('720p_2');
    // }else{
    //     localStreamScreen.setScreenProfile('480p_2');
    // }
    localStreamScreen.setScreenProfile('720p_2');
    localStreamScreen.init(() => {
      var pc = sessionall.sessionDescriptionHandler.peerConnection;
      let svt = localStreamScreen.getVideoTrack();
      localStream_1.removeTrack(ls_vt)
      localStream_1.addTrack(svt)
      pc.getSenders().forEach(sender => {
        if (sender.track.kind == 'video') {
            sender.replaceTrack(svt)
            resolve(true)
        }
      });
  }, err => {
    reject(err)
  });
  })
}
// 停止共享
function stop_screen() {
  return new Promise(function (resolve,reject) {
    var pc = sessionall.sessionDescriptionHandler.peerConnection;
    let svt = localStream_1.getVideoTracks()[0];
    localStream_1.removeTrack(svt)
    localStream_1.addTrack(ls_vt)
    pc.getSenders().forEach(sender => {
      if (sender.track.kind == 'video') {
          sender.replaceTrack(ls_vt)
          svt.stop();
          resolve(true)
      }
    });
  })
}
// 切换成视频流
function switch_video(){
  hasVideo = true
  var pc = sessionall.sessionDescriptionHandler.peerConnection;
  pc.getReceivers().forEach(function (receiver) {
    var track = receiver.track;
    if (track) {
        if (hasVideo && track.kind == 'video'){
          remoteStream.addTrack(track);
        }
    }
});
}
/**
 * 虚拟背景相关
 */
var model = {
  architecture: 'MobileNetV1',
  outputStride: 16,   //8,16  值越小，输出分辨率越大，模型越精确，速度越慢
  multiplier: 0.75,   // 0.5,0.75,1  值越大，层越大，模型越精确，速度越慢
  quantBytes: 2    /* 1,2,4  此参数控制用于权重量化的字节  
                     '4. 每个浮点数 4 个字节（无量化）。最高精度&原始模型尺寸',
                     '2. 每个浮点数 2 个字节。精度略低，模型尺寸减小 2 倍',
                     '1. 每个浮点数 1 个字节。精度降低, 模型尺寸减少 4 倍' 
                   */
}
let net = null
let flag = false
var refVirtua = null
bodyPix.load(model).then(res=>{
  net = res
})

function blurBackground(){
  const img = document.getElementById('localVideo')  // 获取视频帧
  let videoCanvas =  document.getElementById('backgroundImg')
  videoCanvas.style.display = 'block'
  let segmentation = null   
  net.segmentPerson(img).then(res =>{
      segmentation = res
      bodyPix.drawBokehEffect(
          videoCanvas, img, segmentation, 2,
          2, false);
  })
  let stream = videoCanvas.captureStream(15)
  let track = stream.getVideoTracks()[0]
  var pc = sessionall.sessionDescriptionHandler.peerConnection;
  pc.getSenders().forEach(sender => {
    if (sender.track.kind == 'video' && sender.track.readyState != 'ended') {
        sender.replaceTrack(track)
    }
  });
  if(vague) {
    setTimeout(()=>{
      blurBackground()
    },30)
  } else {
    videoCanvas.style.display = 'none'
    let track = localStream_1.getVideoTracks()[0]
    pc.getSenders().forEach(sender => {
      if (sender.track.kind == 'video' && sender.track.readyState != 'ended') {
          sender.replaceTrack(track)
      }
    });
  }
}
function startBlurBackground(){
  vague = true
  blurBackground()
}
function stopBlurBackground(){
  vague = false
}
function startVirtua(imgURL){
  backgroundImgUrl = imgURL
  virtua = true
  replaceBackground()
}
function stopVirtua(){
  backgroundImgUrl = ''
  virtua = false
}
function replaceBackground() {
  const img = document.getElementById('localVideo')  // 获取视频帧
  let videoCanvas =  document.getElementById('backgroundImg')
  videoCanvas.style.display = 'block'
  let segmentation = null
  const foregroundColor = { r: 0, g: 0, b: 0, a: 0 }    // 前景色  设为完全透明
  const backgroundColor = { r: 0, g: 0, b: 0, a: 255 }   // 背景色
  var backgroundImg = new Image();  
  backgroundImg.src= backgroundImgUrl
  let backgroundDarkeningMask  = null
  net.segmentPerson(img).then(res =>{
      segmentation = res
      backgroundDarkeningMask  = bodyPix.toMask(
          segmentation,
          foregroundColor,
          backgroundColor
        )
      let context = videoCanvas.getContext('2d')
      // 合成
      context.putImageData(backgroundDarkeningMask , 0, 0)
      context.globalCompositeOperation = 'source-in' // 新图形只在重合区域绘制
      context.drawImage(backgroundImg, 0, 0, videoCanvas.width, videoCanvas.height)
      context.globalCompositeOperation = 'destination-over' // 新图形只在不重合的区域绘制
      context.drawImage(img, 0, 0, videoCanvas.width, videoCanvas.height)
      context.globalCompositeOperation = 'source-over' // 恢复
      let stream = videoCanvas.captureStream(15)
      let track = stream.getVideoTracks()[0]
      var pc = sessionall.sessionDescriptionHandler.peerConnection;
      pc.getSenders().forEach(sender => {
        if (sender.track.kind == 'video' && sender.track.readyState != 'ended') {
           try {
            sender.replaceTrack(track)
           } catch (err){
              console.log(err)
           }
        }
      });
      if(virtua) {
        setTimeout(()=>{
          replaceBackground()
        },30)
      } else {
        videoCanvas.style.display = 'none'
        let track = localStream_1.getVideoTracks()[0]
        pc.getSenders().forEach(sender => {
          if (sender.track.kind == 'video' && sender.track.readyState != 'ended') {
              sender.replaceTrack(track)
          }
        });
      }
  })
}

/*虚拟背景结束

**/

//ajax封装
function ajax({ type, url, data, success }) {
  let xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      let res = xhr.responseText;
      // res 是服务器返回的结果
      getAgentListXhr = null
      success(res);
    } 
  }
  if (url.indexOf('get-agent-list') >-1){
    if (getAgentListXhr){
      getAgentListXhr.abort();
    }
    getAgentListXhr = xhr
  }
  // 需要把传递进来的对象，转成字符串格式
  let arr = [];
  for (let key in data) {
    // key 表示键：id | appkey | bookname
    // data[key] 表示值： 1 | laotang | zs
    arr.push(key + '=' + data[key]);  // 'id=1'
  }
  let str = arr.join('&');
  // 判断是什么请求方式
  if (type === 'GET') {
    xhr.open(type, url + '?' + str);
    if (token){
      xhr.setRequestHeader('SDK-TOKEN', token);
    }
    xhr.send();
  } else if (type === 'POST') {
    xhr.open(type, url);
    if (token){
      xhr.setRequestHeader('SDK-TOKEN', token);
    }
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.send(JSON.stringify(data));
  }
}


// 切换设备相关

function swithc_mic(deviceId){
  var pc = sessionall.sessionDescriptionHandler.peerConnection;
  var constraints = {
    audio: {deviceId},
    video: false
  }
  navigator.mediaDevices.getUserMedia(constraints).then(stream => {
      let svt = localStream_1.getAudioTracks()[0];
      localStream_1.removeTrack(svt)
      pc.getSenders().forEach(sender => {
          localStream_1.getAudioTracks()[0].replaceTrack(stream.getAudioTracks()[0])
          if (sender.track.kind == 'audio') {
            sender.replaceTrack(stream.getAudioTracks()[0])
            localStream_1.addTrack(stream.getAudioTracks()[0])
          }
      });
  }).catch(error => {
      console.error('切换视频，失败原因：', error)
  });
}
function swithc_cameras(deviceId){
  var pc = sessionall.sessionDescriptionHandler.peerConnection;
  var constraints = {
    audio: false,
    video: {deviceId}
  }
  navigator.mediaDevices.getUserMedia(constraints).then(stream => {
      let svt = localStream_1.getVideoTracks()[0];
      localStream_1.removeTrack(svt)
      pc.getSenders().forEach(sender => {
          if (sender.track.kind == 'video') {
            sender.replaceTrack(stream.getVideoTracks()[0])
            localStream_1.addTrack(stream.getVideoTracks()[0])
          }
      });
  }).catch(error => {
      console.error('切换视频，失败原因：', error)
  });
}
function swithc_speaker(deviceId){
  let basic_four_audio = document.getElementById('remoteVideo');
  basic_four_audio.setSinkId(deviceId);
}
function closeAllStream(){
  if (localStream_1){
    const tracks = localStream_1.getTracks();
    tracks.forEach(track => track.stop());
    localStream_1 = null
  }
  if (remoteStream){
    const tracks = remoteStream.getTracks();
    tracks.forEach(track => track.stop());
    remoteStream = null
  }
  if (switchStream){
    const tracks = switchStream.getTracks();
    tracks.forEach(track => track.stop());
    switchStream = null
  }
  if (localStreamScreen && localStreamScreen.stop){
    localStreamScreen.stop()
    localStreamScreen = null
  }
}

function getCameras() {
  return new Promise(function (resolve, reject) {
      navigator.mediaDevices.enumerateDevices().then(deviceInfos => {
          let datas = [];
          for (let i = 0; i !== deviceInfos.length; ++i) {
              let deviceInfo = deviceInfos[i];
              if (deviceInfo.kind === 'videoinput') {
                  let mediaDeviceInfo = {};
                  mediaDeviceInfo.deviceId = deviceInfo.deviceId;
                  mediaDeviceInfo.kind = 'videoinput';
                  mediaDeviceInfo.label = deviceInfo.label;
                  datas.push(mediaDeviceInfo);
              }
          }
          resolve(datas);
      }).catch(function (error) {
          reject([]);
      });
  })
}
getCameras().then(device =>{
  device.forEach(devices => {
      if (devices.deviceId){
          hasCameras = true
          return
      } else {
          hasCameras = false
      }
  });
})