<template>
    <div>
        <div v-if="!loaded" class="siteMenuAdmin__loading"><i class="fa fa-spinner fa-spin"></i> Loading…</div>

        <form v-else ref="form" class="siteMenuAdmin__form" @submit.prevent="submit">
            <input type="hidden" name="_token" :value="csrf" />
            <input type="hidden" name="id" :value="form.id" />
            <input type="hidden" name="published" :value="form.published ? 1 : 0" />
            <input type="hidden" name="mega_menu" :value="form.mega_menu ? 1 : 0" />
            <input type="hidden" name="mega_menu_items" :value="megaItemsJson" />

            <div class="siteMenuAdmin__formCard">
                <div class="siteMenuAdmin__formCard-title">{{ addEdit }} menu item</div>

                <div class="siteMenuAdmin__field">
                    <label class="siteMenuAdmin__label" for="sm-name">Name</label>
                    <input id="sm-name" name="name" type="text" class="siteMenuAdmin__control"
                           :class="{ 'siteMenuAdmin__control--error': errors.name }"
                           v-model="form.name" @input="clearError('name')" />
                    <p v-if="errors.name" class="siteMenuAdmin__fieldError">{{ errors.name }}</p>
                </div>

                <div class="siteMenuAdmin__field">
                    <label class="siteMenuAdmin__label">Published</label>
                    <span class="siteMenuAdmin__switch" :class="{ 'siteMenuAdmin__switch--on': form.published }"
                          role="switch" :aria-checked="form.published ? 'true' : 'false'" tabindex="0"
                          @click="form.published = !form.published"
                          @keydown.space.prevent="form.published = !form.published">
                        <span class="siteMenuAdmin__switch-track"></span>
                        <span class="siteMenuAdmin__switch-label">{{ form.published ? 'Active' : 'Inactive' }}</span>
                    </span>
                </div>

                <div class="siteMenuAdmin__field">
                    <label class="siteMenuAdmin__label" for="sm-parent">Parent menu item</label>
                    <select id="sm-parent" name="parent_id" class="siteMenuAdmin__control" v-model="form.parent_id">
                        <option v-for="opt in parentOptions" :key="opt.id" :value="String(opt.id)">
                            {{ indent(opt.sublevel) }}{{ opt.name }}
                        </option>
                    </select>
                    <p class="siteMenuAdmin__hint">Which menu item this should sit under.</p>
                </div>

                <div class="siteMenuAdmin__field">
                    <label class="siteMenuAdmin__label" for="sm-url">Link</label>
                    <input id="sm-url" name="url" type="text" class="siteMenuAdmin__control"
                           v-model="form.url" :disabled="isRoot" />
                    <p class="siteMenuAdmin__hint" v-if="isRoot">Top-level menus don't need a link.</p>
                </div>

                <div class="siteMenuAdmin__field">
                    <label class="siteMenuAdmin__label" for="sm-target">Target</label>
                    <select id="sm-target" name="target" class="siteMenuAdmin__control" v-model="form.target">
                        <option value="_self">Same window (_self)</option>
                        <option value="_blank">New window (_blank)</option>
                    </select>
                </div>

                <div class="siteMenuAdmin__field" v-if="isSuperAdmin">
                    <label class="siteMenuAdmin__label" for="sm-css">CSS class</label>
                    <input id="sm-css" name="css_class" type="text" class="siteMenuAdmin__control" v-model="form.css_class" />
                </div>

                <div class="siteMenuAdmin__field" :class="{ keepHidden: !debug }" v-if="brandsEnabled">
                    <label class="siteMenuAdmin__label" for="brand_list">List brands</label>
                    <select id="brand_list" name="brand_list" class="siteMenuAdmin__control" v-model="form.brand_list">
                        <option value="0">No</option>
                        <option value="1">Yes — list all site brands</option>
                    </select>
                </div>

                <template v-if="categoriesMax > 0">
                    <div class="siteMenuAdmin__field" :class="{ keepHidden: !debug }">
                        <label class="siteMenuAdmin__label" for="category_id">Display info from category</label>
                        <select id="category_id" name="category_id" class="siteMenuAdmin__control" v-html="categoryIdHtml"></select>
                    </div>
                    <div class="siteMenuAdmin__field" :class="{ keepHidden: !debug }">
                        <label class="siteMenuAdmin__label" for="single_category">List single category</label>
                        <select id="single_category" name="single_category" class="siteMenuAdmin__control" v-html="singleCategoryHtml"></select>
                    </div>
                    <div class="siteMenuAdmin__field">
                        <label class="siteMenuAdmin__label">Mega menu</label>
                        <span class="siteMenuAdmin__switch" :class="{ 'siteMenuAdmin__switch--on': form.mega_menu }"
                              role="switch" :aria-checked="form.mega_menu ? 'true' : 'false'" tabindex="0"
                              @click="form.mega_menu = !form.mega_menu"
                              @keydown.space.prevent="form.mega_menu = !form.mega_menu">
                            <span class="siteMenuAdmin__switch-track"></span>
                            <span class="siteMenuAdmin__switch-label">{{ form.mega_menu ? 'On' : 'Off' }}</span>
                        </span>
                        <p class="siteMenuAdmin__hint">Turn on to hand-pick the sub-categories and products shown in this item's mega menu.</p>
                    </div>

                    <div class="siteMenuAdmin__field" v-if="form.mega_menu">
                        <label class="siteMenuAdmin__label">Mega menu content</label>
                        <site-menu-mega-picker :base="base" v-model="form.mega_menu_items"></site-menu-mega-picker>
                    </div>
                </template>

                <template v-if="cmsEnabled">
                    <div class="siteMenuAdmin__field" :class="{ keepHidden: !debug }">
                        <label class="siteMenuAdmin__label" for="site_tree">This is a CMS tree</label>
                        <select id="site_tree" name="site_tree" class="siteMenuAdmin__control" v-html="cmsTreeHtml"></select>
                    </div>
                    <div class="siteMenuAdmin__field" :class="{ keepHidden: !debug }">
                        <label class="siteMenuAdmin__label">Single page only</label>
                        <input type="hidden" value="0" name="single_cms_page" />
                        <span class="siteMenuAdmin__switch" :class="{ 'siteMenuAdmin__switch--on': form.single_cms_page }"
                              role="switch" tabindex="0"
                              @click="form.single_cms_page = !form.single_cms_page">
                            <input type="checkbox" value="1" name="single_cms_page" v-model="form.single_cms_page" style="display:none" />
                            <span class="siteMenuAdmin__switch-track"></span>
                            <span class="siteMenuAdmin__switch-label">Show only the selected CMS page</span>
                        </span>
                    </div>
                </template>
            </div>

            <div class="siteMenuAdmin__formActions">
                <button type="submit" class="siteMenuAdmin__btn siteMenuAdmin__btn--primary" :disabled="saving">
                    <i class="fa" :class="saving ? 'fa-spinner fa-spin' : 'fa-check'"></i>
                    {{ saving ? 'Saving…' : 'Save' }}
                </button>
                <a class="siteMenuAdmin__btn siteMenuAdmin__btn--ghost" href="#" @click.prevent="$emit('cancel')">Cancel</a>
                <span v-if="errors.general" class="siteMenuAdmin__saveNote siteMenuAdmin__saveNote--err">{{ errors.general }}</span>
            </div>
        </form>
    </div>
</template>

<script>
/**
 * Add/Edit form view. Fetches its own bootstrap (field values, parent options,
 * source-select option HTML, gated flags) from the JSON API on mount, saves via
 * AJAX (FormData -> JSON) with inline validation, and emits `saved` / `cancel`
 * so the SPA root returns to the Manage view.
 */
export default {
    name: 'site-menu-form',
    props: {
        base: { type: String, required: true },
        csrf: { type: String, default: '' },
        formId: { type: [String, Number], default: null },
        parentId: { type: [String, Number], default: null },
    },
    data() {
        return {
            loaded: false,
            addEdit: 'Add',
            isSuperAdmin: false,
            brandsEnabled: false,
            cmsEnabled: false,
            categoriesMax: 0,
            debug: false,
            parentOptions: [],
            options: {},
            form: {
                id: '',
                name: '',
                published: false,
                parent_id: '0',
                url: '',
                target: '_self',
                css_class: '',
                brand_list: '0',
                single_cms_page: false,
                mega_menu: false,
                mega_menu_items: [],
            },
            errors: {},
            saving: false,
        };
    },
    computed: {
        isRoot() { return String(this.form.parent_id) === '0'; },
        categoryIdHtml() { return '<option value="0">None</option>' + (this.options.category_id || ''); },
        singleCategoryHtml() { return '<option value="0">None</option>' + (this.options.single_category || ''); },
        cmsTreeHtml() { return '<option value="-1">None</option>' + (this.options.cms_tree || ''); },
        // Serialise just the { type, id } refs for the hidden form field; the
        // name/url on each item are display-only and re-resolved server-side.
        megaItemsJson() {
            return JSON.stringify((this.form.mega_menu_items || []).map(item => ({ type: item.type, id: item.id })));
        },
    },
    mounted() {
        let url = this.base + '/api/form/' + (this.formId || '');
        if (!this.formId && this.parentId) { url += '?parent_id=' + this.parentId; }
        fetch(url, { headers: { Accept: 'application/json' }, credentials: 'same-origin' })
            .then(response => response.json())
            .then(data => {
                this.addEdit = data.add_edit;
                this.isSuperAdmin = data.is_super_admin;
                this.brandsEnabled = data.brands_enabled;
                this.cmsEnabled = data.cms_enabled;
                this.categoriesMax = data.categories_max;
                this.parentOptions = data.parent_options || [];
                this.options = data.options || {};
                const m = data.menu || {};
                this.form = {
                    id: m.id || '',
                    name: m.name || '',
                    published: !!m.published,
                    parent_id: String(m.parent_id != null ? m.parent_id : 0),
                    url: m.url || '',
                    target: m.target || '_self',
                    css_class: m.css_class || '',
                    brand_list: String(data.brand_list || 0),
                    single_cms_page: !!m.single_cms_page,
                    mega_menu: !!m.mega_menu,
                    mega_menu_items: Array.isArray(m.mega_menu_items) ? m.mega_menu_items : [],
                };
                this.loaded = true;
            })
            .catch(() => { this.errors = { general: 'Could not load the form.' }; this.loaded = true; });
    },
    methods: {
        indent(level) {
            let out = '';
            for (let n = 0; n < level; n++) { out += '— '; }
            return out;
        },
        clearError(field) {
            if (this.errors[field]) { this.$delete(this.errors, field); }
        },
        submit() {
            this.errors = {};
            if (!this.form.name || !this.form.name.trim()) {
                this.$set(this.errors, 'name', 'Menu item name is required');
                return;
            }
            this.saving = true;
            const body = new FormData(this.$refs.form);
            fetch(this.base + '/save', {
                method: 'POST',
                headers: { Accept: 'application/json' },
                credentials: 'same-origin',
                body,
            })
                .then(response => response.json().then(data => ({ status: response.status, data })))
                .then(({ status, data }) => {
                    if (status >= 400 || (data && data.errors)) {
                        this.errors = (data && data.errors) || { general: 'Save failed.' };
                        return;
                    }
                    this.$emit('saved');
                })
                .catch(() => { this.errors = { general: 'Could not save. Please try again.' }; })
                .finally(() => { this.saving = false; });
        },
    },
};
</script>
