<template>
  <div class="dialer-container">
    <!-- 显示输入的电话号码 -->
    <el-input type="text" v-model="currentPhoneNumber" readonly />
    <div class="dialer-buttons">
      <!-- 循环生成数字按钮 -->
      <el-button
        v-for="number in numbers"
        type="primary"
        :key="number"
        :class="{ 'special-number': number === '1' }"
        @click="appendNumber(number)"
      >
        {{ number }}
      </el-button>
      <audio v-show="false" controls autoplay="autoplay" id="audioCtl"></audio>
    </div>
    <!-- 语音输入按钮 -->
    <el-button type="info" @click="startVoiceInput"> 语音输入 </el-button>
    <!-- 清除输入的电话号码 -->
    <el-button type="warning" @click="clearNumber">清除</el-button>
    <!-- 模拟拨号操作 -->
    <el-button type="success" @click="callNumber">拨号</el-button>
    <!-- 模拟拨号操作 -->
    <el-button type="danger" @click="downNumber">挂断</el-button>
  </div>
</template>
  
  <script>
export default {
  props: {
    phoneNumber: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      id: this.generateGuid(),
      baseUrl: "api/webrtc/",
      pc: null,
      // 拨号盘上的数字和符号
      numbers: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"],
    };
  },
  computed: {
    getOfferUrl() {
      return `${this.baseUrl}getoffer?id=${this.id}`;
    },
    setAnswerUrl() {
      return `${this.baseUrl}setanswer?id=${this.id}`;
    },
    setIceCandidateUrl() {
      return `${this.baseUrl}addicecandidate?id=${this.id}`;
    },
    currentPhoneNumber: {
      get() {
        return this.phoneNumber;
      },
      set(value) {
        // 当输入框的值改变时，通过自定义事件将新值传递给父组件
        this.$emit("update:phoneNumber", value);
      },
    },
  },
  methods: {
    appendNumber(number) {
      this.currentPhoneNumber += number;
    },
    clearNumber() {
      this.currentPhoneNumber = "";
    },
    callNumber() {
      if (this.currentPhoneNumber) {
        alert(`正在拨打号码: ${this.currentPhoneNumber}`);
        this.start();
      } else {
        alert("请输入电话号码");
      }
    },
    downNumber() {
      this.closePeer();
    },
    startVoiceInput() {
      const recognition = new (window.SpeechRecognition ||
        window.webkitSpeechRecognition)();
      recognition.lang = "zh-CN";

      recognition.onresult = (event) => {
        const transcript = event.results[0][0].transcript;
        this.currentPhoneNumber = transcript.replace(/[^0-9*#]/g, "");
      };
      recognition.start();
    },

    generateGuid() {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
        /[xy]/g,
        function (c) {
          var r = (Math.random() * 16) | 0,
            v = c == "x" ? r : (r & 0x3) | 0x8;
          return v.toString(16);
        }
      );
    },
    async start() {
      this.closePeer();

      let videoControl = document.querySelector("#audioCtl");

      const localStream = await navigator.mediaDevices.getUserMedia({
        video: false,
        audio: true,
      });
      videoControl.srcObject = localStream;

      this.pc = new RTCPeerConnection(null);

      localStream.getTracks().forEach((track) => {
        console.log("add local track " + track.kind + " to peer connection.");
        console.log(track);
        this.pc.addTrack(track, localStream);
      });

      this.pc.onicegatheringstatechange = function () {
        console.log("onicegatheringstatechange: " + this.pc.iceGatheringState);
      }.bind(this);

      this.pc.oniceconnectionstatechange = function () {
        console.log(
          "oniceconnectionstatechange: " + this.pc.iceConnectionState
        );
      }.bind(this);

      this.pc.onsignalingstatechange = function () {
        console.log("onsignalingstatechange: " + this.pc.signalingState);
      }.bind(this);

      this.pc.onicecandidate = async function (event) {
        if (event.candidate) {
          console.log("new-ice-candidate:");
          console.log(event.candidate.candidate);
          console.log(event.candidate);
          await fetch(this.setIceCandidateUrl, {
            method: "POST",
            body: JSON.stringify(event.candidate),
            headers: { "Content-Type": "application/json" },
          });
        }
      }.bind(this);

      let offerResponse = await fetch(this.getOfferUrl);
      let offer = await offerResponse.json();
      console.log("got offer: " + offer.type + " " + offer.sdp + ".");
      await this.pc.setRemoteDescription(offer);

      this.pc
        .createAnswer()
        .then(
          function (answer) {
            return this.pc.setLocalDescription(answer);
          }.bind(this)
        )
        .then(
          async function () {
            console.log("Sending answer SDP.");
            console.log("SDP: " + this.pc.localDescription.sdp);
            await fetch(this.setAnswerUrl, {
              method: "POST",
              body: JSON.stringify(this.pc.localDescription),
              headers: { "Content-Type": "application/json" },
            });
          }.bind(this)
        );
    },
    closePeer() {
      if (this.pc != null) {
        console.log("close peer");
        this.pc.close();
      }
    },
  },
};
</script>
  
  <style scoped>
.dialer-container {
  margin: 20px auto;
  width: 300px;
  text-align: center;
  font-weight: bold; /* 文字加粗 */
}
.dialer-buttons {
  margin: 10px auto;
  display: grid;
  grid-template-columns: repeat(3, 3fr);
  gap: 4px;
}

.dialer-buttons button {
  padding: 10px;
  font-size: 20px;
}

button {
  font-size: 20px;
  margin: 5px;
}

/* 定义数字 1 的特殊样式 */
.special-number {
  margin-left: 10px;
  color: #ffffff; /* 文字颜色为白色 */
}
</style>