<template>
    <div class="card">
        <!-- Header containing info and actions for the transcription -->
        <div class="transcription__header">
            <button class="btn-fab" v-on:click="playAudio(0)" type="button">
                <span class="material-icons mdi-l">play_arrow</span>
            </button>

            <span>{{ translations.get("TranscriptionItem_FileName") }}: {{ transcription.fileName }}</span>

            <div style="position: relative;">
                <button class="btn-primary" @mouseover="showDownloadOptions = true" @mouseout="showDownloadOptions = false" type="button">
                    <span class="material-icons">download</span>
                    <span>{{ translations.get("TranscriptionItem_Download") }}</span>
                </button>

                <div class="download-popup card" :class="{ 'download-popup-show': showDownloadOptions }"
                     @mouseover="showDownloadOptions = true" @mouseout="showDownloadOptions = false">
                    <button @click="downloadAsText" type="button" class="btn-primary theme-flat">
                        <span class="material-icons">text_snippet</span>
                        <span>{{ translations.get("TranscriptionItem_DownloadAsText") }}</span>
                    </button>

                    <button @click="downloadAsJson" type="button" class="btn-primary theme-flat">
                        <span class="material-icons">integration_instructions</span>
                        <span>{{ translations.get("TranscriptionItem_DownloadAsJson") }}</span>
                    </button>

                    <button @click="downloadAsWebvtt" type="button" class="btn-primary theme-flat">
                        <span class="material-icons">subtitles</span>
                        <span>{{ translations.get("TranscriptionItem_DownloadAsWebvtt") }}</span>
                    </button>
                </div>
            </div>

            <button class="btn-primary theme-error" @click="remove" type="button">
                <span class="material-icons">delete</span>
                <span>{{ translations.get("TranscriptionItem_Remove") }}</span>
            </button>
        </div>

        <hr />

        <TranscriptionItemEditor :transcription="transcription" style="margin-bottom: 1em" />

        <button @click="toggleEditor" type="button" class="btn-primary theme-flat">
            <span class="material-icons expander-toggle" :class="{ 'rotate-180': showEditor }">expand_more</span>
            <span>{{ translations.get("TranscriptionItem_ExpandEditor") }}</span>
        </button>
    </div>
</template>

<style scoped lang="scss">
.transcription__header {
    display: grid;
    gap: 0.5em 0.5em;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
}

.download-popup {
    display: flex;
    flex-direction: column;
    align-items: stretch;

    position: absolute;
    top: 97%;
    z-index: 2;

    padding: 2px;
    margin: 0;
    width: 14em;

    transition-duration: var(--transition-duration);
    visibility: hidden;
    opacity: 0;
}

.download-popup-show {
    visibility: visible;
    opacity: 1;
}

.expander-toggle {
    transition-duration: 0.4s;
}

.rotate-180 {
    transform: rotate(180deg);
}
</style>

<script>
import { mapState } from "vuex";
import { saveAs } from "file-saver"
import TranscriptionItemEditor, { getWords } from "./TranscriptionItemEditor.vue"
import { TranscriptionViewModel, PlaybackState } from "../main";
import Util from "../js/Util"

export default {
    name: "TranscriptionItem",
    components: {
        TranscriptionItemEditor
    },
    props: {
        transcription: TranscriptionViewModel
    },
    data() {
        return {
            showEditor: false,
            showDownloadOptions: false
        }
    },
    computed: mapState({
        translations: state => state.translations
    }),
    methods: {
        toggleEditor() {
            this.showEditor = !this.showEditor;
        },
        playAudio(startTime = 0) {
            const pState = new PlaybackState(this.transcription.id, true, startTime);
            this.$store.commit("setPlaybackState", pState);
        },
        remove() {
            this.$store.commit("transcriptionRemove", this.transcription.id);
        },
        downloadAsText() {
            const fileName = buildDownloadableFileName(this.transcription.fileName, "txt");

            const blob = new Blob([ this.transcription.transcription ], { type: "text/plain;charset=utf-8" });
            saveAs(blob, fileName);
        },
        downloadAsJson() {
            const fileName = buildDownloadableFileName(this.transcription.fileName, "json");
            const toDownload = (({ fileName, transcription, metadata }) => ({ fileName, transcription, metadata }))(this.transcription);

            const blob = new Blob([ JSON.stringify(toDownload, null, 4) ], { type: "application/json;charset=utf-8" });
            saveAs(blob, fileName);
        },
        downloadAsWebvtt() {
            const fileName = buildDownloadableFileName(this.transcription.fileName, "vtt");
            const toDownload = buildWebvttFileContents(this.transcription);

            const blob = new Blob([ toDownload ], { type: "text/vtt;charset=utf-8" });
            saveAs(blob, fileName);
        }
    }
}

/**
 * Builds a file name for a download.
 * @param {String} transcriptionFileName The name of the transcription that will be downloaded.
 * @param {String} extension The file extension of the download. Do not include a period.
 * @returns {String} The file name.
 */
function buildDownloadableFileName(transcriptionFileName, extension) {
    const extensionIndex = transcriptionFileName.lastIndexOf(".");
    let fileName = transcriptionFileName.slice(0, extensionIndex);
    fileName += "_transcription." + extension;

    return fileName;
}

/**
 * Builds a WebVTT file of the given transcription
 * @param {TranscriptionViewModel} transcription The transcription.
 * @returns {String} The WebVTT content.
 */
function buildWebvttFileContents(transcription) {
    let contents = "WEBVTT Transcription of " + transcription.fileName + "\n\n";

    for (const word of getWords(transcription)) {
        const startTime = Util.formatSecondsTimeString(word.startTime, true);
        const endTime = Util.formatSecondsTimeString(word.endTime, true);

        contents += startTime + " --> " + endTime + "\n";
        contents += "- " + word.word + "\n\n";
    }

    return contents;
}
</script>
