/**
 * Advanced Form Integration - Trigger Components
 * Contains all form/trigger related Vue components
 */

// Webhook triggers
Vue.component('webhook-row', {
    props: ["trigger", "action", "fielddata"],
    template: '#webhook-row-template',
    data: function () {
        return {
            loading: false,
            webhookData: null
        }
    },
    methods: {
        copy: function (e) {
            var copyText = document.getElementById("inbound-webhook-url");
            copyText.select();
            copyText.setSelectionRange(0, 99999);
            document.execCommand("copy");
            e.target.innerText = "Copied!";
        },
        receiveData: function () {
            this.loading = true;
            this.webhookData = null;
            this.pollForWebhookData();
        },
        pollForWebhookData: function () {
            var vm = this;
            jQuery.post(ajaxurl, {
                action: 'adfoin_check_inbound_webhook_data'
            }).done(function (response) {
                if (response.success && response.data) {
                    if (response.data) {
                        var webhook_url = adfoinNewIntegration.trigger.formFields.webhook_url;
                        adfoinNewIntegration.trigger.formFields = response.data;
                        adfoinNewIntegration.trigger.formFields.webhook_url = webhook_url;
                    }
                    vm.loading = false;
                } else {
                    setTimeout(vm.pollForWebhookData, 2000);
                }
            }).fail(function () {
                vm.loading = false;
                console.error("Error fetching webhook data.");
            });
        }
    }
});

Vue.component('webhook2-row', {
    props: ["trigger", "action", "fielddata"],
    template: '#webhook2-row-template',
    data: function () {
        return {
            polling: false,
            rotating: false,
            copied: false,
            showModal: false,
            modalLoading: false,
            errorMessage: '',
            lastEventId: 0,
            pollAttempts: 0,
            lastPayload: null,
            latestPayload: {},
            copiedKey: '',
            filter: '',
            secret: '',
            hasSecret: false,
            savingSecret: false,
            secretMessage: '',
            testing: false,
            testMessage: ''
        };
    },
    computed: {
        integrationId: function () {
            return typeof window.adfoinIntegrationId !== 'undefined' ? parseInt(window.adfoinIntegrationId, 10) : 0;
        },
        // Flat "a__b__c" keys -> indented rows describing a tree. Branch rows
        // are group headers; leaf rows carry the full flat key (the merge tag)
        // and a sample value, each with its own copy button.
        payloadRows: function () {
            var fields = (this.latestPayload && this.latestPayload.fields) ? this.latestPayload.fields : {};
            var rows = this.buildRows(fields);
            var f = (this.filter || '').toLowerCase();
            if (!f) return rows;
            // When filtering, keep leaf rows whose full key or value matches.
            return rows.filter(function (r) {
                if (!r.isLeaf) return false;
                var hay = (r.fullKey + ' ' + (r.value == null ? '' : r.value)).toLowerCase();
                return hay.indexOf(f) !== -1;
            });
        }
    },
    mounted: function () {
        if (!this.trigger.formFields || typeof this.trigger.formFields !== 'object') {
            this.$set(this.trigger, 'formFields', {});
        }
        if (typeof this.trigger.formFields.webhook_url === 'undefined') {
            this.$set(this.trigger.formFields, 'webhook_url', '');
        }
        if (typeof this.trigger.formFields.webhook_id === 'undefined') {
            this.$set(this.trigger.formFields, 'webhook_id', '');
        }
        if (typeof this.trigger.formFields.platform === 'undefined') {
            this.$set(this.trigger.formFields, 'platform', '');
        }
    },
    methods: {
        currentWebhookId: function () {
            return (this.trigger.formFields && this.trigger.formFields.webhook_id) ? this.trigger.formFields.webhook_id : '';
        },
        copyUrl: function () {
            if (!this.trigger.formFields || !this.trigger.formFields.webhook_url) return;
            var url = this.trigger.formFields.webhook_url;
            var vm = this;
            if (navigator.clipboard && navigator.clipboard.writeText) {
                navigator.clipboard.writeText(url).then(function () {
                    vm.copied = true;
                    setTimeout(function () { vm.copied = false; }, 1500);
                });
            } else {
                var input = document.createElement('input');
                input.setAttribute('type', 'text');
                input.setAttribute('value', url);
                document.body.appendChild(input);
                input.select();
                document.execCommand('copy');
                document.body.removeChild(input);
                vm.copied = true;
                setTimeout(function () { vm.copied = false; }, 1500);
            }
        },
        rotateUrl: function () {
            var vm = this;
            if (this.rotating) return;
            this.rotating = true;
            this.errorMessage = "";
            jQuery.post(ajaxurl, {
                action: 'adfoin_rotate_webhooksinbound2_url',
                integrationId: this.integrationId,
                webhookId: this.currentWebhookId(),
                _nonce: adfoin.nonce
            }).done(function (response) {
                if (response.success && response.data) {
                    vm.$set(vm.trigger.formFields, 'webhook_url', response.data.webhook_url);
                    vm.$set(vm.trigger.formFields, 'webhook_id', response.data.webhook_id);
                    vm.lastEventId = 0;
                    vm.lastPayload = null;
                } else if (response.data && response.data.message) {
                    vm.errorMessage = response.data.message;
                }
            }).always(function () { vm.rotating = false; });
        },
        receiveData: function () {
            if (!this.currentWebhookId()) {
                this.errorMessage = "Webhook URL unavailable.";
                return;
            }
            this.polling = true;
            this.pollAttempts = 0;
            this.errorMessage = "";
            this.modalLoading = true;
            this.latestPayload = {};
            this.showModal = true;
            this.pollForData();
        },
        pollForData: function () {
            if (!this.polling) return;
            var vm = this;
            jQuery.post(ajaxurl, {
                action: 'adfoin_check_inbound_webhook2_data',
                _nonce: adfoin.nonce,
                webhookId: this.currentWebhookId(),
                integrationId: this.integrationId,
                afterEventId: this.lastEventId
            }).done(function (response) {
                if (response.success && response.data) {
                    vm.handlePayload(response.data);
                } else {
                    vm.pollAttempts++;
                    if (vm.pollAttempts >= 30) {
                        vm.polling = false;
                        vm.modalLoading = false;
                        vm.errorMessage = "No data received yet.";
                    } else {
                        setTimeout(function () { vm.pollForData(); }, 2000);
                    }
                }
            }).fail(function () {
                vm.pollAttempts++;
                if (vm.pollAttempts >= 30) {
                    vm.polling = false;
                    vm.modalLoading = false;
                    vm.errorMessage = "Unable to poll for webhook data.";
                } else {
                    setTimeout(function () { vm.pollForData(); }, 2000);
                }
            });
        },
        handlePayload: function (payload) {
            this.polling = false;
            this.modalLoading = false;
            this.errorMessage = '';
            this.lastEventId = payload.id;
            this.lastPayload = payload;
            this.latestPayload = payload;
            this.pollAttempts = 0;
        },
        closeModal: function () {
            this.showModal = false;
            this.polling = false;
            this.modalLoading = false;
        },
        showLatest: function () {
            if (!this.lastPayload) {
                this.loadLatestPayload();
                return;
            }
            this.latestPayload = this.lastPayload;
            this.modalLoading = false;
            this.showModal = true;
        },
        loadLatestPayload: function () {
            var vm = this;
            if (!this.currentWebhookId()) return;
            this.modalLoading = true;
            this.showModal = true;
            this.errorMessage = '';
            jQuery.post(ajaxurl, {
                action: 'adfoin_get_webhooksinbound2_payload',
                _nonce: adfoin.nonce,
                webhookId: this.currentWebhookId(),
                integrationId: this.integrationId
            }).done(function (response) {
                if (response.success && response.data) {
                    vm.handlePayload(response.data);
                } else if (response.data && response.data.message) {
                    vm.errorMessage = response.data.message;
                }
            }).fail(function () {
                vm.errorMessage = "Unable to load payload.";
            }).always(function () { vm.modalLoading = false; });
        },
        copyKey: function (mergeTag, fullKey) {
            if (navigator.clipboard && navigator.clipboard.writeText) {
                navigator.clipboard.writeText(mergeTag);
            } else {
                var input = document.createElement('input');
                input.setAttribute('type', 'text');
                input.setAttribute('value', mergeTag);
                document.body.appendChild(input);
                input.select();
                document.execCommand('copy');
                document.body.removeChild(input);
            }
            var vm = this;
            this.copiedKey = fullKey;
            setTimeout(function () {
                if (vm.copiedKey === fullKey) vm.copiedKey = '';
            }, 1500);
        },
        saveSecret: function (generate) {
            if (!this.currentWebhookId()) {
                this.secretMessage = "Webhook URL unavailable.";
                return;
            }
            var vm = this;
            this.savingSecret = true;
            this.secretMessage = '';
            jQuery.post(ajaxurl, {
                action: 'adfoin_set_webhooksinbound2_secret',
                _nonce: adfoin.nonce,
                webhookId: this.currentWebhookId(),
                secret: generate ? '' : this.secret,
                generate: generate ? '1' : '0'
            }).done(function (response) {
                if (response.success && response.data) {
                    vm.secret = response.data.secret || '';
                    vm.hasSecret = !!response.data.has_secret;
                    vm.secretMessage = vm.hasSecret ? 'Secret saved.' : 'Secret cleared.';
                } else if (response.data && response.data.message) {
                    vm.secretMessage = response.data.message;
                }
            }).fail(function () {
                vm.secretMessage = "Could not save the secret.";
            }).always(function () { vm.savingSecret = false; });
        },
        generateSecret: function () {
            this.saveSecret(true);
        },
        sendTest: function () {
            if (!this.currentWebhookId()) {
                this.testMessage = "Webhook URL unavailable.";
                return;
            }
            var vm = this;
            this.testing = true;
            this.testMessage = '';
            jQuery.post(ajaxurl, {
                action: 'adfoin_send_webhooksinbound2_test',
                _nonce: adfoin.nonce,
                webhookId: this.currentWebhookId()
            }).done(function (response) {
                if (response.success) {
                    vm.testMessage = 'Test event sent — loading payload...';
                    vm.loadLatestPayload();
                } else if (response.data && response.data.message) {
                    vm.testMessage = response.data.message;
                }
            }).fail(function () {
                vm.testMessage = "Could not send the test event.";
            }).always(function () { vm.testing = false; });
        },
        // Turn the flat key map into depth-tagged tree rows via a DFS over a
        // transient nested object keyed by the "__" path segments.
        buildRows: function (fields) {
            var tree = {};
            Object.keys(fields || {}).forEach(function (fullKey) {
                var parts = fullKey.split('__');
                var node = tree;
                parts.forEach(function (part, i) {
                    if (!node[part]) {
                        node[part] = { __children: {}, __fullKey: null, __value: undefined };
                    }
                    if (i === parts.length - 1) {
                        node[part].__fullKey = fullKey;
                        node[part].__value = fields[fullKey];
                    }
                    node = node[part].__children;
                });
            });

            var rows = [];
            (function walk(node, depth) {
                Object.keys(node).forEach(function (label) {
                    var n = node[label];
                    var hasChildren = Object.keys(n.__children).length > 0;
                    rows.push({
                        label: label,
                        depth: depth,
                        isLeaf: !hasChildren,
                        fullKey: n.__fullKey,
                        value: n.__value
                    });
                    if (hasChildren) {
                        walk(n.__children, depth + 1);
                    }
                });
            })(tree, 0);

            return rows;
        }
    }
});

// Simple trigger components - use factory pattern
(function() {
    var simpleTriggers = [
        'elementorpro', 'calderaforms', 'everestforms', 'fluentforms',
        'formcraft', 'formcraftb', 'formidable', 'forminator',
        'gravityforms', 'buddypress', 'cartflows', 'happyforms',
        'liveforms', 'ninjaforms', 'quform', 'quillforms',
        'smartforms', 'sureforms', 'weforms', 'wpforms',
        'bricks', 'wsform', 'jetformbuilder'
    ];
    
    simpleTriggers.forEach(function(name) {
        Vue.component(name, {
            props: ["trigger", "action", "fielddata"],
            template: '#' + name + '-template'
        });
    });
})();

// LifterlMS with extra logic
Vue.component('lifterlms', {
    props: ["trigger", "action", "fielddata"],
    template: '#lifterlms-template',
    mounted: function () {
        if (typeof this.trigger.extraFields.courseId == 'undefined') {
            this.trigger.extraFields.courseId = '';
        }
    }
});

// Conditional Logic components
Vue.component('cl-main', {
    props: ["trigger", "action", "fielddata"],
    template: '#cl-main-template',
    data: function () { return {} },
    methods: {
        clAddCondition: function (event) {
            var conditionL = adfoinNewIntegration.action.cl.conditions.length;
            adfoinNewIntegration.action.cl.conditions.push({ id: conditionL + 1, field: "", operator: "equal_to", value: "" });
        }
    }
});

Vue.component('conditional-logic', {
    props: {
        trigger:   {},
        action:    {},
        fielddata: {},
        condition: {},
        // 1-based position passed in from the parent so each row can
        // generate stable, position-aware DOM IDs and ARIA labels even
        // when condition.id values collide (length+1 is reused after a
        // remove).
        position:  { type: Number, default: 1 }
    },
    template: '#conditional-logic-template',
    data: function () { return { selected2: '' } },
    computed: {
        // Dynamic placeholder for the value input — gives the user a
        // concrete hint for operators that take a non-obvious value
        // shape (comma-separated lists, ranges, regex). Plain
        // text/number operators fall through to a generic "Value".
        valuePlaceholder: function () {
            switch (this.condition.operator) {
                case 'in_list':
                case 'not_in_list':
                    return 'value1, value2, value3';
                case 'between':
                case 'not_between':
                    return '5, 100';
                case 'matches_regex':
                case 'does_not_match_regex':
                    return '^[a-z0-9]+$  or  /pattern/i';
                case 'greater_than':
                case 'less_than':
                    return '0';
                case 'date_before':
                case 'date_after':
                case 'date_on':
                case 'date_not_on':
                    return 'YYYY-MM-DD or "today"';
                default:
                    return 'Value';
            }
        },
        // Visible-to-SR label that prefixes every per-control sr-only
        // label, e.g. "Condition 2". Single source of truth so changing
        // wording or i18n only happens here.
        rowLabel: function () {
            return 'Condition ' + this.position;
        },
        // Used by the trash button. SRs announce "Remove condition 2,
        // button" instead of just "button".
        removeLabel: function () {
            return 'Remove condition ' + this.position;
        }
    },
    methods: {
        clRemoveCondition: function (condition) {
            const conditionIndex = adfoinNewIntegration.action.cl.conditions.indexOf(condition);
            adfoinNewIntegration.action.cl.conditions.splice(conditionIndex, 1);
        },
        // Picking a field from the dropdown REPLACES the field-key text
        // with `{{name}}`. Previously this method appended, so picking
        // twice produced "{{a}} {{b}}" — never what a user intends in a
        // single condition. Manual typing in the text input is unchanged
        // for power users who want a custom expression.
        updateFieldValue: function (e) {
            if (this.selected2 || this.selected2 == 0) {
                this.condition.field = '{{' + this.selected2 + '}}';
            }
        }
    }
});

// Editable field component
Vue.component('editable-field', {
    props: ["trigger", "action", "fielddata", "field"],
    template: '#editable-field-template',
    data: function () { return { selected: '' } },
    methods: {
        updateFieldValue: function (e) {
            if (this.selected || this.selected == 0) {
                if (this.fielddata[this.field.value] || "0" == this.fielddata[this.field.value]) {
                    this.fielddata[this.field.value] += ' {{' + this.selected + '}}';
                } else {
                    this.fielddata[this.field.value] = '{{' + this.selected + '}}';
                }
            }
        },
        inArray: function (needle, haystack) {
            var length = haystack.length;
            for (var i = 0; i < length; i++) {
                if (haystack[i] == needle) return true;
            }
            return false;
        }
    }
});
