<template>
  <div class="audio-wrapper">
    <div v-if="'big' === viewSize" class="audio-big">
      <div class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
      <div v-if="showSlider" class="slider-area">
        <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
        <el-slider
          v-model="play_value"
          class="audio-slider"
          :format-tooltip="formatProcessToolTip"
          @change="changeCurrentTime"
        />
        <span class="audio-time">{{ audio_allTime }}</span>
      </div>
      <div class="audio-icon">
        <SvgIcon icon-class="pre" size="12" @click="changeFile('prev')" />
        <SvgIcon :icon-class="iconClass" size="26" @click="playAudio" />
        <SvgIcon icon-class="next" size="12" @click="changeFile('next')" />
      </div>
    </div>
    <div v-else-if="'middle' === viewSize" class="audio-middle">
      <div class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
      <div class="slider-area">
        <SvgIcon :icon-class="iconClass" size="18" @click="playAudio" />
        <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
        <el-slider
          v-model="play_value"
          class="audio-slider"
          :format-tooltip="formatProcessToolTip"
          @change="changeCurrentTime"
        />
        <span class="audio-time">{{ audio_allTime }}</span>
      </div>
    </div>
    <div v-else-if="'small' === viewSize" class="audio-icons">
      <span>{{ audioIndex + 1 }}.</span>
      <span class="icon-box">
        <SvgIcon
          :icon-class="iconClass"
          size="14"
          :style="{ marginLeft: audio.paused ? '4px' : '0' }"
          @click="playAudio"
        />
      </span>
    </div>
    <div v-else :class="['audio-list', audioIndex === curAudioIndex ? 'active' : '']">
      <div class="active-mark">
        <SvgIcon v-if="audioIndex === curAudioIndex" icon-class="paused" size="12" style="cursor: default" />
      </div>
      <span class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</span>
      <span class="audio-time">{{ audio_allTime }}</span>
    </div>

    <audio
      :id="fileId"
      :ref="fileId"
      :src="url"
      preload="metadata"
      @loadedmetadata="onLoadedmetadata"
      @timeupdate="onTimeupdate"
      @canplaythrough="oncanplaythrough"
    ></audio>
  </div>
</template>

<script>
import { GetFileURLMap } from '@/api/app';
import { secondFormatConversion } from '@/utils/transform';

export default {
  name: 'AudioPlay',
  props: {
    fileId: {
      type: String,
      required: true,
    },
    fileName: {
      type: String,
      default: '',
    },
    viewSize: {
      type: String,
      required: true,
    },
    viewMethod: {
      type: String,
      default: 'independent',
    },
    audioIndex: {
      type: Number,
      default: 0,
    },
    curAudioIndex: {
      type: Number,
      default: 0,
    },
    showSlider: {
      type: Boolean,
      default: false,
    },
    // 是否显示音频进度条
    showProgress: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      secondFormatConversion,
      url: '',
      audio: {
        paused: true,
        playing: false,
        // 音频当前播放时长
        current_time: 0,
        // 音频最大播放时长
        max_time: 0,
        isPlaying: false,
        loading: false,
      },
      play_value: 0,
      audio_allTime: null, // 展示总时间
    };
  },
  computed: {
    iconClass() {
      return this.audio.paused ? 'paused' : 'playing';
    },
  },
  watch: {
    fileId: {
      handler(val) {
        if (!val) return;
        GetFileURLMap({ file_id_list: [val] }).then(({ url_map }) => {
          this.url = url_map[val];
        });
      },
      immediate: true,
    },
  },
  mounted() {
    if (!this.fileId) return;
    this.$refs[this.fileId].addEventListener('ended', () => {
      this.audio.paused = true;
    });
    this.$refs[this.fileId].addEventListener('pause', () => {
      this.audio.paused = true;
    });
    this.$refs[this.fileId].addEventListener('play', () => {
      this.audio.paused = false;
    });
  },
  methods: {
    playAudio() {
      if (!this.url) return;
      const audio = this.$refs[this.fileId];
      let audioArr = document.getElementsByTagName('audio');
      if (audioArr && audioArr.length > 0) {
        for (let i = 0; i < audioArr.length; i++) {
          if (audioArr[i].src === this.url) {
            if (audioArr[i].id !== this.fileId) {
              audioArr[i].pause();
            }
          } else {
            audioArr[i].pause();
          }
        }
      }
      audio.paused ? audio.play() : audio.pause();
    },
    // 进度条格式化toolTip
    formatProcessToolTip(index) {
      let _index = parseInt((this.audio.max_time / 100) * index);
      return secondFormatConversion(_index);
    },
    // 点击 拖拽播放音频
    changeCurrentTime(value) {
      let audioId = this.fileId;
      this.$refs[audioId].play();
      this.audio.playing = true;
      this.$refs[audioId].currentTime = parseInt((value / 100) * this.audio.max_time);
    },
    // 音频加载完之后
    onLoadedmetadata(res) {
      this.audio.max_time = parseInt(res.target.duration);
      this.audio_allTime = secondFormatConversion(this.audio.max_time);
    },
    // 当音频当前时间改变后，进度条也要改变
    onTimeupdate(res) {
      let audioId = this.fileId;
      this.audio.current_time = res.target.currentTime;
      this.play_value = (this.audio.current_time / this.audio.max_time) * 100;
      if (this.audio.current_time * 1000 > this.ed) {
        this.$refs[audioId].pause();
      }
    },
    onTimeupdateTime(res, playFlag) {
      if (!res && res !== 0) return;
      let audioId = this.audioId;
      this.$refs[audioId].currentTime = res;
      this.play_value = (res / this.audio.max_time) * 100;
      if (playFlag) {
        let audio = document.getElementsByTagName('audio');
        audio.forEach((item) => {
          if (item.id !== audioId) {
            item.pause();
          }
        });
        this.$refs[audioId].play();
      }
    },
    oncanplaythrough() {
      this.audio.loading = false;
    },
    changeFile(type) {
      this.$emit('changeFile', type);
    },
  },
};
</script>

<style lang="scss" scoped>
.audio-wrapper {
  .audio-time {
    white-space: nowrap;
  }

  .audio-big {
    display: flex;
    flex-direction: column;
    padding: 12px 16px;
    text-align: center;

    .audio-name {
      padding: 8px;
      margin-bottom: 8px;
      font-size: 14px;
      background-color: #eee;
      border-radius: 4px;
    }

    .audio-icon {
      display: flex;
      column-gap: 32px;
      align-items: center;
      justify-content: center;

      .svg-icon {
        cursor: pointer;
      }
    }
  }

  .audio-middle {
    width: 280px;
    padding: 12px 16px;
    background-color: #f8f8f8;
    border: 1px solid #e7e7e7;
    border-radius: 4px;

    .audio-name {
      padding: 8px;
      margin-bottom: 8px;
      font-size: 14px;
      text-align: center;
      background-color: #eee;
      border-radius: 4px;
    }
  }

  .audio-icons {
    display: flex;
    column-gap: 10px;
    align-items: center;

    .icon-box {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 40px;
      height: 40px;
      cursor: pointer;
      background-color: #076aff;
      border-radius: 20px;

      .svg-icon {
        color: #fff;
      }
    }
  }

  .audio-list {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 24px 8px 16px;

    &.active {
      background-color: #f4f9ff;
    }

    .active-mark {
      width: 20px;
      height: 28px;

      .svg-icon {
        color: #076aff;
      }
    }

    .audio-name {
      flex: 1;
    }
  }

  .slider-area {
    display: flex;
    column-gap: 16px;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;

    .audio-slider {
      width: 90%;

      :deep .el-slider__runway {
        height: 4px;
        background-color: #fff;
      }

      :deep .el-slider__button {
        width: 4px;
        height: 4px;
        margin-top: -1px;
        border: none;
      }

      :deep .el-slider__bar {
        height: 4px;
        background-color: #076aff;
      }
    }
  }
}
</style>
