<template>
  <!-- 表单渲染 -->
  <el-dialog append-to-body :close-on-click-modal="false" destroy-on-close :before-close="cancelView" :visible="visible" :title="title" width="520px">
    <div v-show="status" class="corrugation">
      <span style="--d: 7"></span>
      <span style="--d: 6"></span>
      <span style="--d: 5"></span>
      <span style="--d: 4"></span>
      <span style="--d: 3"></span>
      <span style="--d: 2"></span>
      <span style="--d: 1"></span>
      <span style="--d: 0"></span>
      <span style="--d: 1"></span>
      <span style="--d: 2"></span>
      <span style="--d: 3"></span>
      <span style="--d: 4"></span>
      <span style="--d: 5"></span>
      <span style="--d: 6"></span>
      <span style="--d: 7"></span>
    </div>
    <div v-show="!status" class="corrugation-s">
      <span style="--d: 7"></span>
      <span style="--d: 6"></span>
      <span style="--d: 5"></span>
      <span style="--d: 4"></span>
      <span style="--d: 3"></span>
      <span style="--d: 2"></span>
      <span style="--d: 1"></span>
      <span style="--d: 0"></span>
      <span style="--d: 1"></span>
      <span style="--d: 2"></span>
      <span style="--d: 3"></span>
      <span style="--d: 4"></span>
      <span style="--d: 5"></span>
      <span style="--d: 6"></span>
      <span style="--d: 7"></span>
    </div>
    <div style="text-align: center">
      <i v-if="status" class="el-icon-phone-outline el-icon--left" />
      <i v-else class="el-icon-phone el-icon--left" />
      {{message}}
    </div>
    <audio id="audioElement"></audio>
    <audio id="localVideo"></audio>
    <div slot="footer" class="dialog-footer" style="text-align: center">
      <el-button type="success" style="width:120px;font-size:20px" @click="uaCall">拨号<i class="el-icon-video-play el-icon--right"></i></el-button>
      <el-button type="danger" style="width:120px;font-size:20px" @click="uaHangup">挂断<i class="el-icon-video-pause el-icon--right"></i></el-button>
      <el-button style="width:120px;font-size:20px" @click="cancelView">关闭<i class="el-icon-circle-close el-icon--right"></i></el-button>
    </div>
  </el-dialog>
</template>
<script>
import {HttpReq} from '@/assets/js/common.js';
import JsSIP from 'jssip'

export default {
  data() {
    return {
      visible: false,
      title: '安全帽语音通话',
      userAgent: null,
      session: null,
      uaSipInfo: {},
      status: 0,
      isReady: false,
      message: '正在建立链接，等待服务器响应...'
    }
  },
  mounted() {
    this.$nextTick(() => {

    })
  },
  methods: {
    uaRegister() {
      let sip_uri_ = `sip:${this.uaSipInfo.adminsip_id}@${this.uaSipInfo.adminwsip_host}`;
      let sip_password_ = `${this.uaSipInfo.adminsip_pwd}`;
      let ws_uri_ = `${this.uaSipInfo.adminwss_url}`;

      console.info("get input info: sip_uri = ", sip_uri_, " sip_password = ", sip_password_, " ws_uri = ", ws_uri_);

      let socket = new JsSIP.WebSocketInterface(ws_uri_);
      let configuration = {
        sockets: [socket],
        uri: sip_uri_,
        password: sip_password_,
        session_timers: false, // 启用会话计时器（根据RFC 4028)
        user_agent: "Aegis WebRTC v1.0",
        contact_uri: sip_uri_,
        autostart: true, // 自动连接
        register: true, // 自动就绪
      };

      this.userAgent = new JsSIP.UA(configuration);

      this.userAgent.on("connecting", (args) => {
        this.message = `开始尝试连接...`;
        console.info("开始尝试连接", args);
      });
      this.userAgent.on('registered', (data) => {
        console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase);
        this.message = `已接通到服务器，监测到对方安全帽在线，请拨号...`;
        this.isReady = true
      });
      this.userAgent.on('registrationFailed', (data) => {
        console.log("registrationFailed, ", data);
      });
      this.userAgent.on('registrationExpiring', () => {
        console.warn("registrationExpiring");
      });
      this.userAgent.on('newRTCSession', (e) => {
        this.message = `注意：您有新的${e.originator === "local" ? "外呼" : "来电"}`;
        console.log(`新的${e.originator === "local" ? "外呼" : "来电"}`, e);
        const session = e.session;
        this.session = session;
        const peerconnection = session.connection;
        if (e.originator === "local") {
          // 打电话
          peerconnection.addEventListener("addstream", (event) => {
            const audio = document.getElementById("audioElement");
            audio.srcObject = event.stream;
          });

        } else {
          document.getElementById("localVideo").play();
          // 接电话
          this.dialogVisible = true;
          this.isg = true;
          this.callers = session.remote_identity.uri.user;
        }
        // 接通,在这一步可以处理音频播放
        // 接通并不代表对方已经接受，接通代表 滴 滴 滴
        session.on("confirmed", () => {
          console.info("接通中");
          this.message = `已接通，请通话...`;
          this.status = 1;
          const audioElement = document.getElementById("audioElement");
          audioElement.autoplay = true;
          const stream = new MediaStream();
          const receivers = session.connection.getReceivers();
          if (receivers) {
            receivers.forEach((receiver) => stream.addTrack(receiver.track));
          }
          audioElement.srcObject = stream;
          audioElement.play();
        });

        // 接听失败
        session.on("failed", (mdata) => {
          const myAuto = document.getElementById("localVideo");
          myAuto.pause();
          myAuto.load();
          this.message = `来电的时拒接或,未接听对方就挂断...`;
          console.info("来电的时候 拒接或者 还没接听对方自己就挂断了");
        });

        // 接听成功
        session.on("accepted", (response, cause) => {
          // 嘟嘟嘟
          this.message = `接听成功...`;
          this.status = 1;
          console.info("接听成功");
        });
        // 接听成功后 挂断
        session.on("ended", () => {
          this.dialogVisible = false;
          this.InCall = false;
        });
        // 通话被挂起
        session.on("hold", (data) => {
          const org = data.originator;
          if (org === "local") {
            this.message = `通话被本地挂起...`;
            console.log("通话被本地挂起:", org);
          } else {
            this.message = `通话被对方挂起...`;
            console.log("通话被对方挂起:", org);
          }
        });
        // 通话被继续
        session.on("unhold", (data) => {
          const org = data.originator;
          if (org === "local") {

          } else {
            this.message = `对方要求继续通话...`;
            console.log("对方要求继续通话:", org);
          }
        });
      });

      this.userAgent.on('newMessage', (data) => {
        if (data.originator == 'local') {
          console.info('onNewMessage , OutgoingRequest - ', data.request);
        } else {
          console.info('onNewMessage , IncomingRequest - ', data.request);
        }
      });

      console.info("call register");
      this.userAgent.start();
    },
    uaCall() {
      if(this.isReady || this.userAgent){
        let sip_phone_number_ = `sip:${this.uaSipInfo.sip_id}@${this.uaSipInfo.adminwsip_host}`;
        let options = {
          'pcConfig': {
            'rtcpMuxPolicy': "negotiate",
          },
          'rtcOfferConstraints': {
            'offerToReceiveAudio': '1',
            'offerToReceiveVideo': '0',
          },
          'eventHandlers': {
            'progress': (e) => {
              console.log('call is in progress');
            },
            'failed': (e) => {
              console.log('call failed: ', e);
            },
            'ended': (e) => {
              console.log('call ended : ', e);
              console.log('通话结束');
              this.message = `通话结束...`
              this.status = 0
              this.isReady = false
            },
            'confirmed': (e) => {
              console.log('call confirmed');
            }
          },
          'mediaConstraints': {
            'audio': true,
            'video': false,
          },
        };
        this.userAgent.call(sip_phone_number_, options);
      } else {
        this.$message({
          message: "尚未建立链接无法拨号通话，请确保链接通畅且对方在线！",
          type: 'error'
        });
      }
    },
    uaHangup() {
      if(this.isReady || this.userAgent){
        console.log('主动挂断')
        this.userAgent.terminateSessions();
        const myAuto = document.getElementById("localVideo");
        myAuto.pause();
        myAuto.load();
        const audioElement = document.getElementById("audioElement");
        audioElement.pause();
        audioElement.load();
      }
    },
    init(safetyhatmac) {
      this.showView()
      this.message = '正在建立链接，等待服务器响应...'
      HttpReq.truckDispatching.propleGetSipInfo({safetyhatmac}).then((res) => {
        if(res.data){
          this.uaSipInfo = res.data;
          if(!this.uaSipInfo.sip_id){
            this.message = '对方安全帽未在线，无法通话！！'
          } else {
            this.uaRegister()
          }
        }else{
          this.message = '服务器通信失败！！'
          this.$notify({
            title: res.msg,
            type: 'error',
          });
        }
      })
    },
    showView() {
      this.visible = true
    },
    hideView() {
      this.visible = false
      this.uaHangup()
    },
    cancelView() {
      this.hideView()
    }
  },
  beforeDestroy() {
    this.hideView()
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.corrugation-s {
  height: 80px;
  width: 118px;
  margin: auto;
  display: flex;
  align-items: center;
  position: relative;
}
.corrugation-s span {
  background: linear-gradient(to top, #d299c2 0%, #fef9d7 100%);
  width: 4px;
  height: 60%;
  border-radius: 4px;
  margin-right: 4px;
}
.corrugation-s span:last-child {
  margin-right: 0;
}
.corrugation {
  height: 80px;
  width: 118px;
  margin: auto;
  display: flex;
  align-items: center;
  position: relative;
}
.corrugation span {
  background: linear-gradient(to top, #d299c2 0%, #fef9d7 100%);
  width: 4px;
  height: 20%;
  border-radius: 10px;
  margin-right: 4px;
  animation: loading 2.5s infinite linear;
  animation-delay: calc(0.2s * var(--d));
}
.corrugation span:last-child {
  margin-right: 0;
}
@keyframes loading {
  0% {
    background-image: linear-gradient(to right, #fa709a 0%, #fee140 100%);
    height: 20%;
    border-radius: calc(var(--h) * 0.2 * 0.5);
  }
  50% {
    background-image: linear-gradient(to top, #d299c2 0%, #fef9d7 100%);
    height: 100%;
    border-radius: calc(var(--h) * 1 * 0.5);
  }
  100% {
    background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);
    height: 20%;
    border-radius: calc(var(--h) * 0.2 * 0.5);
  }
}
</style>
