<template>
  <div class="record">
    <template v-if="type === 'normal' || type === 'mini'">
      <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone"></div>
      <span
        v-if="type && type == 'normal'"
        :class="[
          'record-time',
          microphoneStatus ? 'record-ing' : '',
          selectIndex || selectIndex == 0 ? 'record-black' : '',
          type && type == 'normal' ? 'record-time-flex' : '',
        ]"
        >{{ isPlaying ? '-' : '' }}{{ handleDateTime(recordtime) }}</span
      >
      <div
        :class="['playBack', hasMicro]"
        @click="playmicrophone(selectIndex || selectIndex == 0 ? recordList[selectIndex].toltime : '')"
      ></div>
    </template>
    <template v-else-if="type === 'pro'">
      <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone"></div>
      <el-select v-model="selectIndex" placeholder="无录音" class="proSelect" @change="handleChangeRecord">
        <el-option v-for="(item, i) in recordList" :key="i + item.id" :label="item.name" :value="i" />
      </el-select>
      <div
        :class="['playBack', hasMicro]"
        @click="playmicrophone(selectIndex || selectIndex == 0 ? recordList[selectIndex].toltime : '')"
      ></div>
      <a :class="['record-delete', hasMicro ? 'record-delete-has' : '']" @click="handleDelete"></a>
    </template>
    <template v-else>
      <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone"></div>
      <span
        :class="[
          'record-time',
          microphoneStatus ? 'record-ing' : '',
          selectIndex || selectIndex == 0 ? 'record-black' : '',
        ]"
        >{{ isPlaying ? '-' : '' }}{{ handleDateTime(recordtime) }}</span
      >
      <el-select v-model="selectIndex" placeholder="无录音" @change="handleChangeRecord">
        <el-option v-for="(item, i) in recordList" :key="i + item.id" :label="item.name" :value="i" />
      </el-select>
      <div
        :class="['playBack', hasMicro]"
        @click="playmicrophone(selectIndex || selectIndex == 0 ? recordList[selectIndex].toltime : '')"
      ></div>
      <a :class="['record-delete', hasMicro ? 'record-delete-has' : '']" @click="handleDelete"></a>
    </template>
  </div>
</template>

<script>
import Recorder from 'js-audio-recorder'; // 录音插件

export default {
  props: {
    wavData: {
      type: Object,
      default: () => {},
    },
    // 类型 normal pro mini promax
    type: {
      type: String,
      default: '',
    },
    fileName: {
      type: String,
      default: '',
    },
    selectData: {
      type: Object,
      default: () => {},
    },
    answerRecordList: {
      type: Array,
      default: () => [],
    },
    index: {
      type: Number,
      default: 0,
    },
    taskModel: {
      type: String,
      default: '',
    },
    tmIndex: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      recorder: new Recorder({
        sampleBits: 16, // 采样位数，支持 8 或 16，默认是16
        sampleRate: 16000, // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
        numChannels: 1, // 声道，支持 1 或 2， 默认是1
      }),
      microphoneStatus: false,
      hasMicro: '', // 录音后的样式class
      wavblob: null,
      audio: new window.Audio(),
      recordList: [], // 录音文件数组
      recordtime: 0, // 录音时长
      timer: null, // 计时器
      recordFile: 1, // 录音文件名
      selectIndex: null, // 选中的录音索引
      oldIndex: null, // 存储播放录音索引
      playtime: 0, // 播放时间
      isPlaying: false,
    };
  },
  computed: {
    modelNotAnswer() {
      return !this.taskModel || this.taskModel !== 'ANSWER';
    },
  },
  watch: {
    answerRecordList(newVal) {
      this.recordList = JSON.parse(JSON.stringify(newVal));
      this.oldIndex = null;
      this.selectIndex = this.recordList.length > 0 ? this.recordList.length - 1 : null;
      if (this.recordList.length > 0 && this.type === 'normal') {
        this.recordtime = this.recordList[this.selectIndex].toltime;
        this.wavblob = this.recordList[this.selectIndex].wavData;
        this.changeStatus('normal');
      }
    },
  },
  created() {
    this.handleActive();
    window.stopAudioSound = () => {
      if (this.audio) {
        this.audio.pause();
      }
    };
  },
  mounted() {
    this.recordList = this.answerRecordList ? JSON.parse(JSON.stringify(this.answerRecordList)) : [];
    if (this.recordList.length > 0) {
      this.selectIndex = 0;
      this.$emit('getSelectData', this.recordList[0].selectData);
      this.recordFile = this.recordList.length + 1;
      this.handleChangeRecord(0);
    }
    this.audio.addEventListener('play', () => {
      this.changeStatus('active');
      this.isPlaying = true;
    });
    this.audio.addEventListener('pause', () => {
      this.changeStatus('normal');
    });
    this.audio.addEventListener('ended', () => {
      this.changeStatus('normal');
      this.isPlaying = false;
    });
  },
  beforeDestroy() {
    this.audio.pause();
  }, // 生命周期 - 销毁之前
  methods: {
    // 开始录音
    microphone() {
      if (!this.taskModel || this.taskModel !== 'ANSWER') {
        if (this.microphoneStatus) {
          this.hasMicro = 'normal';
          this.recorder.stop();
          this.$root.isRecording = false;
          clearInterval(this.timer);
          let toltime = this.recorder.duration; // 录音总时长
          let fileSize = this.recorder.fileSize; // 录音总大小
          // 录音结束，获取取录音数据
          let wav = this.recorder.getWAVBlob(); // 获取 WAV 数据
          // this.wavblob = wav;
          this.microphoneStatus = false;
          let reader = new window.FileReader();
          reader.readAsDataURL(wav);
          reader.onloadend = () => {
            this.recordList[this.selectIndex].wavData = reader.result;
            this.recordList[this.selectIndex].toltime = Math.floor(toltime);
            this.recordList[this.selectIndex].fileSize = fileSize;
            this.wavblob = this.recordList[this.selectIndex].wavData;
            this.$emit('getWavblob', this.wavblob);
            this.$emit('handleWav', JSON.parse(JSON.stringify(this.recordList)), this.tmIndex, this.index, this.indexs);
            if (this.recordList[this.selectIndex].selectData) {
              this.$emit('getSelectData', this.recordList[this.selectIndex].selectData);
            }
          };
        } else {
          this.hasMicro = '';
          this.$root.isRecording = true;
          this.$emit('getWavblob', null);
          this.$emit('getSelectData', { type: '' });
          // 开始录音
          this.recorder.start();
          this.microphoneStatus = true;
          this.recordtime = 0;
          this.isPlaying = false;
          clearInterval(this.timer);
          this.timer = setInterval(() => {
            this.recordtime += 1;
          }, 1000);
          this.$emit('handleParentPlay');
          let obj = {
            name: this.fileName ? this.fileName + this.recordFile : `新录音${this.recordFile}`,
            id: (this.recordFile + Math.round(Math.random() * 10)).toString(),
          };
          if (this.selectData) obj.selectData = this.selectData;
          this.recordList.push(obj);
          this.recordFile += 1;
          this.selectIndex = this.recordList.length - 1;
        }
      }
    },
    playmicrophone(totalTimes) {
      if (this.hasMicro) {
        this.isPlaying = true;
        if (this.selectIndex || this.selectIndex === 0) {
          let totalTime = totalTimes;
          if (!this.audio.paused) {
            this.audio.pause();
            clearInterval(this.timer);
          } else if (this.audio.paused && this.oldIndex === this.selectIndex) {
            this.audio.play();
            if (this.recordtime === 0) {
              this.recordtime = totalTimes;
              this.playtime = 0;
            }
            this.timer = setInterval(() => {
              if (this.playtime < totalTime) {
                this.playtime += 1;
                this.recordtime = totalTime - this.playtime;
              } else {
                clearInterval(this.timer);
              }
            }, 1000);
          } else {
            this.audio.pause();
            this.audio.load();
            this.audio.src = this.wavblob;
            this.oldIndex = this.selectIndex;
            this.audio.play();
            this.playtime = 0;
            this.recordtime = totalTime;
            clearInterval(this.timer);
            this.timer = setInterval(() => {
              if (this.playtime < totalTime) {
                this.playtime += 1;
                this.recordtime = totalTime - this.playtime;
              } else {
                clearInterval(this.timer);
              }
            }, 1000);
          }
        }
      }
    },
    // 高亮初始值
    handleActive() {
      if (this.wavData) {
        this.hasMicro = 'normal';
      } else {
        this.hasMicro = '';
      }
    },
    changeStatus(status) {
      this.hasMicro = status;
    },
    // 格式化录音时长
    handleDateTime(time) {
      let _time = '';
      if (parseInt(time / 60) < 10) {
        _time = `${`0${parseInt(time / 60)}`.substring(`0${parseInt(time / 60)}`.length - 2)}:${`0${
          time % 60
        }`.substring(`0${time % 60}`.length - 2)}`;
      } else {
        _time = `${parseInt(time / 60)}:${`0${time % 60}`.substring(`0${time % 60}`.length - 2)}`;
      }
      return _time;
    },
    handleChangeRecord(index) {
      this.recordtime = this.recordList[index].toltime;
      this.wavblob = this.recordList[index].wavData;
      this.hasMicro = 'normal';
      clearInterval(this.timer);
      this.audio.pause();
      this.oldIndex = null;
      this.$emit('getWavblob', this.wavblob);
      if (this.recordList[index].selectData) this.$emit('getSelectData', this.recordList[index].selectData);
      this.$emit('sentPause', false);
    },
    handleDelete() {
      if (this.hasMicro && (!this.taskModel || this.taskModel !== 'ANSWER')) {
        if (this.selectIndex || this.selectIndex === 0) {
          this.recordList.splice(this.selectIndex, 1);
          this.$emit('handleWav', JSON.parse(JSON.stringify(this.recordList)), this.tmIndex, this.index, this.indexs);
          this.selectIndex = this.recordList.length > 0 ? this.recordList.length - 1 : null;

          this.hasMicro = this.recordList.length > 0 ? 'normal' : '';
          this.recordtime = this.recordList.length > 0 ? this.recordList[this.selectIndex].toltime : 0;
          this.audio.pause();
          this.audio = new window.Audio();
          this.wavblob = this.recordList.length > 0 ? this.recordList[this.selectIndex].wavData : null;
          this.oldIndex = null;
          this.isPlaying = false;
          clearInterval(this.timer);
          this.audio.addEventListener('ended', () => {
            this.changeStatus('normal');
            this.isPlaying = false;
          });
        }
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.record {
  display: flex;
  grid-area: record;
  align-items: center;
  justify-content: center;
  max-width: 160px;
  height: 32px;

  .playBack {
    width: 16px;
    height: 16px;
    margin-left: 8px;
    cursor: pointer;
    background: url('@/assets/voice_matrix/luyin-play.png') center no-repeat;
    background-size: 100%;

    &.normal {
      background: url('@/assets/voice_matrix/luyin-play-active.png') center no-repeat;
      background-size: 100%;
    }

    &.active {
      background: url('@/assets/voice_matrix/luyin-play-stop.png') center no-repeat;
      background-size: 100%;
    }
  }

  .line {
    width: 1px;
    height: 16px;
    margin-left: 8px;
    background: rgba(0, 0, 0, 85%);
    opacity: 0.2;
  }

  .record {
    width: 16px;
    height: 16px;
    cursor: pointer;
    background: url('@/assets/voice_matrix/luyin.png') center no-repeat;
    background-size: 100%;

    &.active {
      background: url('@/assets/voice_matrix/luyin-active.png') center no-repeat;
      background-size: 100%;
    }

    &.active:hover {
      background: url('@/assets/voice_matrix/luyin-stop.png') center no-repeat;
      background-size: 100%;
    }
  }

  .record-time {
    margin-left: 8px;
    font-family: 'robot';
    font-size: 16px;
    line-height: 150%;
    color: rgba(0, 0, 0, 30%);

    &.record-black {
      color: #000;
    }

    &.record-ing {
      color: #de4444;
    }

    &.record-time-flex {
      flex: 1;
    }
  }

  .el-select {
    margin-left: 8px;
  }

  .record-delete {
    display: block;
    width: 16px;
    height: 16px;
    margin-left: 8px;
    background: url('@/assets/voice_matrix/luyin-delete.png') center no-repeat;
    background-size: 100%;

    &.record-delete-has {
      &:hover {
        background: url('@/assets/voice_matrix/luyin-delete-active.png') center no-repeat;
        background-size: 100%;
      }
    }
  }
}
</style>

<style lang="scss">
.record {
  .el-select {
    flex: 1;
    height: 24px;

    &.proSelect {
      width: 78px;
    }

    .el-input__inner {
      box-sizing: border-box;
      height: 24px;
      padding: 0 11px;
      font-family: 'Smartisan';
      font-size: 14px;
      line-height: 22px;
      color: rgba(0, 0, 0, 85%);
      border: 1px solid rgba(0, 0, 0, 10%);
      border-radius: 4px;
    }

    .el-input {
      .el-select__caret {
        display: flex;
        align-items: center;
        justify-content: center;
        color: #000;
      }
    }

    .el-input__icon {
      width: 16px;
    }

    .el-input__suffix {
      right: 3px;
    }
  }
}
</style>
