<template>
    <vue-form
        :http="http"
        :i18n="i18n"
        :locale="lang"
        :path="path"
        :error-handler="errorHandler"
        :router-error-handler="routerErrorHandler"
        :disable-state="disableState"
        :readonly="readonly"
        @submit="success"
        @destroy="success"
        @ready="init"
        ref="form">
        <template v-for="customField in customFields"
            #[customField.name]="props">
            <slot :name="customField.name"
                v-bind="props"/>
        </template>
        <template v-for="section in customSections"
            #[section.slot]="props">
            <slot :name="section.slot"
                v-bind="props"/>
        </template>
        <template v-for="actions in ['actions-right', 'actions-left']"
            #[actions]="props">
            <slot :name="actions"
                v-bind="props"/>
        </template>
    </vue-form>
</template>

<script>
import { bookmarks } from '@enso-ui/bookmarks/src/pinia/bookmarks';
import { preferences } from '@enso-ui/ui/src/pinia/preferences';
import VueForm from './VueForm.vue';

export default {
    name: 'EnsoForm',

    components: { VueForm },

    inject: ['errorHandler', 'http', 'i18n', 'route', 'routerErrorHandler', 'toastr'],

    props: {
        disableState: {
            type: Boolean,
            default: false,
        },
        readonly: {
            type: Boolean,
            default: false,
        },
    },

    data: () => ({
        ready: false,
    }),

    computed: {
        lang() {
            return preferences().global.lang;
        },
        bookmarks() {
            return preferences().global.bookmarks;
        },
        customFields() {
            return this.ready
                ? this.$refs.form.customFields
                : [];
        },
        customSections() {
            return this.ready
                ? this.$refs.form.customSections
                : [];
        },
        data() {
            return this.ready
                ? this.$refs.form.data
                : [];
        },
        loading() {
            return this.ready
                ? this.$refs.form.loading
                : [];
        },
        formData() {
            return this.ready
                ? this.$refs.form.formData
                : [];
        },
        dirty() {
            return this.ready
                ? this.$refs.form.dirty
                : false;
        },
        dirtyFields() {
            return this.ready
                ? this.$refs.form.dirtyFields
                : false;
        },
        errors() {
            return this.ready
                ? this.$refs.form.errors
                : null;
        },
        path() {
            return this.$attrs.path
                ?? this.route(this.$route.name, this.$route.params, false);
        },
    },

    watch: {
        formData: {
            handler(formData) {
                if (this.disableState || !this.bookmarks) {
                    return;
                }

                if (!this.dirty) {
                    bookmarks().updateState({ bookmark: this.$route });
                    return;
                }

                bookmarks().updateState({
                    bookmark: this.$route,
                    data: JSON.parse(JSON.stringify(formData)),
                });
            },
            deep: true,
        },
        dirty(dirty) {
            if (!this.disableState && !dirty && this.bookmarks) {
                bookmarks().updateState({ bookmark: this.$route });
            }
        },
    },

    methods: {
        init() {
            this.ready = true;

            if (this.disableState || !this.bookmarks) {
                return;
            }

            const state = bookmarks().stateByBookmark(this.$route);

            if (state) {
                this.$nextTick(() => this.fill(state));
            }
        },
        fetch() {
            return this.ready
                && this.$refs.form.fetch();
        },
        submit() {
            return this.ready
                && this.$refs.form.submit();
        },
        field(field) {
            return this.ready
                && this.$refs.form.field(field);
        },
        param(param) {
            return this.ready
                && this.$refs.form.param(param);
        },
        routeParam(param) {
            return this.ready
                && this.$refs.form.routeParam(param);
        },
        fill(state) {
            return this.ready
                && this.$refs.form.fill(state);
        },
        setOriginal() {
            return this.ready
                && this.$refs.form.setOriginal();
        },
        undo() {
            return this.ready
                && this.$refs.form.undo();
        },
        hideTab(tab) {
            return this.ready
                && this.$refs.form.hideTab(tab);
        },
        showTab(tab) {
            return this.ready
                && this.$refs.form.showTab(tab);
        },
        hideField(field) {
            return this.ready
                && this.$refs.form.hideField(field);
        },
        showField(field) {
            return this.ready
                && this.$refs.form.showField(field);
        },
        success(data) {
            if (data.message) {
                this.toastr.success(data.message);
            }
        },
    },
};
</script>
