<template>
<div class="root">
    <textarea class="text-input input-area" @input="onTextInput"
        v-model="input" :placeholder="translations.get('DirectInput_InputPlaceholder')" />

    <div class="text-container">
        <span v-if="errorState" class="material-icons mdi-m error-text">error</span>
        <span v-if="errorState" class="error-text">Something went wrong! Please try modifying your input text.</span>

        <!-- eslint-disable-next-line vue/require-v-for-key -->
        <span v-for="word in validRestored" :class="{ 'highlight': word.macronised && this.showMacronisedWords }">{{ word.w }}&nbsp;</span>
    </div>

    <div class="flex">
        <input type="checkbox" id="i-preserve-existing-macrons" v-model="preserveExistingMacrons" />
        <label for="i-preserve-existing-macrons">{{ translations.get('DirectInput_PreserveExistingMacrons') }}</label>
    </div>

    <div class="flex">
        <input type="checkbox" id="i-show-macronised-words" v-model="showMacronisedWords" />
        <label for="i-show-macronised-words">{{ translations.get('DirectInput_ShowMacronisedWords') }}</label>
    </div>

    <button class="btn-primary right-column" :disabled="!canDownload" @click="downloadAsText">{{ translations.get('DirectInput_Download') }}</button>
</div>
</template>

<style scoped lang="scss">
.root {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1em;
}

.input-area {
    resize: none;
    min-height: 4em;
    overflow: hidden;
}

.flex {
    display: flex;
    align-items: center;
    gap: 0.5em;
}

.right-column {
    grid-column: 2;
}

.highlight {
    background-color: var(--highlighted-word-bg);
}

.error-text {
    color: rgb(185, 3, 3);
}
</style>

<script>
import { mapState } from "vuex";
import { saveAs } from "file-saver"
import { log } from "../js/Util"
import MacronRestorationModule from "../js/MacronRestorationModule"

const macroniser = new MacronRestorationModule();

export default {
    name: "DirectInput",
    data() {
        return {
            preserveExistingMacrons: true,
            showMacronisedWords: false,
            transcribeTimeout: null,
            waitingOnTranscribe: false,
            errorState: false
        }
    },
    computed: {
        canDownload() {
            return this.restored !== null && !this.waitingOnTranscribe;
        },
        input: {
            get() {
                return this.$store.state.directInput;
            },
            set(newValue) {
                this.$store.commit("setDirectInput", newValue);
            }
        },
        restored: {
            get() {
                return this.$store.state.directOutput;
            },
            set(newValue) {
                this.$store.commit("setDirectOutput", newValue);
            }
        },
        validRestored() {
            return this.restored.filter(w => w.w !== "");
        },
        ...mapState({
            translations: state => state.translations
        })
    },
    watch: {
        input() {
            this.waitingOnTranscribe = true;

            if (this.transcribeTimeout !== null) {
                clearTimeout(this.transcribeTimeout);
            }

            this.transcribeTimeout = setTimeout(this.updateMacronisedText, 1000);
        }
    },
    methods: {
        /**
         * Handles input on an element, and grows its height so that the text is always visible.
         * @param {InputEvent} event The input event.
         */
        onTextInput(event) {
            event.target.height = "auto";
            event.target.height = event.target.scrollHeight;
        },
        async updateMacronisedText() {
            this.errorState = false;

            try {
                this.restored = await macroniser.directMacronisation(this.input, this.preserveExistingMacrons);
                this.waitingOnTranscribe = false;
            }
            catch (ex) {
                this.errorState = true;
                log(ex, "warn");
            }
        },
        downloadAsText() {
            const blob = new Blob([ this.restored ], { type: "text/plain;charset=utf-8" });
            saveAs(blob, "restored.txt");
        }
    }
}
</script>
