<script setup>
import { ElMessage } from 'element-plus';

const emit = defineEmits(['loadDone']);

const props = defineProps({
  audioUrl: {
    type: String,
    default: ''
  },
  id: {
    type: Number,
    default: 0
  }
})

const speedList = [
  { label: '3 x', value: 3 },
  { label: '2 x', value: 2 },
  { label: '1.5 x', value: 1.5 },
  { label: '1(正常)', value: 1 },
  { label: '0.5 x', value: 0.5 },
]

const audioUrl = import.meta.env.VITE_AUDIO_BASE_URL;

const isDisabled = ref(true);
const audioRef = ref(null);
const audioIsPlay = ref(true);
const audioStart = ref("00:00");
const durationTime = ref("00:00");
const duration = ref(0);
const currentProgress = ref(0);

watch(() => props.audioUrl, () => {
  audioIsPlay.value = true;
  currentProgress.value = 0;
  audioStart.value = "00:00";
  durationTime.value = "00:00";

  audioRef.value.removeEventListener('loadedmetadata', loadEndEvent);
  audioRef.value.removeEventListener('ended', endAudio);

  calculateDuration();
})

// 控制是否播放
const playAudio = () => {
  if ( isDisabled.value ) {
    return ElMessage({
      message: '提示: 音频播放失败',
      type: 'warning',
    });
  }
  if (audioRef.value.paused) {
    audioRef.value.play();
    audioIsPlay.value = false;
  } else {
    audioRef.value.pause();
    audioIsPlay.value = true;
  }
}

// 根据当前播放时间,实时更新进度条
const updateProgress = (e) => {
  var value = e.target.currentTime / e.target.duration;
  if (audioRef.value?.play) {
    currentProgress.value = value * 100;
    audioStart.value = transTime(audioRef.value.currentTime);
  }
}

const handleProgressChange = (val) => {
  if (!val) {
    return;
  }
  let currentTime = duration.value * (val / 100);
  // 更新音频的当前播放时间
  audioRef.value.currentTime = currentTime;
}

// 音频加载完成
const loadEndEvent = () => {
  isDisabled.value = false;
}

// 音频播放完成
const endAudio = () => {
  audioIsPlay.value = true;
  currentProgress.value = 0;
}

// 音频播放时间换算
const transTime = (duration) => {
  const minutes = Math.floor(duration / 60);
  const seconds = Math.floor(duration % 60);
  const formattedMinutes = String(minutes).padStart(2, "0");
  const formattedSeconds = String(seconds).padStart(2, "0");
  return `${formattedMinutes}:${formattedSeconds}`;
}

const calculateDuration = () => {
  const myVid = audioRef.value;
  myVid.loop = false;
  if (!props.audioUrl) {
    isDisabled.value = true;
    myVid.src = '';
    return
  }
  myVid.src = audioUrl + props.audioUrl 

  myVid.addEventListener( 'loadedmetadata', loadEndEvent, false );
  myVid.addEventListener( "ended", endAudio, false );

  if (myVid != null) {
    myVid.oncanplay = () => {
      duration.value = myVid.duration;
      durationTime.value = transTime(myVid.duration);
      emit('loadDone', {durationTime: durationTime.value, id: props.id});
    };
    myVid.volume = 1;
  }
}

const handleCommand = (speed) => {
  audioRef.value && (audioRef.value.playbackRate = speed);
}

onMounted(() => {
  calculateDuration()
})

defineExpose({
  durationTime
})

</script>

<template>
  <div class="custom-audio-payer">
    <audio @timeupdate="updateProgress" controls controlslist= "noplaybackrate nodownload" ref="audioRef" class="audio hidden">
      <source src="" type="audio/mpeg" />
    </audio>
    <div class="audio-player">
      <div class="player-btn" @click="playAudio">
        <el-icon class="is-loading" v-if="isDisabled">
          <Loading />
        </el-icon>
        <div :class="['control-btn', audioIsPlay ? 'play' : 'pause']" v-show="!isDisabled"></div>
      </div>
      <div class="audio-plane">
        <span class="timestamp">{{ audioStart }}</span>
        <el-slider
          v-model="currentProgress"
          @input="handleProgressChange"
          style="width: 124px;"
          :show-tooltip="false"
          :disabled="isDisabled"
        />
        <span class="timestamp">{{ durationTime }}</span>
        <el-dropdown placement="top" @command="handleCommand" popper-class="custom-popper-speed">
          <el-icon><MoreFilled /></el-icon>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item :command="item.value" v-for="item in speedList" :key="item.key">{{ item.label }}</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.custom-audio-payer {
  width: 300px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 18px;
  border: 0.5px solid #E5E6EB;
  background: #FFF;
}
.audio-player {
  display: flex;
  align-items: center;
  height: 100%;
  padding: 6px 8px;
  line-height: 0;

  .player-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 100%;
    background: #E5E6EB;
    font-size: 14px;
    line-height: 0;
    color: #555;

    .control-btn {
      width: 24px;
      height: 24px;
      &.play {
        background: url('@/assets/images/workbench/icon-audio-play.svg') center center no-repeat;
        background-size: 100% 100%;
      }
      &.pause {
        background: url('@/assets/images/workbench/icon-audio-pause.svg') center center no-repeat;
        background-size: 100% 100%;
      }
    }
  }

  .audio-plane {
    display: flex;
    align-items: center;
    justify-content: space-around;
    width: 100%;

    .timestamp {
      display: block;
      line-height: 22px;
      font-size: 12px;
      color: #919397;
    }

    :deep(.el-slider__button) {
      width: 12px;
      height: 12px;
      border-color: #555;
      background: #555;
    }

    :deep(.el-slider__runway) {
      height: 6px;
    }

    :deep(.el-slider__bar) {
      height: 6px;
      background: #898787;
    }
  }
}

</style>

<style lang="scss">
  .custom-popper-speed {
    width: 100px;
  }
</style>