// Copyright Darko Gjorgjijoski <info@codeverve.com>
// 2024. All Rights Reserved.
// This file is licensed under the GPLv2 License.
// License text available at https://opensource.org/licenses/gpl-2.0.php

(function() {
    'use strict';

    /**
     * VimeifySettings - Custom settings page renderer
     */
    window.VimeifySettings = function(config) {
        this.config = config || {};
        this.container = null;
        this.values = config.values || {};
        this.sections = config.sections || [];
        this.settings = config.settings || [];
        this.activeTab = null;
        this.saveTimeout = null;
        this.isDirty = false;

        this.init();
    };

    VimeifySettings.prototype = {
        /**
         * Initialize the settings page
         */
        init: function() {
            this.container = document.getElementById('vimeify-settings-root');
            if (!this.container) {
                return;
            }

            this.render();
            this.bindEvents();
        },

        /**
         * Render the settings page
         */
        render: function() {
            var html = '<div class="vimeify-settings">';

            // Sidebar with tabs navigation
            if (this.sections.length > 0) {
                html += '<div class="vimeify-settings-sidebar">';
                html += '<div class="vimeify-settings-tabs">';
                for (var i = 0; i < this.sections.length; i++) {
                    var section = this.sections[i];
                    var activeClass = (i === 0) ? ' vimeify-settings-tab--active' : '';
                    html += '<button type="button" class="vimeify-settings-tab' + activeClass + '" data-section="' + this.escapeHtml(section.id) + '">';
                    html += this.escapeHtml(section.title);
                    html += '</button>';
                }
                html += '</div>';
                html += '</div>';
            }

            // Main content area
            html += '<div class="vimeify-settings-main">';

            // Settings form
            html += '<form id="vimeify-settings-form" class="vimeify-settings-form">';

            // Render sections
            for (var j = 0; j < this.sections.length; j++) {
                var sectionData = this.sections[j];
                var sectionClass = (j === 0) ? 'vimeify-settings-section vimeify-settings-section--active' : 'vimeify-settings-section';
                html += '<div class="' + sectionClass + '" data-section="' + this.escapeHtml(sectionData.id) + '">';

                // Render fields for this section
                var sectionFields = this.getFieldsForSection(sectionData.id);
                for (var k = 0; k < sectionFields.length; k++) {
                    html += this.renderField(sectionFields[k]);
                }

                html += '</div>';
            }

            // Save button
            if (this.config.showButtons) {
                html += '<div class="vimeify-settings-footer">';
                html += '<button type="submit" class="button button-primary vimeify-settings-save">';
                html += this.escapeHtml(this.config.buttonText || 'Save changes');
                html += '</button>';
                html += '<span class="vimeify-settings-status"></span>';
                if (this.config.documentationUrl) {
                    html += '<a href="' + this.escapeHtml(this.config.documentationUrl) + '" target="_blank" rel="noopener noreferrer" class="vimeify-settings-docs-link">';
                    html += this.escapeHtml(this.config.i18n.documentation || 'Documentation');
                    html += '</a>';
                }
                html += '</div>';
            }

            html += '</form>';
            html += '</div>'; // .vimeify-settings-main
            html += '</div>'; // .vimeify-settings

            this.container.innerHTML = html;

            // Set active tab (restore from localStorage or use first)
            if (this.sections.length > 0) {
                var savedTab = this.getSavedTab();
                if (savedTab && this.sectionExists(savedTab)) {
                    this.activeTab = savedTab;
                    this.switchTab(savedTab);
                } else {
                    this.activeTab = this.sections[0].id;
                }
            }

            // Initialize AJAX selects after rendering
            this.initAjaxSelects();
        },

        /**
         * Get fields for a specific section
         */
        getFieldsForSection: function(sectionId) {
            var fields = [];
            for (var i = 0; i < this.settings.length; i++) {
                var setting = this.settings[i];
                if (setting.section === sectionId) {
                    fields.push(setting);
                }
            }
            return fields;
        },

        /**
         * Render a single field
         */
        renderField: function(field) {
            var html = '';
            var fieldType = field.type || 'text';

            switch (fieldType) {
                case 'tab':
                    // Tab fields are rendered as section headers within sections
                    html = this.renderTabField(field);
                    break;
                case 'checkbox':
                    html = this.renderCheckboxField(field);
                    break;
                case 'radio':
                    html = this.renderRadioField(field);
                    break;
                case 'select':
                    html = this.renderSelectField(field);
                    break;
                case 'text':
                    html = this.renderTextField(field);
                    break;
                case 'html':
                    html = this.renderHtmlField(field);
                    break;
                default:
                    html = this.renderTextField(field);
            }

            return html;
        },

        /**
         * Render tab field (section header within a section)
         */
        renderTabField: function(field) {
            return ''; // Tabs are handled differently now via sections
        },

        /**
         * Render checkbox field
         */
        renderCheckboxField: function(field) {
            var html = '<div class="vimeify-settings-field vimeify-settings-field--checkbox" data-field-id="' + this.escapeHtml(field.id) + '">';

            // Label
            if (field.label) {
                html += '<div class="vimeify-settings-field__label">' + this.escapeHtml(field.label) + '</div>';
            }

            // Description (above choices)
            if (field.desc) {
                html += '<p class="vimeify-settings-field__desc">' + this.escapeHtml(field.desc) + '</p>';
            }

            // Choices
            if (field.choices) {
                html += '<div class="vimeify-settings-field__choices">';

                var choices = field.choices;
                var isArray = Array.isArray(choices);
                var keys = isArray ? choices : Object.keys(choices);

                for (var i = 0; i < keys.length; i++) {
                    var choice, choiceKey, choiceLabel, choiceValue, choiceDesc;

                    if (isArray) {
                        choice = keys[i];
                        choiceKey = choice.value !== undefined ? choice.value : i;
                        choiceLabel = choice.label || '';
                        choiceValue = choice.value !== undefined ? choice.value : 1;
                        choiceDesc = choice.desc || '';
                    } else {
                        choiceKey = keys[i];
                        choice = choices[choiceKey];
                        choiceLabel = choice.label || '';
                        choiceValue = choice.value !== undefined ? choice.value : 1;
                        choiceDesc = choice.desc || '';
                    }

                    var inputName = this.getFieldName(field, choiceKey);
                    var currentValue = this.getFieldValue(field, choiceKey);
                    var checked = currentValue ? ' checked' : '';

                    html += '<label class="vimeify-settings-checkbox">';
                    html += '<input type="checkbox" name="' + this.escapeHtml(inputName) + '" value="' + this.escapeHtml(choiceValue) + '"' + checked + '>';
                    html += '<span class="vimeify-settings-checkbox__label">' + this.escapeHtml(choiceLabel) + '</span>';
                    if (choiceDesc) {
                        html += '<span class="vimeify-settings-checkbox__desc">' + this.escapeHtml(choiceDesc) + '</span>';
                    }
                    html += '</label>';
                }

                html += '</div>';
            }

            html += '</div>';
            return html;
        },

        /**
         * Render radio field
         */
        renderRadioField: function(field) {
            var html = '<div class="vimeify-settings-field vimeify-settings-field--radio" data-field-id="' + this.escapeHtml(field.id) + '">';

            // Label
            if (field.label) {
                html += '<div class="vimeify-settings-field__label">' + this.escapeHtml(field.label) + '</div>';
            }

            // Description
            if (field.desc) {
                html += '<p class="vimeify-settings-field__desc">' + this.escapeHtml(field.desc) + '</p>';
            }

            // Choices
            if (field.choices) {
                html += '<div class="vimeify-settings-field__choices">';

                var currentValue = this.getFieldValue(field);
                var defaultValue = field.std || '';

                for (var i = 0; i < field.choices.length; i++) {
                    var choice = field.choices[i];
                    var choiceValue = choice.value !== undefined ? choice.value : '';
                    var checked = '';

                    if (currentValue !== undefined && currentValue !== null && currentValue !== '') {
                        checked = (currentValue === choiceValue) ? ' checked' : '';
                    } else if (defaultValue === choiceValue) {
                        checked = ' checked';
                    }

                    var inputName = this.getFieldName(field);

                    html += '<label class="vimeify-settings-radio">';
                    html += '<input type="radio" name="' + this.escapeHtml(inputName) + '" value="' + this.escapeHtml(choiceValue) + '"' + checked + '>';
                    html += '<span class="vimeify-settings-radio__label">' + this.escapeHtml(choice.label || '') + '</span>';
                    html += '</label>';
                }

                html += '</div>';
            }

            html += '</div>';
            return html;
        },

        /**
         * Render select field
         */
        renderSelectField: function(field) {
            var isAjax = field.ajax && field.ajax.action;
            var html = '<div class="vimeify-settings-field vimeify-settings-field--select' + (isAjax ? ' vimeify-settings-field--ajax' : '') + '" data-field-id="' + this.escapeHtml(field.id) + '">';

            // Label
            if (field.label) {
                html += '<div class="vimeify-settings-field__label">' + this.escapeHtml(field.label) + '</div>';
            }

            // Description
            if (field.desc) {
                html += '<p class="vimeify-settings-field__desc">' + this.escapeHtml(field.desc) + '</p>';
            }

            var inputName = this.getFieldName(field);
            var currentValue = this.getFieldValue(field);
            var placeholder = field.placeholder || '';

            if (isAjax) {
                // AJAX-powered select
                html += '<select class="vimeify-settings-select vimeify-ajax-select" name="' + this.escapeHtml(inputName) + '"';
                html += ' data-ajax-endpoint="' + this.escapeHtml(field.ajax.endpoint || '') + '"';
                html += ' data-ajax-action="' + this.escapeHtml(field.ajax.action || '') + '"';
                html += ' data-ajax-nonce="' + this.escapeHtml(field.ajax.nonce || '') + '"';
                html += ' data-placeholder="' + this.escapeHtml(placeholder) + '"';
                html += '>';

                // Render pre-loaded choices (for current value)
                if (field.choices && field.choices.length > 0) {
                    for (var i = 0; i < field.choices.length; i++) {
                        var choice = field.choices[i];
                        var selected = (currentValue == choice.value) ? ' selected' : '';
                        html += '<option value="' + this.escapeHtml(choice.value || '') + '"' + selected + '>';
                        html += this.escapeHtml(choice.label || '');
                        html += '</option>';
                    }
                }

                html += '</select>';
            } else {
                // Static select
                html += '<select class="vimeify-settings-select" name="' + this.escapeHtml(inputName) + '">';

                if (placeholder) {
                    html += '<option value="">' + this.escapeHtml(placeholder) + '</option>';
                }

                if (field.choices) {
                    var choices = field.choices;
                    var choicesArray = Array.isArray(choices) ? choices : Object.values(choices);

                    for (var j = 0; j < choicesArray.length; j++) {
                        var opt = choicesArray[j];
                        var optValue = opt.value !== undefined ? opt.value : '';
                        var optLabel = opt.label || '';
                        var optDisabled = opt.disabled ? ' disabled' : '';
                        var optSelected = (currentValue == optValue) ? ' selected' : '';

                        html += '<option value="' + this.escapeHtml(optValue) + '"' + optDisabled + optSelected + '>';
                        html += this.escapeHtml(optLabel);
                        html += '</option>';
                    }
                }

                html += '</select>';
            }

            html += '</div>';
            return html;
        },

        /**
         * Render text field
         */
        renderTextField: function(field) {
            var html = '<div class="vimeify-settings-field vimeify-settings-field--text" data-field-id="' + this.escapeHtml(field.id) + '">';

            // Label
            if (field.label) {
                html += '<div class="vimeify-settings-field__label">' + this.escapeHtml(field.label) + '</div>';
            }

            // Description
            if (field.desc) {
                html += '<p class="vimeify-settings-field__desc">' + this.escapeHtml(field.desc) + '</p>';
            }

            var inputName = this.getFieldName(field);
            var currentValue = this.getFieldValue(field);
            var placeholder = field.placeholder || '';

            html += '<input type="text" class="vimeify-settings-input regular-text" name="' + this.escapeHtml(inputName) + '"';
            html += ' value="' + this.escapeHtml(currentValue || '') + '"';
            if (placeholder) {
                html += ' placeholder="' + this.escapeHtml(placeholder) + '"';
            }
            html += '>';

            html += '</div>';
            return html;
        },

        /**
         * Render HTML field (custom markup)
         */
        renderHtmlField: function(field) {
            var html = '<div class="vimeify-settings-field vimeify-settings-field--html" data-field-id="' + this.escapeHtml(field.id) + '">';

            // Label
            if (field.label) {
                html += '<div class="vimeify-settings-field__label">' + this.escapeHtml(field.label) + '</div>';
            }

            // Custom markup (already sanitized by PHP)
            if (field.markup) {
                html += '<div class="vimeify-settings-field__markup">' + field.markup + '</div>';
            }

            html += '</div>';
            return html;
        },

        /**
         * Get field name for form submission
         */
        getFieldName: function(field, choiceKey) {
            var section = field.section || '';
            var fieldId = field.id || '';

            if (choiceKey !== undefined) {
                return section + '[' + fieldId + '][' + choiceKey + ']';
            }

            return section + '[' + fieldId + ']';
        },

        /**
         * Get current field value
         */
        getFieldValue: function(field, choiceKey) {
            var section = field.section || '';
            var fieldId = field.id || '';

            if (this.values && this.values[section] && this.values[section][fieldId] !== undefined) {
                if (choiceKey !== undefined) {
                    return this.values[section][fieldId][choiceKey] || '';
                }
                return this.values[section][fieldId];
            }

            return field.std || '';
        },

        /**
         * Initialize AJAX-powered selects
         */
        initAjaxSelects: function() {
            var self = this;
            var ajaxSelects = this.container.querySelectorAll('.vimeify-ajax-select');

            ajaxSelects.forEach(function(select) {
                self.initSingleAjaxSelect(select);
            });
        },

        /**
         * Initialize a single AJAX select using Select2 if available
         */
        initSingleAjaxSelect: function(select) {
            var self = this;
            var endpoint = select.dataset.ajaxEndpoint;
            var action = select.dataset.ajaxAction;
            var nonce = select.dataset.ajaxNonce;
            var placeholder = select.dataset.placeholder || '';

            // Use Select2 if available
            if (typeof jQuery !== 'undefined' && jQuery.fn.select2) {
                jQuery(select).select2({
                    width: '100%',
                    placeholder: placeholder,
                    allowClear: true,
                    minimumInputLength: 0,
                    ajax: {
                        url: endpoint + '?action=' + action + '&_wpnonce=' + nonce,
                        dataType: 'json',
                        delay: 250,
                        data: function(params) {
                            return {
                                search_str: params.term || '',
                                page_number: params.page || 1
                            };
                        },
                        processResults: function(response, params) {
                            params.page = params.page || 1;
                            if (response.success && response.data.results) {
                                return {
                                    results: response.data.results,
                                    pagination: response.data.pagination || {}
                                };
                            }
                            return { results: [] };
                        },
                        cache: true
                    },
                    language: {
                        errorLoading: function() {
                            return self.config.i18n.error || 'Error loading results';
                        },
                        noResults: function() {
                            return self.config.i18n.noResults || 'No results found';
                        },
                        searching: function() {
                            return self.config.i18n.searching || 'Searching...';
                        },
                        inputTooShort: function() {
                            return self.config.i18n.typeToSearch || 'Type to search...';
                        }
                    }
                });
            }
        },

        /**
         * Bind event listeners
         */
        bindEvents: function() {
            var self = this;

            // Tab switching
            var tabs = this.container.querySelectorAll('.vimeify-settings-tab');
            tabs.forEach(function(tab) {
                tab.addEventListener('click', function(e) {
                    e.preventDefault();
                    self.switchTab(this.dataset.section);
                });
            });

            // Form submission
            var form = document.getElementById('vimeify-settings-form');
            if (form) {
                form.addEventListener('submit', function(e) {
                    e.preventDefault();
                    self.saveSettings();
                });
            }

            // Track dirty state
            var inputs = this.container.querySelectorAll('input, select, textarea');
            inputs.forEach(function(input) {
                input.addEventListener('change', function() {
                    self.isDirty = true;
                });
            });
        },

        /**
         * Switch to a different tab
         */
        switchTab: function(sectionId) {
            // Update tab buttons
            var tabs = this.container.querySelectorAll('.vimeify-settings-tab');
            tabs.forEach(function(tab) {
                if (tab.dataset.section === sectionId) {
                    tab.classList.add('vimeify-settings-tab--active');
                } else {
                    tab.classList.remove('vimeify-settings-tab--active');
                }
            });

            // Update sections
            var sections = this.container.querySelectorAll('.vimeify-settings-section');
            sections.forEach(function(section) {
                if (section.dataset.section === sectionId) {
                    section.classList.add('vimeify-settings-section--active');
                } else {
                    section.classList.remove('vimeify-settings-section--active');
                }
            });

            this.activeTab = sectionId;
            this.saveTab(sectionId);
        },

        /**
         * Check if a section exists
         */
        sectionExists: function(sectionId) {
            for (var i = 0; i < this.sections.length; i++) {
                if (this.sections[i].id === sectionId) {
                    return true;
                }
            }
            return false;
        },

        /**
         * Get saved tab from localStorage
         */
        getSavedTab: function() {
            try {
                return localStorage.getItem('vimeify_settings_active_tab');
            } catch (e) {
                return null;
            }
        },

        /**
         * Save tab to localStorage
         */
        saveTab: function(tabId) {
            try {
                localStorage.setItem('vimeify_settings_active_tab', tabId);
            } catch (e) {
                // localStorage not available
            }
        },

        /**
         * Save settings via AJAX
         */
        saveSettings: function() {
            var self = this;
            var form = document.getElementById('vimeify-settings-form');
            var saveBtn = this.container.querySelector('.vimeify-settings-save');
            var statusEl = this.container.querySelector('.vimeify-settings-status');

            if (!form) {
                return;
            }

            // Show saving state
            if (saveBtn) {
                saveBtn.disabled = true;
                saveBtn.textContent = this.config.i18n.saving || 'Saving...';
            }

            // Collect form data
            var formData = new FormData(form);
            formData.append('action', this.config.saveAction || 'vimeify_save_settings');
            formData.append('_wpnonce', this.config.nonce);

            // Send AJAX request
            var xhr = new XMLHttpRequest();
            xhr.open('POST', this.config.ajaxUrl, true);

            xhr.onload = function() {
                if (xhr.status === 200) {
                    try {
                        var response = JSON.parse(xhr.responseText);

                        if (response.success) {
                            self.isDirty = false;

                            if (statusEl) {
                                statusEl.textContent = self.config.updatedMessage || 'Options updated!';
                                statusEl.className = 'vimeify-settings-status vimeify-settings-status--success';
                            }

                            // Update local values
                            if (response.data && response.data.values) {
                                self.values = response.data.values;
                            }
                        } else {
                            if (statusEl) {
                                statusEl.textContent = (response.data && response.data.message) || self.config.i18n.error;
                                statusEl.className = 'vimeify-settings-status vimeify-settings-status--error';
                            }
                        }
                    } catch (e) {
                        if (statusEl) {
                            statusEl.textContent = self.config.i18n.error || 'Error saving settings';
                            statusEl.className = 'vimeify-settings-status vimeify-settings-status--error';
                        }
                    }
                } else {
                    if (statusEl) {
                        statusEl.textContent = self.config.i18n.error || 'Error saving settings';
                        statusEl.className = 'vimeify-settings-status vimeify-settings-status--error';
                    }
                }

                // Reset button
                if (saveBtn) {
                    saveBtn.disabled = false;
                    saveBtn.textContent = self.config.buttonText || 'Save changes';
                }

                // Clear status after delay
                setTimeout(function() {
                    if (statusEl) {
                        statusEl.textContent = '';
                        statusEl.className = 'vimeify-settings-status';
                    }
                }, 3000);
            };

            xhr.onerror = function() {
                if (saveBtn) {
                    saveBtn.disabled = false;
                    saveBtn.textContent = self.config.buttonText || 'Save changes';
                }

                if (statusEl) {
                    statusEl.textContent = self.config.i18n.error || 'Error saving settings';
                    statusEl.className = 'vimeify-settings-status vimeify-settings-status--error';
                }
            };

            xhr.send(formData);
        },

        /**
         * Escape HTML entities
         */
        escapeHtml: function(text) {
            if (text === null || text === undefined) {
                return '';
            }
            var div = document.createElement('div');
            div.textContent = String(text);
            return div.innerHTML;
        }
    };

    // Auto-initialize when DOM is ready
    document.addEventListener('DOMContentLoaded', function() {
        if (typeof Vimeify_Settings !== 'undefined' && document.getElementById('vimeify-settings-root')) {
            new VimeifySettings(Vimeify_Settings);
        }
    });
})();
