<template>
    <transition name="slide-fade" mode="out-in">
        <v-card>
            <template slot="header">
                <span v-if="mode === 'edit'" class="text-primary-500">
                    Editing: {{ currentItem.attributes.name }}
                </span>
                <span v-else class="text-green-500">
                    Creating: New Item
                </span>
            </template>

            <div class="menu-builder-form" :key="currentItem.id">

                <v-label>Name</v-label>
                <div class="mt-1 relative rounded-sm shadow-sm">
                    <input
                        class="form-input block w-full rounded-sm sm:text-sm sm:leading-5"
                        type="text"
                        v-model="currentItem.attributes.name"
                    >
                </div>
                <v-error v-if="hasErrors && ! hasName(currentItem)">
                    Item name is required
                </v-error>

                <v-label class="mt-4">Type</v-label>
                <div class="mt-1 relative rounded-sm shadow-sm">
                    <select
                        class="form-input block w-full rounded-sm sm:text-sm sm:leading-5 pr-10"
                        v-model="currentItem.attributes.type"
                    >
                        <option
                            v-for="type in types"
                            :selected="{ 'selected' : isSameType(currentItem, type) }"
                        >
                            {{ type }}
                        </option>
                    </select>
                    <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-500">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="fill-current h-4 w-6">
                            <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
                        </svg>
                    </div>
                </div>

                <div v-if="isExternal(currentItem)" class="external-link">
                    <v-label class="mt-4">Url</v-label>
                    <div class="mt-1 relative rounded-sm shadow-sm">
                        <input
                            class="form-input block w-full rounded-sm sm:text-sm sm:leading-5"
                            type="text"
                            v-model="currentItem.attributes.url"
                        >
                    </div>

                    <v-label class="mt-4">Target</v-label>
                    <div class="mt-1 relative rounded-sm shadow-sm">
                        <select
                            class="form-input block w-full rounded-sm sm:text-sm sm:leading-5"
                            v-model="currentItem.attributes.target"
                        >
                            <option
                                v-for="target in targets"
                                :selected="{ 'selected' : isSameTarget(currentItem, target) }"
                            >
                                {{ target }}
                            </option>
                        </select>
                        <div
                            class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-500"
                        >
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="fill-current h-4 w-6">
                                <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
                                ></path>
                            </svg>
                        </div>
                    </div>
                </div>

                <div v-else class="internal-link">
                    <v-label class="mt-4">Link Category</v-label>
                    <div class="mt-1 relative rounded-sm shadow-sm">
                        <select
                            class="form-input block w-full rounded-sm sm:text-sm sm:leading-5"
                            v-model="currentItem.attributes.entity_type"
                        >
                            <option
                                v-for="entityType in entityTypes"
                                :selected="{ 'selected' : isSameEntityType(currentItem, entityType) }"
                            >
                                {{ entityType }}
                            </option>
                        </select>
                        <div
                            class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-500"
                        >
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="fill-current h-4 w-6">
                                <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
                                ></path>
                            </svg>
                        </div>
                    </div>
                    <v-error v-if="hasErrors && requiresEntityType(currentItem)">
                        Link Category is required
                    </v-error>

                    <div v-if="currentItem.attributes.entity_type">
                        <v-label class="mt-4">Link Id</v-label>
                        <div class="mt-1 relative rounded-sm shadow-sm">
                            <select
                                class="form-input block w-full rounded-sm sm:text-sm sm:leading-5"
                                v-model="currentItem.attributes.entity_id"
                            >
                                <option
                                    v-for="entityItem in entityItems"
                                    :value="entityItem.id"
                                    :selected="{ 'selected' : isSameEntityId(currentItem, entityItem) }"
                                >
                                    {{ entityItem.name }}
                                </option>
                            </select>
                            <div
                                class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-500"
                            >
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
                                     class="fill-current h-4 w-6"
                                >
                                    <path
                                        d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
                                    ></path>
                                </svg>
                            </div>
                        </div>
                    </div>
                    <v-error v-if="hasErrors && requiresEntityId(currentItem)">
                        Link Id is required
                    </v-error>
                </div>

                <v-label class="mt-4">Parent Item</v-label>
                <div class="mt-1 relative rounded-sm shadow-sm">
                    <select
                        class="form-input block w-full rounded-sm sm:text-sm sm:leading-5 pr-10"
                        v-model="currentItem.attributes.parent_id"
                    >
                        <option
                            v-for="parentItem in filteredParentItems"
                            :value="parentItem.id"
                            :selected="{ 'selected' : isSameParentId(currentItem, parentItem) }"
                        >
                            {{ parentItem.attributes.name }}
                        </option>
                    </select>
                    <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-500">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="fill-current h-4 w-6">
                            <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
                        </svg>
                    </div>
                </div>
            </div>

            <template slot="footer">
                <div class="grid grid-cols-2 gap-2 items-center">

                    <div class="col-span-1">
                        <button
                            v-if="mode === 'edit'"
                            class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-sm text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:text-gray-800 active:bg-gray-50 active:text-gray-800 transition duration-150 ease-in-out"
                            @click.prevent="createItem"
                        >
                            New Item
                        </button>
                    </div>

                    <div class="col-span-1 text-right">
                        <button
                            class="inline-flex items-center px-4 py-2 border border-transparent text-sm leading-5 font-medium rounded-sm text-white transition duration-150 ease-in-out"
                            :class="mode === 'create' ? 'bg-green-400 hover:bg-green-500 focus:outline-none focus:shadow-outline-green focus:border-green-600 active:bg-green-600' : 'bg-primary-400 hover:bg-primary-500 focus:outline-none focus:shadow-outline-primary focus:border-primary-600 active:bg-primary-600'"
                            @click.prevent="saveItem"
                        >
                            {{ mode === 'create' ? 'Create' : 'Update' }}
                        </button>
                    </div>

                </div>
            </template>
        </v-card>
    </transition>
</template>


<script>
export default {
    name : 'MenuBuilderForm',
    props : {
        mode : {type : String},
        currentItem : {type : Object},
        entityTypes : {type : Array},
        parentItems : {type : Array}
    },
    data() {
        return {
            hasErrors : false,
            types : ['internal', 'external'],
            targets : ['_self', '_blank'],
            entityItems : [],
        }
    },
    computed : {
        id() {
            return this.currentItem.id;
        },
        parentId() {
            return this.currentItem.attributes.parent_id;
        },
        entityType() {
            return this.currentItem.attributes.entity_type;
        },
        entityId() {
            return this.currentItem.attributes.entity_id;
        },
        defaultOption() {
            return {
                id : 0,
                attributes : {
                    parent_id : null,
                    name : '-- Please Select --',
                },
                relationships : {}
            };
        },
        filteredParentItems() {

            // Clone the parent items array
            let items = JSON.parse(JSON.stringify(this.parentItems || []));
            if (!items || items.length < 1) {
                return [this.defaultOption];
            }

            // Add a default option if it doesn't exist
            if (!items.find(item => item.id === 0)) {
                items.unshift(this.defaultOption);
            }

            // Exclude the current item from being its own parent
            items = items.filter(item => item.id !== this.currentItem.id);

            // Loop through each item and if it has nested children, then add them to the available items
            const addNestedChildren = (parentItem) => {

                // If the parent item does not have any children, return
                if (!this.hasChildren(parentItem)) {
                    return;
                }

                // Otherwise, loop through each child item
                parentItem.relationships.nested_children.forEach(childItem => {

                    // If the parentItem.id matches the childItem.id, then skip it
                    if (this.isSameItem(parentItem, childItem)) {
                        return;
                    }

                    // If the current item id matches the child item id, skip it
                    if (this.isSameItem(this.currentItem, childItem)) {
                        return;
                    }

                    // Otherwise, prefix the parent item's name to indicate hierarchy, and add to the items array
                    childItem.attributes.name = parentItem.attributes.name + ' > ' + childItem.attributes.name;
                    items.push(childItem);

                    // Recursively add any nested children of the child item
                    addNestedChildren(childItem);
                });
            };
            items.forEach(item => {
                addNestedChildren(item);
            });

            // Sort the items by name
            items.sort((a, b) => {
                if (a.attributes.name < b.attributes.name) return -1;
                if (a.attributes.name > b.attributes.name) return 1;
                return 0;
            });

            return items;
        }
    },
    methods : {
        isNew(item) {
            return !item.id;
        },
        isInternal(item) {
            return item.attributes.type === 'internal';
        },
        isExternal(item) {
            return item.attributes.type === 'external';
        },
        isSameItem(item1, item2) {
            return item1.id === item2.id;
        },
        isSameType(item, type) {
            return item.attributes.type === type;
        },
        isSameTarget(item, target) {
            return item.attributes.target === target;
        },
        isSameEntityType(item, entityType) {
            return item.attributes.entity_type === entityType;
        },
        isSameEntityId(item, entityItem) {
            return item.attributes.entity_id === entityItem.id;
        },
        isSameParentId(item, parentItem) {
            return item.attributes.parent_id === parentItem.id;
        },

        hasName(item) {
            return item.attributes.name;
        },
        hasEntityType(item) {
            return item.attributes.entity_type;
        },
        hasEntityId(item) {
            return item.attributes.entity_id;
        },
        hasChildren(item) {
            return item.relationships
                && item.relationships.nested_children
                && item.relationships.nested_children.length > 0;
        },

        requiresEntityType(item) {
            return this.isInternal(item)
                && !this.hasEntityType(item);
        },
        requiresEntityId(item) {
            return this.isInternal(item)
                && this.hasEntityType(item)
                && !this.hasEntityId(item);
        },

        createItem() {
            window.EventBus.$emit('menuBuilder:createItem');
        },
        saveItem() {
            this.hasErrors = false;

            // Make sure the item has a name
            if (!this.hasName(this.currentItem)) {
                return this.hasErrors = true;
            }

            // If internal, make sure it has entity type and id
            if (this.isInternal(this.currentItem)
                && (!this.hasEntityType(this.currentItem) || !this.hasEntityId(this.currentItem))
            ) {
                return this.hasErrors = true;
            }

            // Is this a new item?
            if (this.isNew(this.currentItem)) {
                window.EventBus.$emit('menuBuilder:storeItem', {item : this.currentItem});

                return;
            }

            // Otherwise, update existing item
            window.EventBus.$emit('menuBuilder:updateItem', {item : this.currentItem});
        },

        getEntityEndpoint() {
            let apiUrl = null;

            switch (this.currentItem.attributes.entity_type) {
                case 'Document':
                    apiUrl = '/api/documents';
                    break;
                case 'Page':
                    apiUrl = '/api/pages';
                    break;
                case 'Post':
                    apiUrl = '/api/posts';
                    break;
                case 'Post Category':
                    apiUrl = '/api/post-categories';
                    break;
                case 'Project':
                    apiUrl = '/api/projects';
                    break;
                case 'Project Category':
                    apiUrl = '/api/project-categories';
                    break;
            }

            return apiUrl;
        },
        getEntityItems() {

            // If no entity type is selected, clear the entity items
            if (!this.hasEntityType(this.currentItem)) {
                this.entityItems = [];

                return
            }

            // Get the API endpoint for the selected entity type
            let apiUrl = this.getEntityEndpoint();
            if (!apiUrl) {
                this.entityItems = [];
                console.log('No entity type selected');

                return;
            }

            // Fetch the entity items from the API
            window.axios.get(apiUrl)
                .then((response) => {
                    this.entityItems = response.data.data || response.data.items;
                    if (!this.entityItems || this.entityItems.length < 1) {
                        this.entityItems = [{
                            id : 0,
                            name : '-- Please Select --',
                        }];
                    }
                })
                .catch(e => {
                    console.log(e.message);
                });
        }
    },
    watch : {
        entityType : function () {
            this.getEntityItems();
        },
        entityId : function () {
            this.getEntityItems();
        },
    },
}
</script>
