import {getGroupColor} from './../utils.js';

export default {

    data() {
        return {
            group: null,
            filter: '',
            selected: null,
            getGroupColor
        }
    },

    props: {
        components: {
            type: Object,
            default: {}
        },
        init: {
            type: Boolean,
            default: true
        },
        select: {
            type: Function,
        },
        layout: {
            type: Array,
            default: []
        },
        insertPosition: {
            type: Number,
            default: -1
        },
        globalComponents: {
            type: Object,
            default: null
        },
    },

    computed: {

        filtered() {

            let components = {}, component = null;

            Object.keys(this.components || {}).sort((x, y) => {

                // sort components
                x = (this.components[x].label || x).toLocaleLowerCase();
                y = (this.components[y].label || y).toLocaleLowerCase();

                if (x < y) return -1;
                if (x > y) return 1;

                return 0;

            }).forEach(name => {

                if (this.filter && !`${name} ${this.components[name].label || ''}`.toLocaleLowerCase().includes(this.filter.toLocaleLowerCase())) {
                    return;
                }

                if (this.group && this.components[name].group != this.group ) return;

                components[name] = this.components[name]
            });

            return components;
        },

        groups() {
            let groups = [];

            Object.keys(this.components || {}).forEach(name => {
                if (!this.components[name].group || groups.indexOf(this.components[name].group) > -1) return;
                groups.push(this.components[name].group);
            });

            return groups.sort();
        },

        selectedComponent() {
            return this.selected !== null ? Object.keys(this.filtered)[this.selected] : null;
        }
    },

    mounted() {
        setTimeout(() => {
            const autofocus = this.$el.parentNode.querySelector('input[autofocus]');
            if (autofocus) autofocus.focus();
        }, 150);
    },

    methods: {

        selectComponent(component) {

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

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

            let item = {
                id: App.utils.nanoid(),
                component,
                label: meta.label || component,
                children: meta.children ? [] : null,
                data,
                meta: {}
            };

            if (!this.init) {
                this.select(item);
                return;
            }

            VueView.ui.modal('layout:assets/vue-components/layout/component-edit.js', {component: item, mode: 'add', globalComponents: this.globalComponents}, {

                save: component => {

                    Object.assign(item, component);

                    if (this.insertPosition > -1) {
                        this.layout.splice(this.insertPosition + 1, 0, item);
                    } else {
                        this.layout.push(item);
                    }

                    this.select(item);
                }
            }, {size: meta.opts?.['dialog.size'] || 'large'})
        },

        previewUrl(component) {

            const image = this.components[component].image || null;

            if (!image || !image.file) {
                return null;
            }

            return `uploads://buckets/${image.bucket}/${image.file.path}`;
        },

        keydown(event) {

            switch (event.keyCode) {

                // close on ESC
                case 27:
                    this.selected = null;
                    break;
                // enter
                case 13:

                    if (this.selected !== null) {
                        event.preventDefault();
                        this.selectComponent(this.selectedComponent);
                        return;
                    }

                    if (Object.keys(this.filtered).length === 1) {
                        event.preventDefault();
                        this.selectComponent(Object.keys(this.filtered)[0]);
                        return;
                    }

                    break;

                // up | down
                case 38:
                case 40:

                    const components = Object.keys(this.filtered);

                    if (!components.length) {
                        return;
                    }

                    event.preventDefault();

                    if (this.selected === null) {
                        this.selected = event.keyCode == 38 ? components.length - 1 : 0;
                    } else {

                        if (event.keyCode == 38) {
                            this.selected = components[this.selected - 1] ? this.selected - 1 : components.length - 1 ;
                        } else {
                            this.selected = components[this.selected + 1] ? this.selected + 1 : 0 ;
                        }
                    }

                    const ele = document.getElementById(`layout-component-picker-${this.selectedComponent}`);

                    if (ele) {
                        ele.scrollIntoView({behavior: 'smooth', block: 'start'});
                    }
                    break;
            }
        }

    },

    template: /* html */`

        <div class="kiss-padding">
            <input type="text" class="kiss-input" :placeholder="t('Filter components...')" @keydown="keydown" @input="selected=null" v-model="filter" autofocus>

            <div class="kiss-flex kiss-margin-small-top kiss-width-1-2@m kiss-overlay-input" gap>
                <div>
                    <div>
                        <span class="kiss-text-caption kiss-color-muted">{{ t('Group') }}</span>
                        <div class="kiss-text-capitalize kiss-size-xsmall" :class="{'kiss-color-muted': !group, 'kiss-text-bold': group}">{{ group || t('All components') }}</div>
                    </div>
                    <select v-model="group" @change="selected=null">
                        <option :value="null">{{ t('All components') }}</option>
                        <option :value="name" v-for="name in groups">{{ name }}</option>
                    </select>
                </div>
            </div>
        </div>

        <div class="app-offcanvas-content kiss-padding">

            <div class="kiss-flex kiss-flex-center" v-if="components && !Object.keys(filtered).length">
                <div class="kiss-color-muted kiss-align-center">
                    <div><kiss-svg :src="$baseUrl('layout:assets/icons/component.svg')" width="50" height="50"></kiss-svg></div>
                    <div class="kiss-margin-small">{{ t('No components') }}</div>
                </div>
            </div>

            <kiss-card :id="'layout-component-picker-'+component" class="kiss-padding-small kiss-position-relative kiss-margin-small" theme="bordered" hover="contrast shadow" :style="{borderColor: selectedComponent == component ? 'var(--kiss-color-primary)':''}" v-for="meta, component in filtered">
                <kiss-row class="kiss-flex-middle" gap="small">
                    <div>
                        <kiss-svg :src="$baseUrl(meta.icon)" width="35" height="35" :style="{color: getGroupColor(meta.group)}" v-if="meta.icon"></kiss-svg>
                        <app-avatar size="35" :name="meta.label || component" :color="getGroupColor(meta.group)" v-if="!meta.icon"></app-avatar>
                    </div>
                    <div class="kiss-size-small kiss-flex-1">
                        <div class="kiss-text-bold kiss-text-truncate">{{ meta.label || component }}</div>
                        <div class="kiss-size-xsmall kiss-color-muted">{{ meta.group || '' }}</div>
                    </div>
                </kiss-row>
                <div class="kiss-margin-small-top kiss-flex kiss-flex-center kiss-position-relative kiss-bgcolor-transparentimage" v-if="components[component].image">
                    <display-image class="kiss-display-block kiss-margin-auto" :src="previewUrl(component)" w="600"></display-image>
                </div>
                <a class="kiss-cover" @click="selectComponent(component)" :title="meta.label || component"></a>
            </kiss-card>

        </div>
        `
}
