<template>
	<div class="gloWe-audio">
		<div class="audio">
			<div class="icon-div">
				<SvgIcon
					@click="playPauseAudio"
					:name="audioData.playing ? 'ele-VideoPause' : 'ele-VideoPlay'"
					:title="audioData.playing ? '暂停' : '播放'"
					class="mr10 cursor-pointer"
					size="24px"
					color="var(--el-color-primary)"
				/>
				<div class="time-wrap">
					<span class="time">{{ formatDuration(Math.round(audioData.currentTime)) }}/{{ formatDuration(Math.round(audioData.duration)) }}</span>
				</div>
			</div>
			<div class="slider-wrap ml10 mr10" ref="progressRef">
				<el-slider v-model="audioData.percentage" @input="inputProgress" @change="changeProgress" :format-tooltip="formatTooltip"> </el-slider>
			</div>

			<el-dropdown trigger="hover">
				<SvgIcon :name="icon" class="mr5 ml5 cursor-pointer" size="18px" color="var(--el-color-primary)" @click="mute" />
				<template #dropdown>
					<el-dropdown-menu>
						<el-slider v-model="audioData.voice" vertical height="100px" @change="changeSound" />
					</el-dropdown-menu>
				</template>
			</el-dropdown>
			<SvgIcon name="ele-Download" class="cursor-pointer ml5" size="18px" color="var(--el-color-primary)" @click="downLoad" title="下载" />
		</div>
		<audio :src="audioData.url" preload="auto" @ended="audioEnded" @timeupdate="audioTimeupdate" @loadeddata="audioLoadeddata" ref="audioRef"></audio>
	</div>
</template>
<script lang="ts" name="GloWeAudio" setup>
import {reactive, ref, computed, watch, nextTick} from 'vue';
import { formatDuration } from '/@/utils/formatTime';
import {ElMessage} from "element-plus";

// 定义父组件传过来的值
const props = defineProps({
	url: {
		type: String,
		required: true,
	},
	fileName: {
		type: String,
		required: false,
		default: '测试文件',
	},
});

// 定义变量内容
const audioData = reactive<any>({
	url: props.url,
	playing: false,
	duration: 0, // 音频总时长
	currentTime: 0, // 当前播放的时间
	percentage: 0, //进度条百分比
	voice: 50, //音量
	muteState: false, //是否静音
});

const audioRef = ref<RefType>();
// 播放或暂停音频
const playPauseAudio = () => {
	if (audioData.playing) {
		audioPause();
	} else {
		audioPlay();
	}
};
const icon = computed(() => {
	if (audioData.muteState) {
		return 'iconfont icon-guanbiyinliang';
	} else {
		return 'iconfont icon-jiadayinliang';
	}
});
// 计算百分比的分子
function getPercentage(num: number | string, den: number | string): number {
	const numerator = typeof num === 'number' ? num : parseFloat(num);
	const denominator = typeof den === 'number' ? den : parseFloat(den);
	return Math.round((numerator / denominator) * 10000) / 100;
}
/**
 * 更新进度条
 * @param percentage 百分比
 */
function updateProgressBar(percentage: number) {
	audioData.percentage = percentage;
}

/**
 * 以下是对音频的操作
 */

// 音频播放结束
const audioEnded = () => {
	audioData.playing = false;
};
// 播放进度：表示audio正在播放，currentTime在更新
const audioTimeupdate = (e: any) => {
	audioData.currentTime = e.target.currentTime;
  progressBarByCurrentTime();
};
// 当媒体音频第一帧加载完成时
const audioLoadeddata = (e: any) => {
	audioData.duration = e.target.duration;
};

// 播放
function audioPlay() {
	audioRef.value.play();
	audioData.playing = true;
}

// 暂停播放
function audioPause() {
	audioRef.value.pause();
	audioData.playing = false;
}

// 进度条和音频播放进度进行关联
function progressBarByCurrentTime() {
	const progress = getPercentage(audioData.currentTime, audioData.duration);
	updateProgressBar(progress);
}

//  改变进度 暂停 使用鼠标拖曳时，活动过程实时触发
const inputProgress = (val: number) => {
	audioData.percentage = val;
	audioData.currentTime = audioData.duration * (val / 100);
	audioRef.value.currentTime = audioData.duration * (val / 100);
	audioRef.value.pause();
};
// 使用鼠标拖曳时，只在松开鼠标后触发 继续播放
const changeProgress = () => {
	if (audioData.playing) audioPlay();
};
// 格式化提示
const formatTooltip = (val: number) => {
	return formatDuration(Math.round(audioData.duration * (val / 100)));
};
// 改变音量
const changeSound = (val: number) => {
	audioData.muteState = val <= 0;
	audioRef.value.volume = val / 100;
	audioData.voice = val;
};
// 监听声音大小
watch(
	() => audioData.muteState,
	(val) => {
		if (val) {
			audioRef.value.volume = audioData.voice = 0;
		} else {
			audioRef.value.volume = 0.5;
			audioData.voice = 50;
		}
	},
	{
		deep: true,
	}
);
// 静音
const mute = () => {
	audioData.muteState = !audioData.muteState;
};
// 下载
const downLoad = () => {
	//     // eslint-disable-next-line no-unused-vars
	// let blobType = 'application/force-download' // 设置blob请求头
	// // eslint-disable-next-line no-unused-vars
	// let blob = new Blob([res.data], {type: res.data.type}) // 创建blob 设置blob文件类型 data 设置为后端返回的文件(例如mp3,jpeg) type:这里设置后端返回的类型 为 mp3
	// let downa = document.createElement('a') // 创建A标签
	// // eslint-disable-next-line no-unused-vars
	// let href = window.URL.createObjectURL(blob) // 创建下载的链接
	// downa.href = props.url // 下载地址
	// downa.download = props?.fileName ?? '' // 下载文件名
	// document.body.appendChild(downa)
	// downa.click() // 模拟点击A标签
	// document.body.removeChild(downa) // 下载完成移除元素
	// window.URL.revokeObjectURL(href) // 释放blob对象

	// const elink = document.createElement('a')
	// elink.href = props.url
	// elink.setAttribute('download', props?.fileName ?? '')
	// elink.style.display = 'none'
	// document.body.appendChild(elink)
	// setTimeout(() => {
	//     elink.click()
	//     document.body.removeChild(elink)
	// }, 66)
	window.open(props.url);
};
nextTick(() => {
  audioRef.value.onerror =  ()=> {
    ElMessage.error('音频加载失败');
  };
});
</script>
<style scoped lang="scss">
.gloWe-audio{
	.audio {
		display: flex;
		align-items: center;
		justify-content: center;
		height: 48px;
		.icon-div {
			display: flex;
			align-items: center;
			border-radius: 100%;
			margin-right: 10px;
		}

		.slider-wrap {
			position: relative;
			display: flex;
			align-items: center;
			min-width: 200px;
		}
	}
}
</style>
