<template>
    <div class="yaml-panel">
        <div v-for="Field in Fields"
             :key="Field.key"
             class="yaml-item-wrapper"
        >
            <YAMLField :field="Field" @save="registerSave"/>
        </div>
        <b-loading :active="$store.getters['workshop/isBusy'](template.url) || saving"
                   :is-full-page="false"
        />
    </div>
</template>

<script>
import YAMLField from "./YAMLField";

/**
 * @description The WorkshopProperties component lists the fields described in the workshop metadata and allows a user to customise their content.
 *
 * @vue-prop template {File} Template workshop with metadata describing the fields to display.
 *
 * @vue-data currentValue={} {Object<key, any>} Dictionary of values indexed by YAML keys.
 * @vue-data valueChanged={} {Object<key, boolean>} Dictionary of change flags indexed by YAML keys.
 * @vue-data loadingFileList=true {Boolean} Whether the file list special property of any field is being determined.
 * @vue-data [fileList=[]] {Array<String>} List of files that can be selected as options for certain special fields.
 * @vue-data saving=false {Boolean} Whether the local changes to the fields are being saved to the store.
 * @vue-data saveTimeout=null {null|Number} Timeout index for the store save event.
 * @vue-data minSaveDelay=500 {Number} Minimum delay between editing a field and its content being saved to the store.
 * @vue-data lastSaveTime=0 {Number} Time the last save occurred.
 * @vue-data saveOperations={} {Object} Dictionary of pending save operations.
 * @vue-data [checkboxGroup=[]] {Array} Currently unused.
 *
 * @vue-computed Fields {Array<Field>} YAML Fields that can be edited.
 *
 * @vue-event refresh Signal that the _config.yml file in the store has been changed.
 */
export default {
    name: "WorkshopProperties",
    components: {YAMLField},
    props: {
        template: {type: Object, required: true}
    },
    data: function() {
        return {
            currentValue: {}, // dictionary of values indexed by YAML keys
            valueChanged: {}, // dictionary of change flags indexed by YAML keys
            loadingFileList: true,
            fileList: [],
            saving: false,
            saveTimeout: null,
            minSaveDelay: 500,
            lastSaveTime: 0,
            saveOperations: {},
            checkboxGroup: []
        }
    },
    computed: {
        Fields() {
            const out = [];
            // Find the keys
            const keyList = this.template.yaml['ukrn_wb']
                .filter(f => f.fields_structure)[0].fields_structure;
            // Next, find the properties
            const obj = this.template.yaml['ukrn_wb']
                .filter(f => f.fields)[0].fields;
            const fields = obj.map(o => Object.keys(o)[0]); // Field YAML keys
            obj.forEach((o, n) => {
                const propList = o[Object.keys(o)[0]];
                const properties = {};
                propList.forEach((p, i) => properties[keyList[i]] = propList[i]);
                // Add the actual value
                out.push({
                    ...properties,
                    value: this.template.yaml[fields[n]],
                    key: fields[n]
                })
            });
            return out;
        },
    },
    methods: {
        /**
         * Set a save operation to happen because a change has occurred.
         * @param key {String} Key of the YAML field that should be saved.
         * @param value {any} Value of the YAML field to save.
         */
        registerSave({key, value}) {
            this.saveOperations[key] = value;
            if(this.saveTimeout)
                clearTimeout(this.saveTimeout);
            this.saveTimeout = setTimeout(() => this.save(), this.minSaveDelay);
        },
        /**
         * Save the content of any changed YAML fields to the _config.yml file in the store.
         * @return {Promise<boolean>}
         */
        save() {
            this.saving = true;
            const me = this;
            this.saveTimeout = null;
            this.lastSaveTime = performance.now();
            const newYAML = {...this.template.yaml};
            for(let k of Object.keys(this.saveOperations)) {
                console.log(`Saving ${k} => ${this.saveOperations[k]}`)
                newYAML[k] = this.saveOperations[k];
                delete this.saveOperations[k];
            }

            return this.$store.dispatch('workshop/setFileContentFromYAML', {url: this.template.url, yaml: newYAML, body: this.template.body})
                .then(() => me.$emit('refresh'))
                .then(() => me.saving = false);
        }
    }
}
</script>

<style scoped>
.yaml-panel {
    display: grid;
    grid-auto-flow: row;
    grid-row-gap: 1em;
}
.yaml-item-wrapper {
    display: grid;
    min-width: 45%;
}
</style>