/* 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 api from '@yootheme/api';
import http from '@yootheme/http';
import essentials from 'essentials';
import { DynamicPanel } from '@essentials/core/source';
import { flattenChildren } from '@essentials/core/util';

const FormAreaPanel = 'yooessentials-form-settings';

export default {
    name: 'EssentialsFormModel',

    data: () => ({
        formNode: null,
        actions: essentials.customizer?.form_actions || {},
    }),

    created() {
        essentials.FormModel = this;
    },

    watch: {
        formNode(node) {
            node ? this.addFormSchema(node) : this.resetSchema();
        },
    },

    events: {
        openPanel(e, panel) {
            const panels = [panel, ...(e.sidebar?.stack || [])];
            const formPanel = panels.find((s) => s.name === 'yooessentials-form-settings');

            if (formPanel) {
                const node = formPanel.props?.node;
                const enabled = node?.props?.yooessentials_form?.state;

                this.formNode = enabled ? node : null;
                return;
            }

            this.formNode = null;
        },

        closePanel(e, payload, panel) {
            if (panel.name === 'yooessentials-form-settings') {
                this.formNode = null;
            }
        },
    },

    methods: {
        addFormSchema(node = this.formNode) {
            this.$prevschema = api.builder.schema;

            const controls = this.getFields(node).map((field) => ({
                name: field?.props?.control_name,
                type: field?.type?.name,
                props: field?.props,
            }));

            if (controls.length) {
                http('yooessentials/form/schema')
                    .post({ controls })
                    .json((schema) => {
                        api.builder.schema = schema;
                    });
            }
        },

        resetSchema() {
            if (!this.$prevschema) {
                return;
            }

            api.builder.schema = this.$prevschema;
            this.$prevschema = null;
        },

        closestForm(node = this.formNode) {
            while (node && !node.props?.yooessentials_form?.state) {
                node = essentials.Builder?.parent(node);
            }

            return node;
        },

        controls(node = this.formNode) {
            return this.getFields(node).map((field) => field.props?.control_name);
        },

        getFields(node = this.formNode) {
            return flattenChildren(this.closestForm(node) || {})
                .filter(
                    (node) => node.type.match(/yooessentials_form_/) && node?.props?.control_name
                )
                .map((node) => ({ ...node, type: essentials.Builder.type(node) }))
                .filter((node) => node.type.submittable);
        },

        isInvalidField(node = this.formNode) {
            if (!node?.type?.match('^yooessentials_form_')) {
                return false;
            }

            const formArea = this.closestForm(node);

            if (!formArea) {
                return 'field-outside-form-area';
            }

            const siblings = flattenChildren(formArea);
            const controlName = node.props?.control_name;
            const controlNames = siblings
                .filter((n) => n.type.match(/^yooessentials_form_/))
                .map((n) => n.props?.control_name)
                .filter(Boolean);

            if (controlNames.filter((name) => name === controlName).length > 1) {
                return 'field-duplicated-control';
            }

            return false;
        },

        openFormAreaSettings(node) {
            const panel = api.customizer.panels[FormAreaPanel];

            if (!panel) {
                throw Error('Missing Form Area Panel');
            }

            this.$trigger('openPanel', {
                ...panel,
                component: DynamicPanel,
                props: {
                    node,
                    values: node?.props,
                },
            });
        },
    },
};
