/* Essentials YOOtheme Pro 2.2.16 build 0813.1608; ZOOlanders https://www.zoolanders.com; Copyright (C) Joolanders, SL; http://www.gnu.org/licenses/gpl.html GNU/GPL */

import Vue from 'vue';
import api from '@yootheme/api';
import hooks from '@yootheme/hooks';
import { DynamicCustomQuery, DynamicDropdown } from './components';
import SourceExt from './SourceExtended';
import find from 'lodash-es/find';

hooks.before('app.init', ({ extend }) => {
    extend({
        events: {
            essentialsPickSource({ origin: { node } }, field, { target }) {
                const options = SourceExt.getDynamicOptions({ node, field });
                const prop = SourceExt.getProp(node, field.name);

                this.$dropdown(DynamicDropdown, {
                    options,
                    field,
                    node,
                    prop,
                })
                    .show(target, {
                        classes: 'yo-dropdown',
                        boundaryX: target.closest('.yo-sidebar-fields > *') || target,
                    })
                    .then((value) => {
                        if (value) {
                            SourceExt.setExtendedProp(node, field.name, value);
                        }
                    });
            },

            essentialsPickArgumentSource({ origin: { $parent } }, field, { target }) {
                const node = $parent.node;

                // get all options that do not rely on a node
                const options = SourceExt.getDynamicOptions({
                    source: node.source || node.source_extended,
                    field,
                });

                const button = field.buttons.filter(
                    (btn) => btn.action === 'essentialsPickArgumentSource'
                )?.[0];

                const prop = button.isMultipleItemField
                    ? SourceExt.getSubQueryArgumentProp(node, field.name)
                    : SourceExt.getQueryArgumentProp(node, field.name);

                this.$dropdown(DynamicDropdown, {
                    options,
                    field,
                    node,
                    prop,
                })
                    .show(target, {
                        classes: 'yo-dropdown',
                        boundaryX: target.closest('.yo-sidebar-fields > *') || target,
                    })
                    .then((value) => {
                        if (value) {
                            if (button.isMultipleItemField) {
                                SourceExt.setSubQueryArgumentProp(node, field.name, value);
                            } else {
                                SourceExt.setQueryArgumentProp(node, field.name, value);
                            }
                        }
                    });
            },

            essentialsPickComposableSource({ origin: { node } }, field, { target }) {
                // const prop = SourceExt.getProp(node, field.name);

                const options = SourceExt.getDynamicOptions({ node }).filter(
                    (opt) => opt.name !== 'composable'
                );

                this.$dropdown(DynamicDropdown, {
                    options,
                    node,
                    prop: {},
                })
                    .show(target, {
                        classes: 'yo-dropdown',
                        boundaryX: target.closest('.yo-sidebar-fields > *') || target,
                    })
                    .then((value) => {
                        if (value) {
                            Vue.events.trigger('yeAddComposableSource', value);
                        }
                    });
            },

            prepareFields: {
                handler({ origin: { builder, node } }, fields) {
                    // add composable source field buttons
                    for (const field of fields) {
                        if (field.type === 'yooessentials-composable-source') {
                            field.buttons = field.buttons || [];
                            field.buttons = field.buttons.concat([
                                {
                                    label: this.$t('Add Dynamic'),
                                    action: 'essentialsPickComposableSource',
                                    show: () => true,
                                },
                            ]);
                        }
                    }
                },
                priority: -5, // execute latest
            },
        },
    });
});

/**
 * inherit node
 */
Vue.events.on('essentialsDynamicOptions', ({ result = [] }, { node, field }) => {
    if (!node) {
        return result;
    }

    const { Source } = api.builder.helpers;
    const activeNode = SourceExt.resolveAdjacentNode(node);
    const queryName = Source.getQuery(activeNode);

    if (!queryName) {
        return result;
    }

    const source = Source.getSourceField(SourceExt.path(activeNode));

    result.push({
        group: Vue.i18n.t('Inherit'),
        name: 'inherit.node',
        title: 'Node',
        crumb: 'Node',
        priority: 10,
        meta: source?.type?.ofType?.name || source?.metadata?.label,
        source: () => source,
        match: ({ prop }) => {
            // if no prop, this option is assumed default
            if (!prop && queryName) {
                return true;
            }

            // if prop has query or has no name, it's not inheriting node
            if (prop?.query || !prop.name) {
                return false;
            }

            return queryName && prop;
        },
        resolve: ({ name }) => {
            if (!field) {
                return { name };
            }

            Source.setProp(SourceExt.path(node), field.name, {
                name,
            });

            return false;
        },
    });

    return result;
});

/**
 * inherit closest
 */
Vue.events.on('essentialsDynamicOptions', ({ result = [] }, { node }) => {
    if (!node) {
        return result;
    }

    const { Schema } = api.builder.helpers;
    const closest = SourceExt.getClosestInheritableNode(node);

    if (!closest) {
        return result;
    }

    const source = Schema.findField(SourceExt.getQueryPath(closest));
    const ofType = find(Schema.types, { name: source?.type?.ofType?.name });
    const isMulti = source?.type?.kind === 'LIST';

    result.push({
        group: Vue.i18n.t('Inherit'),
        name: 'inherit.closest',
        title: 'Closest',
        crumb: 'Closest',
        priority: 5,
        meta:
            isMulti && ofType?.metadata?.label
                ? `${source?.metadata?.label} (${ofType.metadata.label})`
                : source?.metadata?.label,
        source: () => source,
        match: ({ prop }) => prop?.query?.name === SourceExt.closestKey,
        resolve: ({ name }) => ({
            name,
            query: { name: SourceExt.closestKey },
        }),
    });

    return result;
});

/**
 * page queries
 */
Vue.events.on('essentialsDynamicOptions', ({ result = [] }) => {
    const { Schema } = api.builder.helpers;

    for (const pageQuery of SourceExt.getPageQueries()) {
        const query = { name: pageQuery.name };
        const source = Schema.findField(pageQuery.name);

        result.push({
            group: Vue.i18n.t('Page'),
            name: `page.${pageQuery.name}`,
            title: source?.metadata.label,
            source: () => source,
            match: ({ prop }) => prop?.query?.name === pageQuery.name,
            resolve: ({ name }) => ({ name, query }),
        });
    }

    return result;
});

/**
 * global sources
 */
Vue.events.on('essentialsDynamicOptions', ({ result = [] }) => {
    const { Schema } = api.builder.helpers;

    for (const globalSource of SourceExt.globalSources) {
        const query = { name: globalSource.name };
        const source = Schema.findField(globalSource.name);

        result.push({
            group: Vue.i18n.t('Global'),
            name: `global.${globalSource.name}`,
            title: source?.metadata.label,
            source: () => source,
            match: ({ prop }) => prop?.query?.name === globalSource.name,
            resolve: ({ name }) => ({ name, query }),
        });
    }

    return result;
});

/**
 * custom query
 */
Vue.events.on(
    'essentialsDynamicOptions',
    ({ result = [] }) => {
        result.push({
            group: '',
            name: 'query',
            title: 'Custom Query',
            component: DynamicCustomQuery,
            source: ({ prop }) => {
                return SourceExt.findQueryField(prop?.query);
            },
            match: ({ prop }) => {
                return SourceExt.findQueryField(prop?.query);
            },
            resolve: ({ name, query }) => ({ name, query }),
        });
    },
    -50
);
