// 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';

    /**
     * VimeifyMetabox - Custom metabox renderer
     */
    window.VimeifyMetabox = function(config) {
        this.config = config || {};
        this.container = null;
        this.values = config.values || {};
        this.tabs = config.tabs || [];
        this.fields = config.fields || [];
        this.activeTab = null;
        this.metaboxId = config.metaboxId || 'vimeify_metabox';
        this.saveMode = config.saveMode || 'compact';

        this.init();
    };

    VimeifyMetabox.prototype = {
        /**
         * Initialize the metabox
         */
        init: function() {
            this.container = document.getElementById('vimeify-metabox-root-' + this.metaboxId);
            if (!this.container) {
                return;
            }

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

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

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

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

            // Fields container
            html += '<div class="vimeify-metabox-content">';

            // Group fields by their section (tab)
            if (this.tabs.length > 0) {
                var currentTab = null;

                for (var j = 0; j < this.fields.length; j++) {
                    var field = this.fields[j];

                    if (field.type === 'tab') {
                        // Close previous tab section if open
                        if (currentTab !== null) {
                            html += '</div>';
                        }

                        // Start new tab section
                        var isFirstTab = (currentTab === null);
                        var tabClass = isFirstTab ? 'vimeify-metabox-section vimeify-metabox-section--active' : 'vimeify-metabox-section';
                        html += '<div class="' + tabClass + '" data-tab="' + this.escapeHtml(field.id) + '">';
                        currentTab = field.id;
                    } else {
                        html += this.renderField(field);
                    }
                }

                // Close last tab section
                if (currentTab !== null) {
                    html += '</div>';
                }
            } else {
                // No tabs - render all fields directly
                for (var k = 0; k < this.fields.length; k++) {
                    if (this.fields[k].type !== 'tab') {
                        html += this.renderField(this.fields[k]);
                    }
                }
            }

            html += '</div>'; // .vimeify-metabox-content
            html += '</div>'; // .vimeify-metabox-main
            html += '</div>'; // .vimeify-metabox

            this.container.innerHTML = html;

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

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

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

            switch (fieldType) {
                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 checkbox field
         */
        renderCheckboxField: function(field) {
            var html = '<div class="vimeify-metabox-field vimeify-metabox-field--checkbox" data-field-id="' + this.escapeHtml(field.id) + '">';

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

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

            // Choices
            if (field.choices) {
                html += '<div class="vimeify-metabox-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 currentValue = this.getFieldValue(field.id, choiceKey);
                    var checked = currentValue ? ' checked' : '';

                    html += '<label class="vimeify-metabox-checkbox">';
                    html += '<input type="checkbox" data-field="' + this.escapeHtml(field.id) + '" data-choice="' + this.escapeHtml(choiceKey) + '" value="' + this.escapeHtml(choiceValue) + '"' + checked + '>';
                    html += '<span class="vimeify-metabox-checkbox__label">' + this.escapeHtml(choiceLabel) + '</span>';
                    if (choiceDesc) {
                        html += '<span class="vimeify-metabox-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-metabox-field vimeify-metabox-field--radio" data-field-id="' + this.escapeHtml(field.id) + '">';

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

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

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

                var currentValue = this.getFieldValue(field.id);
                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';
                    }

                    html += '<label class="vimeify-metabox-radio">';
                    html += '<input type="radio" name="vimeify_meta_' + this.escapeHtml(field.id) + '" data-field="' + this.escapeHtml(field.id) + '" value="' + this.escapeHtml(choiceValue) + '"' + checked + '>';
                    html += '<span class="vimeify-metabox-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-metabox-field vimeify-metabox-field--select' + (isAjax ? ' vimeify-metabox-field--ajax' : '') + '" data-field-id="' + this.escapeHtml(field.id) + '">';

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

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

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

            if (isAjax) {
                // AJAX-powered select
                html += '<select class="vimeify-metabox-select vimeify-ajax-select" data-field="' + this.escapeHtml(field.id) + '"';
                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-metabox-select" data-field="' + this.escapeHtml(field.id) + '">';

                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-metabox-field vimeify-metabox-field--text" data-field-id="' + this.escapeHtml(field.id) + '">';

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

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

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

            html += '<input type="text" class="vimeify-metabox-input regular-text" data-field="' + this.escapeHtml(field.id) + '"';
            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-metabox-field vimeify-metabox-field--html" data-field-id="' + this.escapeHtml(field.id) + '">';

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

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

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

        /**
         * Get current field value
         */
        getFieldValue: function(fieldId, choiceKey) {
            if (this.values && this.values[fieldId] !== undefined) {
                if (choiceKey !== undefined) {
                    return this.values[fieldId][choiceKey] || '';
                }
                return this.values[fieldId];
            }

            return '';
        },

        /**
         * 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...';
                        }
                    }
                });

                // Update hidden data on change
                jQuery(select).on('change', function() {
                    self.updateHiddenData();
                });
            }
        },

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

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

            // Track changes and update hidden input
            var inputs = this.container.querySelectorAll('input, select, textarea');
            inputs.forEach(function(input) {
                input.addEventListener('change', function() {
                    self.updateHiddenData();
                });
            });
        },

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

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

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

        /**
         * Check if a tab exists
         */
        tabExists: function(tabId) {
            for (var i = 0; i < this.tabs.length; i++) {
                if (this.tabs[i].id === tabId) {
                    return true;
                }
            }
            return false;
        },

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

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

        /**
         * Update the hidden data input with current values
         */
        updateHiddenData: function() {
            if (this.saveMode !== 'compact') {
                return;
            }

            var data = {};
            var self = this;

            // Collect all field values
            this.fields.forEach(function(field) {
                if (field.type === 'tab' || field.type === 'html') {
                    return;
                }

                var fieldId = field.id;

                if (field.type === 'checkbox' && field.choices) {
                    // Checkbox group
                    data[fieldId] = {};
                    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 choiceKey;
                        if (isArray) {
                            var choice = keys[i];
                            choiceKey = choice.value !== undefined ? choice.value : i;
                        } else {
                            choiceKey = keys[i];
                        }

                        var checkbox = self.container.querySelector('input[type="checkbox"][data-field="' + fieldId + '"][data-choice="' + choiceKey + '"]');
                        if (checkbox) {
                            data[fieldId][choiceKey] = checkbox.checked ? checkbox.value : '';
                        }
                    }
                } else if (field.type === 'radio') {
                    var radio = self.container.querySelector('input[type="radio"][data-field="' + fieldId + '"]:checked');
                    data[fieldId] = radio ? radio.value : '';
                } else {
                    var input = self.container.querySelector('[data-field="' + fieldId + '"]');
                    if (input) {
                        data[fieldId] = input.value || '';
                    }
                }
            });

            // Update hidden input
            var hiddenInput = document.getElementById(this.metaboxId + '_data');
            if (hiddenInput) {
                hiddenInput.value = JSON.stringify(data);
            }

            // Also update local values
            this.values = data;
        },

        /**
         * 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() {
        // Find all metabox configs and initialize
        var metaboxRoots = document.querySelectorAll('.vimeify-metabox-root');

        metaboxRoots.forEach(function(root) {
            var metaboxId = root.dataset.metaboxId;
            var configName = 'Vimeify_Metabox_' + metaboxId;

            if (typeof window[configName] !== 'undefined') {
                new VimeifyMetabox(window[configName]);
            }
        });
    });
})();
