let uuid = 0;

export default {

    _meta: {
        label: 'Component',
        info: 'Layout component',
        icon: 'layout:assets/icons/component.svg',
        settings: [
            {
                name: 'allowedComponents',
                type: 'select',
                label: 'Components',
                info: 'List of components to pick from.',
                opts: {
                    multiple: true,
                    src: {
                        route: `/layout/components?list=1&v=${App.version}`,
                        map: {
                            value: 'name',
                            label: 'name',
                        }
                    }
                }
            },
        ],
        render(value, field, context) {

            if (!value) {
                return 'n/a';
            }

            return `<display-component component='${JSON.stringify(value)}'></display-component>`;
        }
    },

    data() {
        return {
            val: this.modelValue || null,
            uuid: `field-component-${++uuid}`,

            ready: false,
            globalComponents: null,
        }
    },

    mounted() {

        App.utils.getlayoutComponents().then(components => {

            this.globalComponents = components;
            this.ready = true;

            if (!this.val && Array.isArray(this.allowedComponents) && this.allowedComponents.length == 1) {
                this.setComponent(this.allowedComponents[0]);
            }
        });
    },

    props: {
        modelValue: {
            type: Object,
            default: null
        },
        allowedComponents: {
            type: Array,
            default: []
        }
    },

    components: {
        componentPreview: Vue.defineAsyncComponent(() =>
            App.utils.import('layout:assets/vue-components/layout/component-preview.js')
        )
    },

    computed: {
        hasSwitch() {
            return Object.values(this.allowedComponents || []).length > 1;
        }
    },

    watch: {
        val: {
            handler() { this.update() },
            deep: true
        },
        modelValue: {
            handler(val) {
                this.val = this.modelValue || null;
                this.update();
            },
            deep: true
        },
    },

    methods: {

        setComponent(component) {

            let meta = this.globalComponents[component.component], data = {};

            if (!meta) {
                this.val = null;
                return;
            }

            (meta.fields || []).forEach(field => {
                data[field.name] = component.data[field.name] || field.default || null;
            });

            this.val = {
                id: App.utils.nanoid(),
                component: component.component,
                label: meta.label || component.component,
                children: null,
                data
            };
        },

        selectComponent() {

            let components = {}, allowed = Array.isArray(this.allowedComponents) && this.allowedComponents.length ? this.allowedComponents : Object.keys(this.globalComponents);

            Object.keys(this.globalComponents).forEach(name => {

                const meta = this.globalComponents[name] || {};
                const type = meta.type || null;

                const isLeaf = !meta.children && type !== 'grid' && type !== 'row';

                if (allowed.includes(name) && isLeaf) {
                    components[name] = meta;
                }
            });

            VueView.ui.offcanvas('layout:assets/vue-components/layout/component-picker.js', {

                globalComponents: this.globalComponents,
                components,

                shared: false,
                templates: false,
                clipboard: false
            }, {

                select: component => {
                    this.setComponent(component);
                }

            }, { flip: true, size: 'xlarge' })

        },

        hasPreview(component) {
            if (
                this.globalComponents[component.component] &&
                (
                    // template preview
                    this.globalComponents[component.component].preview ||
                    //component preview Url
                    (
                        this.globalComponents[component.component].opts &&
                        this.globalComponents[component.component].opts.previewComponent
                    )
                )
            ) {
                return true;
            }

            return false;
        },

        update() {
            this.$emit('update:modelValue', this.val)
        }
    },

    template: /*html*/`
        <div field="component">

            <div v-if="ready && val">
                <kiss-card class="kiss-margin-small kiss-padding-small kiss-text-caption kiss-flex kiss-flex-middle" theme="bordered">
                    <div class="kiss-flex-1">
                        <span class="kiss-color-muted">{{ t('Component') }}:</span> <strong>{{ globalComponents[val.component].label || val.component }}</strong>
                    </div>
                    <div v-if="hasSwitch">
                        <a @click="selectComponent()" :title="t('Switch component')"><icon size="larger">sync_alt</icon></a>
                    </div>
                </kiss-card>
                <kiss-card class="kiss-padding" theme="contrast">
                    <fields-renderer v-model="val.data" :fields="globalComponents[val.component].fields"></fields-renderer>
                </kiss-card>

            </div>

            <kiss-card class="kiss-flex kiss-flex-column kiss-flex-center kiss-padding-larger kiss-margin-small kiss-align-center kiss-color-muted kiss-position-relative" theme="contrast" hover="shadow" style="height:150px" v-if="ready && !val">
                <kiss-svg :src="$baseUrl('layout:assets/icons/component.svg')" width="30" height="30"><canvas width="30" height="30"></canvas></kiss-svg>
                <div class="kiss-margin-small kiss-size-small">{{ t('Select component') }}</div>
                <a class="kiss-cover" @click="selectComponent()"></a>
            </kiss-card>

        </div>
    `,
}
