;(function($) {
'use strict';

Vue.component('field-address', {
    template: '#tmpl-wpuf-field-address',

    mixins: [
        wpuf_mixins.option_field_mixin,
        wpuf_mixins.form_field_mixin,
    ],

    data: function () {
        return {
            default_country: this.editing_form_field.address.country_select.value,
            show_details: {
                street_address:  false,
                street_address2: false,
                city_name:       false,
                state:           false,
                zip:             false,
                country_select:  false,
            },
        };
    },

    computed: {
        countries: function () {
            return wpuf_form_builder.countries;
        },

        visibility_buttons: function () {
            return [
                { name: 'all', title: this.i18n.show_all },
                { name: 'hide', title: this.i18n.hide_these },
                { name: 'show', title: this.i18n.only_show_these }
            ];
        },

        active_visibility: function () {
            return this.editing_form_field.address.country_select.country_list_visibility_opt_name;
        },

        country_in_hide_list: function () {
            return this.editing_form_field.address.country_select.country_select_hide_list;
        },

        country_in_show_list: function () {
            return this.editing_form_field.address.country_select.country_select_show_list;
        }
    },

    mounted: function () {
        this.bind_selectize();
    },

    methods: {
        toggle_address_checked: function(field) {
            this.editing_form_field.address[field].checked = this.editing_form_field.address[field].checked ? '' : 'checked';
        },

        toggle_address_required: function(field) {
            this.editing_form_field.address[field].required = this.editing_form_field.address[field].required ? '' : 'checked';
        },

        toggle_show_details: function (field) {
            this.show_details[field] = !this.show_details[field];
        },

        bind_selectize: function () {
            var self = this;

            $(this.$el).find('.default-country').selectize({
                plugins: ['remove_button'],

            }).on('change', function () {
                var value = $(this).val();

                self.default_country = value;
                self.update_country_select('value', value);
            });

            $(this.$el).find('select.country-list-selector').selectize({
                plugins: ['remove_button'],
                placeholder: this.i18n.select_countries

            }).on('change', function (e) {
                var select      = $(this),
                    visibility  = e.target.dataset.visibility,
                    value       = select.val(),
                    list        = '';

                switch(visibility) {
                    case 'hide':
                        list = 'country_select_hide_list';
                        break;

                    case 'show':
                        list = 'country_select_show_list';
                        break;
                }

                if (!value) {
                    value = [];
                }

                self.update_country_select(list, value);

            });
        },

        update_country_select: function (prop, value) {
            var address = $.extend(true, {}, this.editing_form_field.address);

            address.country_select[prop] = value;

            this.update_value('address', address);
        },

        set_visibility: function(visibility) {
            this.update_country_select('country_list_visibility_opt_name', visibility);
        },
    }
});

Vue.component('field-conditional-logic', {
    template: '#tmpl-wpuf-field-conditional-logic',

    mixins: [
        wpuf_mixins.option_field_mixin,
        wpuf_mixins.form_field_mixin
    ],

    data: function () {
        return {
            conditions: [],
            rule_options: [
                {
                    label: 'All',
                    value: 'all',
                },
                {
                    label: 'Any',
                    value: 'any',
                }
            ],
            all_conditional_operators: {
                radio: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ],
                text: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'contains',
                        value: '==contains',
                    },
                    {
                        label: 'has any value',
                        value: '!=empty',
                    },
                    {
                        label: 'has no value',
                        value: '==empty',
                    }
                ],
                number: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'contains',
                        value: '==contains',
                    },
                    {
                        label: 'has any value',
                        value: '!=empty',
                    },
                    {
                        label: 'has no value',
                        value: '==empty',
                    },
                    {
                        label: 'value is greater then',
                        value: 'greater',
                    },
                    {
                        label: 'value is less then',
                        value: 'less',
                    }
                ],
                others: [
                    {
                        label: 'has any value',
                        value: '!=empty',
                    },
                    {
                        label: 'has no value',
                        value: '==empty',
                    }
                ]
            }
        };
    },

    computed: {
        wpuf_cond: function () {
            return this.editing_form_field.wpuf_cond;
        },

        hierarchical_taxonomies: function () {
            var hierarchical_taxonomies = [];

            _.each(wpuf_form_builder.wp_post_types, function (taxonomies) {
                _.each(taxonomies, function (tax_props, taxonomy) {
                    if (tax_props.hierarchical) {
                        hierarchical_taxonomies.push(taxonomy);
                    }
                });
            });

            return hierarchical_taxonomies;
        },

        wpuf_cond_supported_fields: function () {
            return wpuf_form_builder.wpuf_cond_supported_fields.concat(this.hierarchical_taxonomies);
        },

        dependencies: function () {
            var self = this,
                dependenciesFields = [],
                i = 0;

            for (i = 0; i < self.$store.state.form_fields.length; i++) {

                var field = self.$store.state.form_fields[i];

                if ('column_field' === field.template) {
                    var innerColumnFields = self.$store.state.form_fields[i].inner_fields;

                    for (const columnFields in innerColumnFields) {
                        if (innerColumnFields.hasOwnProperty(columnFields)) {
                            var columnFieldIndex = 0;

                            while (columnFieldIndex < innerColumnFields[columnFields].length) {
                                var columnInnerField = innerColumnFields[columnFields][columnFieldIndex];

                                if ('taxonomy' !== columnInnerField.template) {
                                    if ( (_.indexOf(self.wpuf_cond_supported_fields, columnInnerField.template) >= 0) &&
                                            columnInnerField.name &&
                                            columnInnerField.label &&
                                            (self.editing_form_field.name !== columnInnerField.name)
                                        )
                                    {
                                        dependenciesFields.push(columnInnerField);
                                    }
                                } else {
                                    if ( (_.indexOf(self.wpuf_cond_supported_fields, columnInnerField.name) >= 0) &&
                                            columnInnerField.label &&
                                            (self.editing_form_field.name !== columnInnerField.name)

                                        )
                                    {
                                        dependenciesFields.push(columnInnerField);
                                    }
                                }

                                columnFieldIndex++;
                            }
                        }
                    }

                } else if ('taxonomy' !== field.template && 'column_field' !== field.template) {

                    if ( (_.indexOf(self.wpuf_cond_supported_fields, field.template) >= 0) &&
                            field.name &&
                            field.label &&
                            (self.editing_form_field.name !== field.name)
                        )
                    {
                        dependenciesFields.push(field);
                    }

                } else {

                    if ( (_.indexOf(self.wpuf_cond_supported_fields, field.name) >= 0) &&
                            field.label &&
                            (self.editing_form_field.name !== field.name)

                        )
                    {
                        dependenciesFields.push(field);
                    }

                }
            }

            return dependenciesFields;
        },

        prev_conditions: function () {
            let self = this,
                prev_fields = {},
                i = 0;

            for (i = 0; i < self.$store.state.form_fields.length; i++) {
                let field = self.$store.state.form_fields[i];
                prev_fields[field.name] = field.input_type;
            }

            return prev_fields;
        }
    },

    created: function () {
        var wpuf_cond = $.extend(true, {}, this.editing_form_field.wpuf_cond),
            prev_conditions = this.prev_conditions,
            self = this;

        _.each(wpuf_cond.cond_field, function (name, i) {

            if (name && wpuf_cond.cond_field[i] && wpuf_cond.cond_operator[i]) {
                const input_types = wpuf_cond.input_type !== undefined ? wpuf_cond.input_type : '';
                const option_title = wpuf_cond.option_title !== undefined && wpuf_cond.option_title[i] !== undefined ? wpuf_cond.option_title[i] : "";
                let input_type = '';
                // for backward compatibility
                if (input_types === '') {
                    input_type = prev_conditions[name] !== undefined ? prev_conditions[name] : '';
                } else {
                    input_type = input_types[i] !== undefined ? input_types[i] : '';
                }
                self.conditions.push({
                    name: name,
                    operator: wpuf_cond.cond_operator[i],
                    option: wpuf_cond.cond_option[i],
                    option_title: option_title,
                    input_type: input_type,
                    field_type: (wpuf_cond.field_type !== undefined) && (wpuf_cond.field_type[i] !== undefined) ? wpuf_cond.field_type[i] : ''
                });
            }

        });

        if (!self.conditions.length) {
            self.conditions = [{
                name: '',
                operator: '',
                option: ''
            }];
        }
    },

    methods: {
        get_cond_options: function (field_name) {
            var options = [];

            if (_.indexOf(this.hierarchical_taxonomies, field_name) < 0) {
                var dep = this.dependencies.filter(function (field) {
                    return field.name === field_name;
                });

                if (dep.length && dep[0].options) {
                    _.each(dep[0].options, function (option_title, option_name) {
                        options.push({opt_name: option_name, opt_title: option_title});
                    });
                }

            } else {
                // NOTE: Two post types cannot have same taxonomy
                // ie: post_type_one and post_type_two cannot have same taxonomy my_taxonomy
                var i;

                for (i in wpuf_form_builder.wp_post_types) {
                    var taxonomies = wpuf_form_builder.wp_post_types[i];

                    if (taxonomies.hasOwnProperty(field_name)) {
                        var tax_field = taxonomies[field_name];

                        if (tax_field.terms && tax_field.terms.length) {
                            var j = 0;

                            for (j = 0; j < tax_field.terms.length; j++) {
                                options.push({opt_name: tax_field.terms[j].term_id, opt_title: tax_field.terms[j].name});
                            }
                        }

                        break;
                    }
                }
            }

            return options;
        },

        get_cond_operators: function (field_type) {
            switch (field_type) {
                case 'select':
                case 'radio':
                case 'category':
                case 'taxonomy':
                case 'checkbox':
                    return this.all_conditional_operators.radio;
                case 'text':
                case 'textarea':
                case 'email':
                case 'url':
                case 'password':
                    return this.all_conditional_operators.text;
                case 'numeric_text':
                    return this.all_conditional_operators.number;
                case null:
                    return [];
                default:
                    return this.all_conditional_operators.others;
            }
        },

        show_dropdown: function(input_type) {
            switch (input_type) {
                case 'select':
                case 'radio':
                case 'category':
                case 'taxonomy':
                case 'checkbox':
                    return true;
                default:
                    return false;
            }
        },

        show_textfield: function(input_type) {
            switch (input_type) {
                case 'select':
                case 'radio':
                case 'category':
                case 'taxonomy':
                case 'checkbox':
                    return false;
                default:
                    return true;
            }
        },

        on_change_cond_field: function (index, event) {
            let current_condition = this.conditions[index];
            current_condition.option = '';
            const the_target = event.target.options[event.target.options.selectedIndex];
            const input_type = the_target.dataset.type;
            const field_type = the_target.dataset.fieldType;
            const opt_name = this.get_cond_options(current_condition.name)[0] !== undefined ? this.get_cond_options(current_condition.name)[0].opt_name : '';
            current_condition.input_type = input_type;
            current_condition.field_type = field_type !== undefined ? field_type : input_type;
            // set the default selected item
            current_condition.operator = this.get_cond_operators(input_type)[0].value;
            current_condition.option = opt_name;

            if (input_type === 'textarea' && (this.dependencies[event.target.options.selectedIndex - 1]).hasOwnProperty('rich') ) {
                current_condition.field_type = this.dependencies[event.target.options.selectedIndex - 1].rich;
            }
        },

        on_change_options_field: function (index, event) {
            const current_condition = this.conditions[index];
            const the_target = event.target.options[event.target.options.selectedIndex];
            const option_title = the_target.dataset.optionTitle !== undefined ? the_target.dataset.optionTitle : "";

            current_condition.option_title = option_title;
        },

        is_disabled: function(operator) {
            // check if the operator is set to 'has any value' or 'has no value'
            return (operator === '==empty') || (operator === '!=empty');
        },

        add_condition: function () {
            this.conditions.push({
                name: '',
                operator: '',
                option: '',
                option_title: '',
                input_type: '',
                field_type: ''
            });
        },

        delete_condition: function (index) {
            if (this.conditions.length === 1) {
                this.warn({
                    text: this.i18n.last_choice_warn_msg,
                    showCancelButton: false,
                    confirmButtonColor: "#46b450",
                });

                return;
            }

            this.conditions.splice(index, 1);
        },

        update_cond_logic( data ) {
            this.editing_form_field.wpuf_cond.cond_logic = data;
        }
    },

    watch: {
        conditions: {
            deep: true,
            handler: function (new_conditions) {
                var new_wpuf_cond = $.extend(true, {}, this.editing_form_field.wpuf_cond);

                if (!this.editing_form_field.wpuf_cond) {
                    new_wpuf_cond.condition_status = 'no';
                    new_wpuf_cond.cond_logic = 'all';
                }

                new_wpuf_cond.cond_field = [];
                new_wpuf_cond.cond_operator = [];
                new_wpuf_cond.cond_option = [];
                new_wpuf_cond.option_title = [];
                new_wpuf_cond.input_type = [];
                new_wpuf_cond.field_type = [];

                _.each(new_conditions, function (cond) {
                    new_wpuf_cond.cond_field.push(cond.name);
                    new_wpuf_cond.cond_operator.push(cond.operator);
                    if ((cond.operator === '==empty') || (cond.operator === '!=empty')) {
                        new_wpuf_cond.cond_option.push('');
                    } else {
                        new_wpuf_cond.cond_option.push(cond.option);
                    }
                    new_wpuf_cond.input_type.push(cond.input_type);
                    new_wpuf_cond.field_type.push(cond.field_type);
                    new_wpuf_cond.option_title.push(cond.option_title);
                });

                this.update_value('wpuf_cond', new_wpuf_cond);
            }
        }
    }
});

Vue.component('field-country-list', {
    template: '#tmpl-wpuf-field-country-list',

    mixins: [
        wpuf_mixins.option_field_mixin,
    ],

    data: function () {
        return {
            default_country: this.editing_form_field.country_list.name
        };
    },

    computed: {
        countries: function () {
            return wpuf_form_builder.countries;
        },

        visibility_buttons: function () {
            return [
                { name: 'all', title: this.i18n.show_all },
                { name: 'hide', title: this.i18n.hide_these },
                { name: 'show', title: this.i18n.only_show_these }
            ];
        },

        active_visibility: function () {
            return this.editing_form_field.country_list.country_list_visibility_opt_name;
        },

        country_in_hide_list: function () {
            return this.editing_form_field.country_list.country_select_hide_list;
        },

        country_in_show_list: function () {
            return this.editing_form_field.country_list.country_select_show_list;
        },

    },

    mounted: function () {
        this.bind_selectize();
    },

    watch: {
        met_dependencies: function(newVal, oldVal) {
            // When dependencies become met (component becomes visible)
            if (newVal && !oldVal) {
                var self = this;
                this.$nextTick(function() {
                    setTimeout(function() {
                        self.bind_selectize();
                    }, 100);
                });
            }
        }
    },

    methods: {
        bind_selectize: function () {
            var self = this;

            // Destroy existing selectize instances first (like field-multiselect does)
            var $defaultCountry = $(this.$el).find('.default-country');
            if ($defaultCountry[0] && $defaultCountry[0].selectize) {
                $defaultCountry[0].selectize.destroy();
            }

            $(this.$el).find('select.country-list-selector').each(function() {
                if ($(this)[0] && $(this)[0].selectize) {
                    $(this)[0].selectize.destroy();
                }
            });

            $defaultCountry.selectize({
                plugins: ['remove_button'],

            }).on('change', function () {
                var value = $(this).val();

                self.default_country = value;
                self.update_country_list('name', value);
            });

            $(this.$el).find('select.country-list-selector').selectize({
                plugins: ['remove_button'],
                placeholder: this.i18n.select_countries

            }).on('change', function (e) {
                var select      = $(this),
                    visibility  = e.target.dataset.visibility,
                    value       = select.val(),
                    list        = '';

                switch(visibility) {
                    case 'hide':
                        list = 'country_select_hide_list';
                        break;

                    case 'show':
                        list = 'country_select_show_list';
                        break;
                }

                if (!value) {
                    value = [];
                }

                self.update_country_list(list, value);

            });
        },

        update_country_list: function (prop, value) {
            var country_list = $.extend(true, {}, this.editing_form_field.country_list);

            country_list[prop] = value;

            this.update_value('country_list', country_list);
        },

        set_visibility: function(visibility) {
            this.update_country_list('country_list_visibility_opt_name', visibility);
        },
    }
});

Vue.component('field-dropdown', {
    template: '#tmpl-wpuf-field-dropdown',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    props: {
        options: {
            type: Array,
        },
        default_option: {
            type: [String, Boolean],
            default: false,
        },
        show_icon: {
            type: Boolean,
            default: true,
        },
        is_bordered: {
            type: Boolean,
            default: true,
        },
        container_class: {
            type: String,
            default: '',
        },
        placeholder_class: {
            type: String,
            default: '',
        },
        dropdown_class: {
            type: String,
            default: '',
        },
        dropdown_item_class: {
            type: String,
            default: '',
        },
        dropdown_link_class: {
            type: String,
            default: '',
        },
    },

    data: function () {
        return {
            is_open: false,
            selected: '',
        };
    },

    created: function() {
        this.selected = this.default_selected;
    },

    computed: {
        selected_option: function() {
            return this.selected ? this.selected : this.default_option;
        },

        default_selected: function() {
            if ( this.default_option ) {
                return this.default_option;
            }

            return this.options[0] ? this.options[0].value : '';
        }
    },

    methods: {
        selectOption: function(option) {
            this.selected = option;
            this.is_open = false;
        }
    }
});

Vue.component('field-gmap-set-position', {
    template: '#tmpl-wpuf-field-gmap-set-position',

    mixins: [
        wpuf_mixins.option_field_mixin,
        wpuf_mixins.form_field_mixin,
    ],

    /* global google */
    mounted: function () {
        var self = this,
            default_pos = self.editing_form_field.default_pos,
            default_zoom = self.editing_form_field.zoom;

        var default_latLng = default_pos.split(',');

        if (2 === default_latLng.length && isFinite(default_latLng[0]) && isFinite(default_latLng[1])) {
            default_pos = {lat: parseFloat(default_latLng[0]), lng: parseFloat(default_latLng[1])};
        } else {
            default_pos = {lat: 40.7143528, lng: -74.0059731};
        }

        var map = new google.maps.Map($(this.$el).find('.wpuf-field-google-map').get(0), {
            center: default_pos,
            zoom: parseInt(default_zoom) || 12,
            mapTypeId: 'roadmap',
            streetViewControl: false,
        });

        var geocoder = new google.maps.Geocoder();

        // Create the search box and link it to the UI element.
        var input = $(this.$el).find('.wpuf-google-map-search').get(0);
        var searchBox = new google.maps.places.SearchBox(input);
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

        // Bias the SearchBox results towards current map's viewport.
        map.addListener('bounds_changed', function() {
            searchBox.setBounds(map.getBounds());
        });

        var markers = [];

        set_marker(self.editing_form_field.default_pos);

        function set_marker(address) {
            geocoder.geocode({'address': address}, function(results, status) {
                if (status === 'OK') {
                    // Clear out the old markers.
                    _.each(markers, function (marker) {
                        marker.setMap(null);
                    });

                    markers = [];

                    // Create a marker for each place.
                    markers.push(new google.maps.Marker({
                        map: map,
                        position: results[0].geometry.location
                    }));

                    map.setCenter(results[0].geometry.location);

                    self.set_default_pos(results[0].geometry.location);
                }
            });
        }

        // when input latitude and longitude like "40.7143528,-74.0059731"
        input.addEventListener('input', function () {
            var address = this.value;

            var latLng = address.split(',');

            if (2 === latLng.length && isFinite(latLng[0]) && isFinite(latLng[1])) {
                set_marker(address);
            }
        });



        // Listen for the event fired when the user selects a prediction and retrieve
        // more details for that place.
        searchBox.addListener('places_changed', function() {
            var places = searchBox.getPlaces();

            if (places.length === 0) {
                return;
            }

            // Clear out the old markers.
            _.each(markers, function (marker) {
                marker.setMap(null);
            });

            markers = [];

            // For each place, get the icon, name and location.
            var bounds = new google.maps.LatLngBounds();

            _.each(places, function (place) {
                if (!place.geometry) {
                    console.log('Returned place contains no geometry');

                    return;
                }

                // Create a marker for each place.
                markers.push(new google.maps.Marker({
                    map: map,
                    position: place.geometry.location
                }));

                self.set_default_pos(place.geometry.location);

                if (place.geometry.viewport) {
                    // Only geocodes have viewport.
                    bounds.union(place.geometry.viewport);

                } else {
                    bounds.extend(place.geometry.location);
                }
            });

            map.fitBounds(bounds);
        });

        map.addListener('click', function(e) {
            var latLng = e.latLng;

            // Clear out the old markers.
            _.each(markers, function (marker) {
                marker.setMap(null);
            });

            markers = [];

            markers.push(new google.maps.Marker({
                position: latLng,
                map: map
            }));

            self.set_default_pos(latLng);

            map.panTo(latLng);
        });

        map.addListener('zoom_changed', function () {
            var zoom = map.getZoom();

            self.update_value('zoom', zoom);

            wpuf_form_builder.event_hub.$emit('wpuf-update-map-zoom-' + self.editing_form_field.id, zoom);
        });
    },

    methods: {
        toggle_checkbox_field: function (field) {
            this.editing_form_field[field] = ('yes' === this.editing_form_field[field]) ? 'no' : 'yes';
        },

        set_default_pos: function (latLng) {
            latLng = latLng.toJSON();

            this.update_value('default_pos', latLng.lat + ',' + latLng.lng);
        }
    }
});

Vue.component('field-math-captcha', {
    template: '#tmpl-wpuf-field-math-captcha',

    mixins: [
        wpuf_mixins.option_field_mixin
    ],
});

/**
 * Settings component for pricing option fields
 * Extends field-option-data with price support
 */
Vue.component('field-option-data-price', {
    template: '#tmpl-wpuf-field-option-data-price',

    mixins: [
        wpuf_mixins.option_field_mixin,
        wpuf_mixins.form_field_mixin
    ],

    data: function () {
        return {
            show_value: false,
            sync_value: true,
            options: [],
            selected: [],
            display: true
        };
    },

    computed: {
        field_options: function () {
            return this.editing_form_field.options;
        },

        field_prices: function () {
            return this.editing_form_field.prices || {};
        },

        field_selected: function () {
            return this.editing_form_field.selected;
        },

        is_multiple: function () {
            return this.option_field.is_multiple;
        }
    },

    mounted: function () {
        var self = this;

        this.set_options();

        $(this.$el).find('.option-field-option-chooser').sortable({
            items: '.option-field-option',
            handle: '.sort-handler',
            update: function (e, ui) {
                var item        = ui.item[0],
                    data        = item.dataset,
                    toIndex     = parseInt($(ui.item).index()),
                    fromIndex   = parseInt(data.index);

                self.options.swap(fromIndex, toIndex);
            }
        });
    },

    methods: {
        set_options: function () {
            var self = this;
            var field_options = $.extend(true, {}, this.editing_form_field.options);
            var field_prices = $.extend(true, {}, this.editing_form_field.prices || {});

            _.each(field_options, function (label, value) {
                self.options.push({
                    label: label,
                    value: value,
                    price: field_prices[value] || '0',
                    id: self.get_random_id()
                });
            });

            if (this.option_field.is_multiple && !_.isArray(this.field_selected)) {
                this.selected = [this.field_selected];
            } else {
                this.selected = this.field_selected;
            }
        },

        clear_selection: function () {
            if (this.option_field.is_multiple) {
                this.selected = [];
            } else {
                this.selected = null;
            }
        },

        add_option: function () {
            var count   = this.options.length,
                new_opt = this.i18n.option + '-' + (count + 1);

            this.options.push({
                label: new_opt,
                value: new_opt,
                price: '0',
                id: this.get_random_id()
            });
        },

        delete_option: function (index) {
            if (this.options.length === 1) {
                this.warn({
                    text: this.i18n.last_choice_warn_msg,
                    showCancelButton: false,
                    confirmButtonColor: "#46b450",
                });

                return;
            }

            this.options.splice(index, 1);
        },

        set_option_label: function (index, label) {
            if (this.sync_value) {
                this.options[index].value = label.toLocaleLowerCase().replace( /\s/g, '_' );
            }
        }
    },

    watch: {
        options: {
            deep: true,
            handler: function (new_opts) {
                var options = {},
                    prices = {},
                    i = 0;

                for (i = 0; i < new_opts.length; i++) {
                    options['' + new_opts[i].value] = new_opts[i].label;
                    prices['' + new_opts[i].value] = new_opts[i].price || '0';
                }

                this.update_value('options', options);
                this.update_value('prices', prices);
            }
        },

        selected: function (new_val) {
            this.update_value('selected', new_val);
        }
    }
});
Vue.component('field-repeater-columns', {
    template: '#tmpl-wpuf-field-repeater-columns',

    mixins: [
        wpuf_mixins.option_field_mixin
    ],

    mounted: function () {
        var self = this;

        $(this.$el).find('.repeater-columns').sortable({
            items: '.repeater-single-column',
            handle: '.sort-handler',
            update: function (e, ui) {
                var item        = ui.item[0],
                    data        = item.dataset,
                    toIndex     = parseInt($(ui.item).index()),
                    fromIndex   = parseInt(data.index);

                var columns = $.extend(true, [], self.editing_form_field.columns);

                columns.swap(fromIndex, toIndex);

                self.update_value('columns', columns);
            }
        }).disableSelection();
    },

    methods: {
        add_column: function () {
            var count       = this.editing_form_field.columns.length,
                new_column  = this.i18n.column + ' ' + (count + 1);

            this.editing_form_field.columns.push(new_column);
        },

        delete_column: function (index) {
            if (this.editing_form_field.columns.length === 1) {
                this.warn({
                    text: this.i18n.last_column_warn_msg,
                    showCancelButton: false,
                    confirmButtonColor: "#46b450",
                });

                return;
            }

            this.editing_form_field.columns.splice(index, 1);
        }
    },

    watch: {

    }
});

Vue.component('field-step-start', {
    template: '#tmpl-wpuf-field-step-start',

    mixins: [
        wpuf_mixins.option_field_mixin,
        wpuf_mixins.form_field_mixin
    ],
});

/**
 * Field template: Action Hook
 */
Vue.component('form-action_hook', {
    template: '#tmpl-wpuf-form-action_hook',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Address Field
 */
Vue.component('form-address_field', {
    template: '#tmpl-wpuf-form-address_field',

    mixins: [
        wpuf_mixins.option_field_mixin,
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        countries: function () {
            var countries   = wpuf_form_builder.countries,
                visibility  = this.field.address.country_select.country_list_visibility_opt_name,
                hide_list   = this.field.address.country_select.country_select_hide_list,
                show_list   = this.field.address.country_select.country_select_show_list;

            if ('hide' === visibility && hide_list && hide_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(hide_list, country.code) < 0);
                });

            } else if ('show' === visibility && show_list && show_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(show_list, country.code) >= 0);
                });
            }

            return countries;
        },

        default_country: function () {
            return this.field.address.country_select.value;
        }
    }
});

/**
 * Field template: Avatar
 */
Vue.component('form-avatar', {
    template: '#tmpl-wpuf-form-avatar',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

Vue.component('form-cart_total', {
    template: '#tmpl-wpuf-form-cart_total',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
/**
 * Field template: Country list
 */
Vue.component('form-country_list_field', {
    template: '#tmpl-wpuf-form-country_list_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        countries: function () {
            var countries   = wpuf_form_builder.countries,
                visibility  = this.field.country_list.country_list_visibility_opt_name,
                hide_list   = this.field.country_list.country_select_hide_list,
                show_list   = this.field.country_list.country_select_show_list;

            if ('hide' === visibility && hide_list && hide_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(hide_list, country.code) < 0);
                });

            } else if ('show' === visibility && show_list && show_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(show_list, country.code) >= 0);
                });
            }

            return countries;
        },

        default_country: function () {
            return this.field.country_list.name;
        }
    }
});

/**
 * Field template: Cover Photo
 */
Vue.component('form-cover_photo', {
    template: '#tmpl-wpuf-form-cover_photo',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});


/**
 * Field template: Date
 */
Vue.component('form-date_field', {
    template: '#tmpl-wpuf-form-date_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Date of Birth
 */
Vue.component('form-date_of_birth_field', {
    template: '#tmpl-wpuf-form-date_of_birth_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Display Name
 */
Vue.component('form-display_name', {
    template: '#tmpl-wpuf-form-display_name',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Embed
 */
Vue.component('form-embed', {
    template: '#tmpl-wpuf-form-embed',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
/**
 * Field template: Facebook URL
 */
Vue.component('form-facebook_url', {
    template: '#tmpl-wpuf-form-facebook_url',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: File upload
 */
Vue.component('form-file_upload', {
    template: '#tmpl-wpuf-form-file_upload',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: First Name
 */
Vue.component('form-first_name', {
    template: '#tmpl-wpuf-form-first_name',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Gender
 */
Vue.component('form-gender_field', {
    template: '#tmpl-wpuf-form-gender_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Date
 */
Vue.component('form-google_map', {
    template: '#tmpl-wpuf-form-google_map',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    data: function () {
        return {
            map: {},
            geocoder: {},
            markers: []
        };
    },

    /* global google */
    mounted: function () {
        if (typeof window.google === 'undefined') {
            return;
        }

        var self = this,
            default_pos = self.field.default_pos,
            default_zoom = self.field.zoom;

        var default_latLng = default_pos.split(',');

        if (2 === default_latLng.length && isFinite(default_latLng[0]) && isFinite(default_latLng[1])) {
            default_pos = {lat: parseFloat(default_latLng[0]), lng: parseFloat(default_latLng[1])};
        } else {
            default_pos = {lat: 40.7143528, lng: -74.0059731};
        }

        self.map = new google.maps.Map($(this.$el).find('.wpuf-form-google-map').get(0), {
            center: default_pos,
            zoom: parseInt(default_zoom) || 12,
            mapTypeId: 'roadmap',
            streetViewControl: false,
        });

        self.geocoder = new google.maps.Geocoder();

        // Create the search box and link it to the UI element.
        var input = $(this.$el).find('.wpuf-google-map-search').get(0);
        var searchBox = new google.maps.places.SearchBox(input);
        self.map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

        // Bias the SearchBox results towards current map's viewport.
        self.map.addListener('bounds_changed', function() {
            searchBox.setBounds(self.map.getBounds());
        });

        self.markers = [];

        self.set_marker(self.field.default_pos);
    },

    methods: {
        set_marker: function (address) {
            var self = this;

            self.geocoder.geocode({'address': address}, function(results, status) {
                if (status === 'OK') {
                    // Clear out the old markers.
                    _.each(self.markers, function (marker) {
                        marker.setMap(null);
                    });

                    self.markers = [];

                    // Create a marker for each place.
                    self.markers.push(new google.maps.Marker({
                        map: self.map,
                        position: results[0].geometry.location
                    }));

                    self.map.setCenter(results[0].geometry.location);
                }
            });
        }
    },

    watch: {
        field: {
            deep: true,
            handler: function (newVal) {
                this.set_marker(newVal.default_pos);
                this.map.setZoom(parseInt(newVal.zoom));
            }
        }
    }
});

/**
 * Field template: Instagram URL
 */
Vue.component('form-instagram_url', {
    template: '#tmpl-wpuf-form-instagram_url',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
/**
 * Field template: Last Name
 */
Vue.component('form-last_name', {
    template: '#tmpl-wpuf-form-last_name',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: LinkedIn URL
 */
Vue.component('form-linkedin_url', {
    template: '#tmpl-wpuf-form-linkedin_url',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
/**
 * Field template: Math Captcha
 */
Vue.component('form-math_captcha', {
    template: '#tmpl-wpuf-form-math_captcha',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        captcha: () => {
            let operators = [ '+', '-', 'x' ],
                random = Math.floor( Math.random() * operators.length );

            return {
                operandOne: Math.floor( Math.random() * 200 ) + 1,
                operandTwo: Math.floor( Math.random() * 200 ) + 1,
                operator: operators[random]
            };
        }
    },
});

/**
 * Field template: Nickname
 */
Vue.component('form-nickname', {
    template: '#tmpl-wpuf-form-nickname',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

Vue.component('form-numeric_text_field', {
    template: '#tmpl-wpuf-form-numeric_text_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Password
 */
Vue.component('form-password', {
    template: '#tmpl-wpuf-form-password',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

Vue.component('form-phone_field', {
    template: '#tmpl-wpuf-form-phone_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        countries: function () {
            var countries   = wpuf_form_builder.countries,
                visibility  = this.field.country_list.country_list_visibility_opt_name,
                hide_list   = this.field.country_list.country_select_hide_list,
                show_list   = this.field.country_list.country_select_show_list;

            if ('hide' === visibility && hide_list && hide_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(hide_list, country.code) < 0);
                });

            } else if ('show' === visibility && show_list && show_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(show_list, country.code) >= 0);
                });
            }

            return countries;
        },

        default_country: function () {
            return this.field.country_list.name;
        }
    }
});

Vue.component('form-price_field', {
    template: '#tmpl-wpuf-form-price_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
Vue.component('form-pricing_checkbox', {
    template: '#tmpl-wpuf-form-pricing_checkbox',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
Vue.component('form-pricing_dropdown', {
    template: '#tmpl-wpuf-form-pricing_dropdown',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
Vue.component('form-pricing_multiselect', {
    template: '#tmpl-wpuf-form-pricing_multiselect',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
Vue.component('form-pricing_radio', {
    template: '#tmpl-wpuf-form-pricing_radio',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
/**
 * Field template: Profile Phone
 */
Vue.component('form-profile_phone', {
    template: '#tmpl-wpuf-form-profile_phone',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        countries: function () {
            var countries   = wpuf_form_builder.countries,
                visibility  = this.field.country_list.country_list_visibility_opt_name,
                hide_list   = this.field.country_list.country_select_hide_list,
                show_list   = this.field.country_list.country_select_show_list;

            if ('hide' === visibility && hide_list && hide_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(hide_list, country.code) < 0);
                });

            } else if ('show' === visibility && show_list && show_list.length) {
                countries = countries.filter(function (country) {
                    return (_.indexOf(show_list, country.code) >= 0);
                });
            }

            return countries;
        },

        default_country: function () {
            return this.field.country_list.name;
        }
    }
});


/**
 * Field template: Profile Photo
 */
Vue.component('form-profile_photo', {
    template: '#tmpl-wpuf-form-profile_photo',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Ratings
 */
Vue.component('form-ratings', {
    template: '#tmpl-wpuf-form-ratings',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Really Simple Captcha
 */
Vue.component('form-really_simple_captcha', {
    template: '#tmpl-wpuf-form-really_simple_captcha',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        is_rs_captcha_active: function () {
            return wpuf_form_builder.is_rs_captcha_active;
        },

        no_plugin_msg: function () {
            return wpuf_form_builder.field_settings.really_simple_captcha.validator.msg;
        }
    }
});

/**
 * Field template: Repeat Field
 */
Vue.component('form-repeat_field', {
    template: '#tmpl-wpuf-form-repeat_field',

    mixins: [
        wpuf_mixins.form_field_mixin,
        wpuf_mixins.add_form_field
    ],

    data() {
        return {
            showFieldPicker: false,
        }
    },

    computed: {
        editing_form_id: function () {
            return this.$store.state.editing_field_id;
        },

        action_button_classes: function () {
            return 'wpuf-px-3 wpuf-py-2 wpuf-text-sm wpuf-font-medium wpuf-rounded-md hover:wpuf-bg-green-700 wpuf-transition wpuf-duration-150 wpuf-ease-out hover:wpuf-transition-all';
        },
    },

    mounted() {
        this.initializeSortable();
    },

    methods: {
        initializeSortable() {
            var self = this;
            var sortableFields = $(self.$el).find('.wpuf-repeat-fields-sortable-list');

            // bind jquery ui sortable
            $(sortableFields).sortable({
                placeholder: 'form-preview-stage-dropzone',
                items: '.repeat-field-items',
                handle: '.wpuf-repeat-field-control-buttons .move',
                scroll: true,
                stop: function( event, ui ) {
                    var item        = ui.item[0];
                    var data        = item.dataset;
                    var data_source = data.source;

                    if ('panel' === data_source) {
                        var payload = {
                            toIndex: parseInt($(ui.item).index()),
                            field_template: data.formField,
                            to_repeat_field: self.field.id
                        };

                        self.add_repeat_inner_field(payload);

                        // remove button from stage
                        $(this).find('.wpuf-field-button').remove();
                    }
                },
                update: function (e, ui) {
                    var item    = ui.item[0],
                        data    = item.dataset,
                        source  = data.source,
                        toIndex = parseInt($(ui.item).index()),
                        payload = {
                            toIndex: toIndex
                        };

                    if ( 'repeat-field-stage' === source) {
                        payload.field_id   = self.field.id;
                        payload.fromIndex  = parseInt(item.attributes['repeat-field-index'].value);
                        payload.toIndex    = toIndex;

                        self.$store.commit('swap_repeat_field_elements', payload);
                    }
                }
            });
        },

        is_full_width: function (template) {
            if (this.$store.state.field_settings[template] && this.$store.state.field_settings[template].is_full_width) {
                return true;
            }
            return false;
        },

        is_failed_to_validate: function (template) {
            // TODO: Implement validation check
            return false;
        },

        get_field_name: function (template) {
            return this.$store.state.field_settings[template] ? this.$store.state.field_settings[template].title : template;
        },

        is_pro_preview: function (template) {
            return !!( this.$store.state.field_settings[template] && this.$store.state.field_settings[template].is_pro_preview );
        },

        pro_link: function () {
            return wpuf_admin_script.pro_link || '#';
        },

        open_inner_field_settings(innerField, idx) {
            var self = this,
                payload = {
                    field_id: self.field.id,
                    repeat_field: innerField,
                    index: idx
                };
            self.$store.commit('open_repeat_field_settings', payload);
        },

        clone_inner_field(innerField, idx) {
            var self = this,
                payload = {
                    field_id: self.field.id,
                    repeat_field_id: innerField.id,
                    index: idx,
                    new_id: self.get_random_id()
                };

            // check if the field is allowed
            if ( this.isSingleInstance( field_template ) && this.containsField( field_template ) ) {
                Swal.fire({
                    title: '<span class="wpuf-text-primary">Oops...</span>',
                    html: '<p class="wpuf-text-gray-500 wpuf-text-xl wpuf-m-0 wpuf-p-0">You already have this field in the form</p>',
                    imageUrl: wpuf_form_builder.asset_url + '/images/oops.svg',
                    showCloseButton: true,
                    padding: '1rem',
                    width: '35rem',
                    customClass: {
                        confirmButton: "!wpuf-flex focus:!wpuf-shadow-none !wpuf-bg-primary",
                        closeButton: "wpuf-absolute"
                    },
                });
                return;
            }

            self.$store.commit('clone_repeat_inner_field_element', payload);
        },
        delete_inner_field(idx) {
            var self = this,
                payload = {
                    field_id: self.field.id,
                    index: idx
                };

            const icon_delete = wpuf_admin_script.asset_url + '/images/delete-icon-rounded.svg';
            const delete_icon_html = '<img src="' + icon_delete + '" alt="delete">';

            (Swal.fire({
                title: self.i18n.delete_field_warn_title,
                html: '<span class="wpuf-text-gray-500 wpuf-font-medium">' + self.i18n.delete_field_warn_msg + '</span>',
                iconHtml: delete_icon_html,
                showCancelButton: true,
                confirmButtonText: self.i18n.yes_delete_it,
                cancelButtonText: self.i18n.no_cancel_it,
                cancelButtonColor: '#fff',
                confirmButtonColor: '#EF4444',
                reverseButtons: true
            })).then((result) => {
                if (result.isConfirmed) {
                    self.$store.commit('delete_repeat_inner_field_element', payload);
                }
            });
        },

        isAllowedInRepeatField(field_template) {
            var allowedFields = [
                'text_field',
                'textarea_field',
                'dropdown_field',
                'multiple_select',
                'radio_field',
                'checkbox_field',
                'website_url',
                'date_field',
                'phone_field',
                'numeric_text_field',
                'email_address',
                // 'country_list_field',
                // 'image_upload',
                // 'file_upload'
            ];

            return $.inArray(field_template, allowedFields) >= 0;
        },

        openFieldPicker(e) {
            if (e) e.stopPropagation();
            this.showFieldPicker = true;
        },
        closeFieldPicker(e) {
            if (e) e.stopPropagation();
            this.showFieldPicker = false;
        },
        addInnerFieldFromPicker(fieldType) {
            // Create a new field object with default settings
            var fieldSettings = this.$store.state.field_settings[fieldType];
            if (!fieldSettings) return;
            var field = $.extend(true, {}, fieldSettings.field_props);
            field.id = this.get_random_id();
            // Set a unique name if needed
            if ('yes' === field.is_meta && !field.name && field.label) {
                field.name = field.label.replace(/\W/g, '_').toLowerCase();
                field.name += '_' + this.get_random_id();
            }
            if (!this.field.inner_fields) {
                this.$set(this.field, 'inner_fields', []);
            }
            this.field.inner_fields.push(field);
            this.showFieldPicker = false;
        },
        add_repeat_inner_field(data) {
            var payload = {
                toWhichRepeatField: this.field.id,
                toWhichRepeatFieldMeta: this.field.name,
                toIndex: data.toIndex
            };

            if (!this.isAllowedInRepeatField(data.field_template)) {
                Swal.fire({
                    title: '<span class="wpuf-text-primary">Oops...</span>',
                    html: '<p class="wpuf-text-gray-500 wpuf-text-xl wpuf-m-0 wpuf-p-0">This field type is not supported in repeat field\n</p>',
                    imageUrl: wpuf_form_builder.asset_url + '/images/oops.svg',
                    showCloseButton: true,
                    padding: '1rem',
                    width: '35rem',
                    customClass: {
                        confirmButton: "!wpuf-flex focus:!wpuf-shadow-none !wpuf-bg-primary",
                        closeButton: "wpuf-absolute"
                    },
                });
                return;
            }


            // check if these are already inserted
            if ( this.isSingleInstance( data.field_template ) && this.containsField( data.field_template ) ) {
                Swal.fire({
                    title: "Oops...",
                    text: "You already have this field in the form"
                });
                return;
            }

            // check if these are already inserted
            if ( this.isSingleInstance( data.field_template ) && this.containsField( data.field_template ) ) {
                Swal.fire({
                    title: '<span class="wpuf-text-primary">Oops...</span>',
                    html: '<p class="wpuf-text-gray-500 wpuf-text-xl wpuf-m-0 wpuf-p-0">You already have this field in the form</p>',
                    imageUrl: wpuf_form_builder.asset_url + '/images/oops.svg',
                    showCloseButton: true,
                    padding: '1rem',
                    width: '35rem',
                    customClass: {
                        confirmButton: "!wpuf-flex focus:!wpuf-shadow-none !wpuf-bg-primary",
                        closeButton: "wpuf-absolute"
                    },
                });
                return;
            }

            var field = $.extend(true, {}, this.$store.state.field_settings[data.field_template].field_props),
            form_fields = this.$store.state.form_fields;

            field.id = this.get_random_id();

            if ('yes' === field.is_meta && !field.name && field.label) {
                field.name = field.label.replace(/\W/g, '_').toLowerCase();

                var same_template_fields = form_fields.filter(function (form_field) {
                    return (form_field.template === field.template);
                });

                if (same_template_fields) {
                    field.name += '_' + this.get_random_id();
                }
            }

            payload.field = field;

            // add new form element
            this.$store.commit('add_repeat_inner_field_element', payload);

            // Trigger field initialization after adding new field
            this.$nextTick(function() {
                this.initializeRepeatFieldComponents();
            }.bind(this));
        },

        /**
         * Initialize field components that require JavaScript plugins
         * This is called after new fields are added to repeat fields
         */
        initializeRepeatFieldComponents: function() {
            var self = this;

            // Wait for DOM to be updated
            setTimeout(function() {
                // Check if WPUF_Field_Initializer is available
                if (typeof window.WPUF_Field_Initializer !== 'undefined' && typeof window.WPUF_Field_Initializer.reinitialize === 'function') {
                    window.WPUF_Field_Initializer.reinitialize();
                }

                // Also trigger a custom event for any other initialization needs
                $(document).trigger('wpuf-repeat-field-updated', [self.$el]);
            }, 100);
        },
    }
});

/**
 * Field template: shortcode
 */
Vue.component('form-shortcode', {
    template: '#tmpl-wpuf-form-shortcode',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    data: function () {
        return {
            raw_html: 'from data'
        };
    }
});

/**
 * Field template: Step Start
 */
Vue.component('form-step_start', {
    template: '#tmpl-wpuf-form-step_start',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Time
 */
Vue.component('form-time_field', {
    template: '#tmpl-wpuf-form-time_field',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Terms & Conditions
 */
Vue.component('form-toc', {
    template: '#tmpl-wpuf-form-toc',

    mixins: [
        wpuf_mixins.form_field_mixin
    ],

    computed: {
        content: function () {
            return this.field.description.replace(/\n/g, '<br>');
        }
    }
});

/**
 * Field template: Twitter URL
 */
Vue.component('form-twitter_url', {
    template: '#tmpl-wpuf-form-twitter_url',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});
/**
 * Field template: Biographical Info
 */
Vue.component('form-user_bio', {
    template: '#tmpl-wpuf-form-user_bio',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: User Email
 */
Vue.component('form-user_email', {
    template: '#tmpl-wpuf-form-user_email',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Username
 */
Vue.component('form-user_login', {
    template: '#tmpl-wpuf-form-user_login',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

/**
 * Field template: Website
 */
Vue.component('form-user_url', {
    template: '#tmpl-wpuf-form-user_url',

    mixins: [
        wpuf_mixins.form_field_mixin
    ]
});

Vue.component('integration-conditional-logic', {
    template: '#tmpl-wpuf-integration-conditional-logic',

    filters: {
        capitalize: function (value) {
            if (!value) {
                return '';
            }

            return value.charAt(0).toUpperCase() + value.slice(1);
        }
    },

    props: {
        'integration-name': {
            type: String,
            required: true
        },
        'settings-path': {
            type: String,
            required: true
        },
        'current-settings': {
            type: Object,
            default: () => ({
                condition_status: 'no',
                cond_logic: 'all',
                conditions: [{
                    name: '',
                    operator: '=',
                    option: ''
                }]
            })
        },
        'label': {
            type: String,
            default: 'Conditional Logic'
        }
    },

    data: function () {
        return {
            // Internal reactive state for conditional logic settings
            condition_status: 'no',
            cond_logic: 'all',
            conditions: [],
            // Flag to track if component has been initialized
            isInitialized: false,
            rule_options: [
                {
                    label: 'All',
                    value: 'all',
                },
                {
                    label: 'Any',
                    value: 'any',
                }
            ],
            all_conditional_operators: {
                radio: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ],
                dropdown: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ],
                checkbox: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ]
            }
        };
    },

    computed: {
        // Get form fields that support conditional logic
        conditional_fields: function () {
            var compatibleFields = [],
                allowedTypes = ['radio_field', 'checkbox_field', 'dropdown_field'];

            if (!this.$store || !this.$store.state || !this.$store.state.form_fields) {
                return [];
            }

            this.$store.state.form_fields.forEach(function(field) {
                if (allowedTypes.includes(field.template) &&
                    field.name &&
                    field.label) {
                    compatibleFields.push({
                        name: field.name,
                        label: field.label,
                        template: field.template,
                        options: field.options || {}
                    });
                }
            });

            return compatibleFields;
        }
    },

    watch: {
        // Watch for changes in current settings prop
        currentSettings: {
            handler: function(newSettings) {
                // Only initialize if component hasn't been initialized yet
                if (!this.isInitialized) {
                    this.initializeFromSettings(newSettings);
                }
            },
            deep: true,
            immediate: true
        },

        // Watch for changes in internal state and update settings
        condition_status: function() {
            this.update_settings();
        },

        cond_logic: function() {
            this.update_settings();
        },

        // Watch for changes in conditions array
        conditions: {
            handler: function() {
                this.update_settings();
            },
            deep: true
        }
    },

    methods: {
        // Initialize component data from current settings
        initializeFromSettings: function(settings) {
            if (!settings) {
                settings = {
                    condition_status: 'no',
                    cond_logic: 'all',
                    conditions: []
                };
            }

            // Set reactive data properties
            this.condition_status = settings.condition_status || 'no';
            this.cond_logic = settings.cond_logic || 'all';

            if (!settings.conditions || !Array.isArray(settings.conditions) || settings.conditions.length === 0) {
                this.conditions = [{
                    id: this.generateUniqueId(),
                    name: '',
                    operator: '=',
                    option: ''
                }];
            } else {
                var self = this;
                this.conditions = settings.conditions.map(function(condition) {
                    return {
                        id: condition.id || self.generateUniqueId(),
                        name: condition.name || '',
                        operator: condition.operator || '=',
                        option: condition.option || ''
                    };
                });

                // Validate all existing conditions
                this.$nextTick(function() {
                    self.validateAllConditions();
                });
            }

            // Mark component as initialized
            this.isInitialized = true;
        },

        // Validate all conditions to ensure they have valid operators and options
        validateAllConditions: function() {
            var self = this;
            var needsUpdate = false;

            this.conditions.forEach(function(condition, index) {
                if (condition.name) {
                    // Validate operator for the field type
                    var availableOperators = self.get_cond_operators(condition.name);
                    var operatorValid = availableOperators.some(function(op) {
                        return op.value === condition.operator;
                    });

                    if (!operatorValid && availableOperators.length > 0) {
                        condition.operator = availableOperators[0].value;
                        needsUpdate = true;
                    }

                    // Clear option if operator doesn't need a value
                    if (condition.operator === '!=empty' || condition.operator === '==empty') {
                        if (condition.option !== '') {
                            condition.option = '';
                            needsUpdate = true;
                        }
                    }
                }
            });

            // Force update if any validation changes were made
            if (needsUpdate) {
                this.$forceUpdate();
            }
        },

        // Get conditional operators based on field type
        get_cond_operators: function(fieldName) {
            if (!fieldName) {
                return this.all_conditional_operators.radio; // Default to radio operators
            }

            var field = this.conditional_fields.find(function(f) {
                return f.name === fieldName;
            });

            if (!field || !field.template) {
                return this.all_conditional_operators.radio; // Default to radio operators
            }

            // Extract field type from template (remove '_field' suffix)
            var fieldType = field.template.replace('_field', '');

            // Return operators for the field type, default to radio if not found
            return this.all_conditional_operators[fieldType] || this.all_conditional_operators.radio;
        },

        // Get field options for dropdown conditions
        get_cond_options: function(fieldName) {
            if (!fieldName) {
                return [];
            }

            var field = this.conditional_fields.find(function(f) {
                return f.name === fieldName;
            });

            if (!field || !field.options || typeof field.options !== 'object') {
                return [];
            }

            var options = [];

            // Handle both object and array format options
            if (Array.isArray(field.options)) {
                // Array format: [{label: 'Label', value: 'value'}, ...]
                field.options.forEach(function(option) {
                    if (option && typeof option === 'object' && option.label && option.value !== undefined) {
                        options.push({
                            value: option.value,
                            label: option.label
                        });
                    }
                });
            } else {
                // Object format: {value: 'label', ...} or {key: {label: 'Label', value: 'value'}}
                for (var key in field.options) {
                    if (field.options.hasOwnProperty(key)) {
                        var option = field.options[key];

                        if (typeof option === 'string') {
                            // Simple key-value format: {value: 'label'}
                            options.push({
                                value: key,
                                label: option
                            });
                        } else if (typeof option === 'object' && option.label && option.value !== undefined) {
                            // Complex object format: {key: {label: 'Label', value: 'value'}}
                            options.push({
                                value: option.value,
                                label: option.label
                            });
                        }
                    }
                }
            }

            return options;
        },

        // Check if we should show text input or dropdown for condition value
        show_textfield: function(fieldName) {
            // We only support checkbox, radio, and dropdown fields
            // All of these should show dropdown for their options
            return false;
        },

        show_dropdown: function(fieldName) {
            // We only support checkbox, radio, and dropdown fields
            // All of these should show dropdown for their options
            return true;
        },

        // Check if condition value input should be disabled
        is_disabled: function(operator) {
            return operator === '!=empty' || operator === '==empty';
        },

        // Generate unique ID for conditions
        generateUniqueId: function() {
            return 'condition_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        },

        // Add new condition
        add_condition: function() {
            this.conditions.push({
                id: this.generateUniqueId(),
                name: '',
                operator: '=',
                option: ''
            });
        },

        // Remove condition
        delete_condition: function(index) {
            if (this.conditions.length > 1) {
                this.conditions.splice(index, 1);
            }
        },

        // Handle field selection change
        on_change_cond_field: function(index) {
            var condition = this.conditions[index];
            var fieldName = condition.name;

            // Get available operators for the new field
            var availableOperators = this.get_cond_operators(fieldName);
            var currentOperator = condition.operator;

            // Check if current operator is valid for the new field
            var operatorValid = availableOperators.some(function(op) {
                return op.value === currentOperator;
            });

            // Reset operator to first available if current is invalid
            if (!operatorValid && availableOperators.length > 0) {
                condition.operator = availableOperators[0].value;
            }

            // Reset option value
            condition.option = '';

            // Force reactivity update for options dropdown
            this.$forceUpdate();

            // Validate the operator after field change
            this.on_change_cond_operator(index, true);
        },

        // Handle operator selection change
        on_change_cond_operator: function(index, skipUpdateSettings) {
            var condition = this.conditions[index];
            var operator = condition.operator;

            // Clear option value for operators that don't need a value
            if (operator === '!=empty' || operator === '==empty') {
                condition.option = '';
            }

            // Force update to ensure UI reflects the disabled state
            this.$forceUpdate();
        },

        // Handle option value change
        on_change_cond_option: function(index) {
            // Force update to ensure changes are reflected
            this.$forceUpdate();
        },

        // Update settings and emit changes
        update_settings: function() {
            var settings = {
                condition_status: this.condition_status,
                cond_logic: this.cond_logic,
                conditions: this.conditions.map(function(condition) {
                    return {
                        name: condition.name,
                        operator: condition.operator,
                        option: condition.option
                    };
                })
            };

            // Update the Vuex store directly using the settings path
            if (this.$store && this.$store.state && this.$store.state.settings) {
                // Create nested path in settings based on settingsPath
                var pathParts = this.settingsPath.split('.');
                var current = this.$store.state.settings;

                // Create nested objects if they don't exist
                for (var i = 0; i < pathParts.length - 1; i++) {
                    if (!current[pathParts[i]]) {
                        this.$set(current, pathParts[i], {});
                    }
                    current = current[pathParts[i]];
                }

                // Set the final value
                this.$set(current, pathParts[pathParts.length - 1], settings);
            }
        },

        // Reset component to allow re-initialization (useful when switching integrations)
        reset: function() {
            this.isInitialized = false;
            this.initializeFromSettings(this.currentSettings);
        }
    },

    created: function() {
        // The watcher with immediate: true will handle initialization
    }
});

Vue.component('submit-button-conditional-logics', {
    template: '#tmpl-wpuf-submit-button-conditional-logic',

    props: {
        'current-settings': {
            type: Object,
            default: () => ({
                condition_status: 'no',
                cond_logic: 'any',
                conditions: [{
                    name: '',
                    operator: '=',
                    option: ''
                }]
            })
        },
        'label': {
            type: String,
            default: 'Conditional Logic on Submit Button'
        }
    },

    data: function() {
        return {
            // Internal reactive state for conditional logic settings
            condition_status: 'no',
            cond_logic: 'any',
            conditions: [],
            // Flag to track if component has been initialized
            isInitialized: false,
            rule_options: [
                {
                    label: 'All',
                    value: 'all',
                },
                {
                    label: 'Any',
                    value: 'any',
                }
            ],
            all_conditional_operators: {
                radio: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ],
                text: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'contains',
                        value: '==contains',
                    },
                    {
                        label: 'has any value',
                        value: '!=empty',
                    },
                    {
                        label: 'has no value',
                        value: '==empty',
                    }
                ],
                number: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'contains',
                        value: '==contains',
                    },
                    {
                        label: 'has any value',
                        value: '!=empty',
                    },
                    {
                        label: 'has no value',
                        value: '==empty',
                    },
                    {
                        label: 'value is greater then',
                        value: 'greater',
                    },
                    {
                        label: 'value is less then',
                        value: 'less',
                    }
                ],
                dropdown: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ],
                checkbox: [
                    {
                        label: 'is',
                        value: '=',
                    },
                    {
                        label: 'is not',
                        value: '!=',
                    },
                    {
                        label: 'any selection',
                        value: '!=empty',
                    },
                    {
                        label: 'no selection',
                        value: '==empty',
                    }
                ],
                others: [
                    {
                        label: 'has any value',
                        value: '!=empty',
                    },
                    {
                        label: 'has no value',
                        value: '==empty',
                    }
                ]
            }
        };
    },

    computed: {
        // Get form fields that support conditional logic
        conditional_fields: function () {
            var compatibleFields = [],
                allowedTypes = ['radio_field', 'checkbox_field', 'dropdown_field', 'text_field', 'textarea_field', 'email_address', 'numeric_text_field'];

            if (!this.$store || !this.$store.state || !this.$store.state.form_fields) {
                return [];
            }

            this.$store.state.form_fields.forEach(function(field) {
                if (allowedTypes.includes(field.template) &&
                    field.name &&
                    field.label) {
                    compatibleFields.push({
                        name: field.name,
                        label: field.label,
                        template: field.template,
                        options: field.options || {},
                        input_type: field.input_type || field.template
                    });
                }
            });

            return compatibleFields;
        }
    },

    watch: {
        // Watch for changes in current settings prop
        currentSettings: {
            handler: function(newSettings) {
                // Only initialize if component hasn't been initialized yet
                if (!this.isInitialized) {
                    this.initializeFromSettings(newSettings);
                }
            },
            deep: true,
            immediate: true
        },

        // Watch for changes in internal state and update settings
        condition_status: function() {
            this.update_settings();
        },

        cond_logic: function() {
            this.update_settings();
        },

        // Watch for changes in conditions array
        conditions: {
            handler: function(newConditions, oldConditions) {
                if (!oldConditions) return;
                
                for (var i = 0; i < newConditions.length; i++) {
                    var newCondition = newConditions[i];
                    var oldCondition = oldConditions[i];
                    
                    if (!oldCondition) continue;
                    
                    // Check if field name changed
                    if (newCondition.name !== oldCondition.name) {
                        this.on_change_cond_field(i);
                    }
                    
                    // Check if operator changed
                    if (newCondition.operator !== oldCondition.operator) {
                        this.on_change_cond_operator(i);
                    }
                    
                    // Check if option changed
                    if (newCondition.option !== oldCondition.option) {
                        this.on_change_cond_option();
                    }
                }
                
                // Update settings when conditions change
                this.update_settings();
            },
            deep: true
        }
    },

    methods: {
        // Initialize component data from current settings
        initializeFromSettings: function(settings) {
            if (!settings) {
                settings = {
                    condition_status: 'no',
                    cond_logic: 'any',
                    conditions: []
                };
            }

            // Set reactive data properties
            this.condition_status = settings.condition_status || 'no';
            this.cond_logic = settings.cond_logic || 'any';

            if (!settings.conditions || !Array.isArray(settings.conditions) || settings.conditions.length === 0) {
                this.conditions = [{
                    id: this.generateUniqueId(),
                    name: '',
                    operator: '=',
                    option: '',
                    input_type: ''
                }];
            } else {
                var self = this;
                this.conditions = settings.conditions.map(function(condition) {
                    return {
                        id: condition.id || self.generateUniqueId(),
                        name: condition.name || '',
                        operator: condition.operator || '=',
                        option: condition.option || '',
                        input_type: condition.input_type || ''
                    };
                });

                // Set input_type for existing conditions and trigger change handlers
                this.$nextTick(function() {
                    for (var i = 0; i < self.conditions.length; i++) {
                        var condition = self.conditions[i];
                        
                        // Set input_type for existing conditions that have a field selected
                        if (condition.name) {
                            var field = self.conditional_fields.find(f => f.name === condition.name);
                            
                            if (field) {
                                // Map field template to input_type for frontend conditional logic
                                var inputType = '';
                                switch (field.template) {
                                    case 'radio_field':
                                        inputType = 'radio';
                                        break;
                                    case 'checkbox_field':
                                        inputType = 'checkbox';
                                        break;
                                    case 'dropdown_field':
                                        inputType = 'select';
                                        break;
                                    case 'text_field':
                                        inputType = 'text';
                                        break;
                                    case 'textarea_field':
                                        inputType = 'textarea';
                                        break;
                                    case 'email_address':
                                        inputType = 'email';
                                        break;
                                    case 'numeric_text_field':
                                        inputType = 'numeric_text';
                                        break;
                                    default:
                                        inputType = field.template.replace('_field', '');
                                        break;
                                }
                                condition.input_type = inputType;
                            }
                        }
                        // Manually trigger operator change handler for existing conditions
                        // Skip update_settings to avoid multiple calls
                        self.on_change_cond_operator(i, true);
                    }
                    // Call update_settings once after all conditions are processed
                    self.update_settings();
                });
            }

            // Mark component as initialized
            this.isInitialized = true;
        },

        // Get conditional operators based on field type
        get_cond_operators: function(fieldName) {
            var field = this.conditional_fields.find(f => f.name === fieldName);
            if (!field) {
                return this.all_conditional_operators.text;
            }

            var fieldType = field.template.replace('_field', '');

            // Map field types to operator sets
            switch (fieldType) {
                case 'radio':
                case 'dropdown':
                case 'checkbox':
                    return this.all_conditional_operators[fieldType] || this.all_conditional_operators.radio;
                case 'text':
                case 'textarea':
                case 'email_address':
                    return this.all_conditional_operators.text;
                case 'numeric_text':
                    return this.all_conditional_operators.number;
                default:
                    return this.all_conditional_operators.others;
            }
        },

        // Get field options for dropdown conditions
        get_cond_options: function(fieldName) {
            var field = this.conditional_fields.find(f => f.name === fieldName);
            if (!field || !field.options) {
                return [];
            }

            var options = [];
            for (var key in field.options) {
                if (field.options.hasOwnProperty(key)) {
                    options.push({
                        value: key,
                        label: field.options[key]
                    });
                }
            }
            return options;
        },

        // Check if we should show text input or dropdown for condition value
        show_textfield: function(fieldName) {
            var field = this.conditional_fields.find(f => f.name === fieldName);
            if (!field) {
                return true;
            }

            var fieldType = field.template;
            return fieldType === 'text_field' || fieldType === 'textarea_field' || fieldType === 'email_address' || fieldType === 'numeric_text_field';
        },

        show_dropdown: function(fieldName) {
            return !this.show_textfield(fieldName);
        },

        // Check if condition value input should be disabled
        is_disabled: function(operator) {
            return operator === '!=empty' || operator === '==empty';
        },

        // Generate unique ID for conditions
        generateUniqueId: function() {
            return 'condition_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        },

        // Add new condition
        add_condition: function() {
            this.conditions.push({
                id: this.generateUniqueId(),
                name: '',
                operator: '=',
                option: '',
                input_type: ''
            });
        },

        // Remove condition
        delete_condition: function(index) {
            if (this.conditions.length > 1) {
                this.conditions.splice(index, 1);
            }
        },

        // Handle field selection change
        on_change_cond_field: function(index) {
            // Reset operator and option when field changes
            var fieldName = this.conditions[index].name;
            var field = this.conditional_fields.find(f => f.name === fieldName);
            var operators = this.get_cond_operators(fieldName);

            this.conditions[index].operator = operators.length > 0 ? operators[0].value : '=';
            this.conditions[index].option = '';
            
            // Map field template to input_type for frontend conditional logic
            var inputType = '';
            if (field && field.template) {
                switch (field.template) {
                    case 'radio_field':
                        inputType = 'radio';
                        break;
                    case 'checkbox_field':
                        inputType = 'checkbox';
                        break;
                    case 'dropdown_field':
                        inputType = 'select';
                        break;
                    case 'text_field':
                        inputType = 'text';
                        break;
                    case 'textarea_field':
                        inputType = 'textarea';
                        break;
                    case 'email_address':
                        inputType = 'email';
                        break;
                    case 'numeric_text_field':
                        inputType = 'numeric_text';
                        break;
                    default:
                        inputType = field.template.replace('_field', '');
                        break;
                }
            }
            this.conditions[index].input_type = inputType;
            this.update_settings();
        },

        // Handle operator selection change
        on_change_cond_operator: function(index, skipUpdateSettings) {
            // Clear option value for operators that don't need a value
            var operator = this.conditions[index].operator;
            if (operator === '!=empty' || operator === '==empty') {
                this.conditions[index].option = '';
            }
            if (!skipUpdateSettings) {
                this.update_settings();
            }
        },

        // Handle option value change
        on_change_cond_option: function() {
            this.update_settings();
        },

        // Update settings and emit changes to store
        update_settings: function() {
            var settings = {
                condition_status: this.condition_status,
                cond_logic: this.cond_logic,
                conditions: this.conditions.map(function(condition) {
                    return {
                        name: condition.name,
                        operator: condition.operator,
                        option: condition.option,
                        input_type: condition.input_type
                    };
                })
            };

            // Update the store using Vue's reactivity system
            if (this.$store && this.$store.state && this.$store.state.settings) {
                this.$set(this.$store.state.settings, 'submit_button_cond', settings);
            }
        }
    },

    created: function() {
        // Initialize component data from current settings
        this.initializeFromSettings(this.currentSettings);
    }
});

})(jQuery);
