<template>
    <div class="form-builder grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3" v-cloak>

        <div class="col-span-1">
            <form-builder-form
                :current-item="currentItem"
                :mode="mode"
                @newItem="newItem"
                @saveItem="saveItem"
            ></form-builder-form>
        </div>

        <div class="col-span-1 lg:col-span-2">
            <div v-if="items && items.length" :class="['has-items', state]">
                <draggable :list="items" @update="updateSortOrder">
                    <transition-group name="list" tag="div">
                        <form-builder-item
                            v-for="(item, index) in orderedItems"
                            :key="item.id"
                            :index="index"
                            :item="item"
                            :current-item="currentItem"
                            @editItem="editItem"
                            @deleteItem="deleteItem"
                        >
                        </form-builder-item>
                    </transition-group>
                </draggable>
            </div>
            <div v-else :class="['no-items', state]">
                <v-card>
                    <div class="message text-center">
                        <div class="message-text font-semibold">
                            {{ message }}
                        </div>
                    </div>
                </v-card>
            </div>
        </div>

    </div>
</template>


<script>
import FormBuilderForm from "./FormBuilderForm";
import FormBuilderItem from "./FormBuilderItem";
import Draggable from 'vuedraggable';

export default {
    components : {
        FormBuilderForm,
        FormBuilderItem,
        Draggable
    },
    props : ['form'],
    computed : {
        orderedItems : function () {
            return _.orderBy(this.items, this.orderBy)
        }
    },
    data() {
        return {
            items : [],
            currentItem : this.defaultItem(),
            orderBy : 'sort_order',
            message : 'Checking for items, please wait...',
            state : 'loading',
            mode : 'create'
        }
    },
    methods : {
        generateId() {
            let length = 8,
                timestamp = +new Date,
                ts = timestamp.toString(),
                parts = ts.split("").reverse(),
                id = "";

            let _getRandomInt = function (min, max) {
                return Math.floor(Math.random() * (max - min + 1)) + min;
            };

            for (let i = 0; i < length; ++i) {
                let index = _getRandomInt(0, parts.length - 1);
                id += parts[index];
            }

            return id;
        },
        updateSortOrder() {
            this.items.map((item, index) => {
                item.sort_order = index + 1;
            });
        },
        newItem() {
            this.currentItem = this.defaultItem();
            this.mode = 'create';
        },
        updateItems(items, currentItem) {
            // Is this a new item or are we updating an existing item
            if (items.includes(currentItem)) {
                items[currentItem] = currentItem;
            } else {
                currentItem.sort_order = items.length + 1;
                items.push(currentItem);
            }

            return items;
        },
        saveItem() {
            // Make sure the current item has an id in which to track it
            this.currentItem.id = this.currentItem.id || this.generateId();

            let currentItem = this.currentItem;
            this.items = this.updateItems(this.items, currentItem);

            // Reset the current item as we are done with it
            this.currentItem = this.defaultItem();
        },
        editItem(item, index) {
            this.currentItem = item;
            this.currentItem.width = item.width || '';
            this.mode = 'edit';
        },
        deleteItem(item, index) {
            this.deleteItems(this.items, index);
            this.updateState();
        },
        deleteItems(items, itemIndex) {
            this.$delete(items, itemIndex);

            return items;
        },
        updateState() {
            if (!this.items.length) {
                this.state = 'no-data';
                this.message = 'Please complete the form to add new items'
            }
        },
        checkForExistingItems() {
            if (this.form && this.form.items) {
                this.items = this.form.items;
            }
        },
        defaultItem() {
            return {
                id : null,
                width : '',
                label : null,
                display_label : 'yes',
                name : null,
                options : null,
                class : null,
                required : 'no',
                type : 'input',
            }
        },
    },
    mounted() {
        this.checkForExistingItems();
        this.updateState();
    }
}
</script>
