<template>
    <Tooltip :text="$t('pronunciation.play')">
        <a
            :class="['btn', 'btn-sm', 'btn-link', 'px-1', 'py-0', !pronunciation ? 'disabled' : '']"
            dir="ltr"
            :href="pronunciationLink"
            target="_blank"
            @click.prevent="pronounce"
        >
            <Icon :v="icon" /><sub v-if="name">{{ name }}</sub>
        </a>
    </Tooltip>
</template>


<script lang="ts">
import { Base64 } from 'js-base64';
import Vue from 'vue';
import type { PropType } from 'vue';

const STATE_IDLE = 'idle';
const STATE_LOADING = 'loading';
const STATE_PLAYING = 'playing';

export default Vue.extend({
    props: {
        pronunciation: { default: null, type: String as PropType<string | null> },
        voice: { required: true, type: String },
    },
    data(): { state: 'idle' | 'loading' | 'playing', sound: HTMLAudioElement | null } {
        return {
            state: STATE_IDLE,
            sound: null,
        };
    },
    computed: {
        pronunciationLink(): string | undefined {
            if (!this.pronunciation) {
                return undefined;
            }

            return `/api/pronounce/${this.voice}/${Base64.encodeURI(this.pronunciation)}`;
        },
        name(): string | null {
            if (!this.$config.pronunciation?.enabled) {
                return this.voice;
            }

            const voices = Object.keys(this.$config.pronunciation.voices);
            if (voices.length === 1 && this.voice === voices[0]) {
                // don’t show voice name if it is considered the main voice for this locale
                return null;
            }

            return this.voice;
        },
        icon(): string {
            switch (this.state) {
                case STATE_LOADING:
                    return 'spinner fa-spin';
                case STATE_PLAYING:
                    return 'volume-up';
                case STATE_IDLE:
                default:
                    return 'volume';
            }
        },
    },
    methods: {
        pronounce() {
            if (!this.pronunciationLink) {
                return;
            }
            if (this.sound && this.sound.src.endsWith(this.pronunciationLink) && !this.sound.error) {
                // reuse the sound object if it has the same source and has been loaded without an error
                this.sound.pause();
                this.sound.currentTime = 0;
                this.sound.play();

                return;
            }

            this.sound = new Audio(this.pronunciationLink);

            this.sound.addEventListener('canplay', () => this.sound!.play());
            this.sound.addEventListener('play', () => this.state = STATE_PLAYING);
            this.sound.addEventListener('ended', () => this.state = STATE_IDLE);
            this.sound.addEventListener('error', () => this.state = STATE_IDLE);

            this.state = STATE_LOADING;
            this.sound.load();
        },
    },
});
</script>
