/* *********   Custom Js Script for WP-Deployer Plugin   ********* */

jQuery(document).ready(function ($) {
    // @TODO: Remove unused or deprecate soon to be removed code.
    $('.deploy-sync-content--notice.is-dismissible').each(function () {
        var $el = $(this),
            $button = $('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>');

        if ($el.find('.notice-dismiss').length) {
            return;
        }
        // Ensure plain text
        $button.find('.screen-reader-text').text('Dismiss this notice.');
        $button.on('click.wp-dismiss-notice', function (event) {
            event.preventDefault();
            $el.fadeTo(100, 0, function () {
                $el.slideUp(100, function () {
                    $el.remove();
                });
            });
        });
        $el.append($button);
    });

    $('.toplevel_page_deploy-sync-content .select-all-checkbox').click(function () {
        if ($(this).is(':checked')) {
            $(this).closest('.select-all-row').next().find('input[type="checkbox"]').prop('checked', true);
        } else {
            $(this).closest('.select-all-row').next().find('input[type="checkbox"]').prop('checked', false);
        }
    });

    $('.toplevel_page_deploy-sync-content .list-trackers input[type="checkbox"]').click(function () {
        if (!$(this).is(':checked')) {
            $(this).closest('.list-trackers').prev().find('.select-all-checkbox').prop('checked', false);
        }
        // checkbox selectAll checked if all items are checked
        if ($('input.checkbox-tracker-item:checked').length === $('input.checkbox-tracker-item').length) {
            $(this).closest('.list-trackers').prev().find('.select-all-checkbox').prop('checked', true);
        }
    });

    // For checkbox subordinate tracker item.
    $('.toplevel_page_deploy-sync-content input.child-tracker-item').click(function () {
        if ($(this).is(':checked')) {
            // Check the parent item.
            $(this)
                .closest('.row.g-3.text-left')
                .parent().closest('.row.g-3.text-left')
                .find('input.checkbox-tracker-item')
                .first()
                .prop('checked', true);
        }
    });

    $('.toplevel_page_deploy-sync-content input.checkbox-tracker-item').click(function () {
        if ($(this).is(':checked')) {
            // Check all descendants.
            $(this)
                .closest('.row.g-3.text-left')
                .find('input.checkbox-tracker-item')
                .prop('checked', true);
        }
    });

    // Remove Bundle item
    $(".toplevel_page_deploy-sync-content .delete-item").on("click", function () {
        var _admin_url = $(this).data("admin-url");
        var _itemId = $(this).data("id");
        var _nonce = $(this).data("nonce");
        // Use Bootstrap modal for confirmation
        $("#confirmationModal").modal("show");

        // When the "Confirm" button in the modal is clicked
        $("#confirm-action").on("click", function () {
            $.post(_admin_url + "admin-ajax.php", {
                action: "deploy_sync_content__remove_item",
                id: _itemId,
                _wpnonce: _nonce
            }, function () {
                // Reload the list after deletion
                location.reload();
            });
        });
    });

    // For checkbox table tracker - Advanced Settings
    $('.toplevel_page_deploy-sync-content input.table-plugin').each(function () {
        if ($(this).is(':checked')) {
            $(this).closest('.wrapper-checkbox-table').next().css('display', 'block');
        } else {
            $(this).closest('.wrapper-checkbox-table').next().css('display', 'none');
        }
    });
    $('.toplevel_page_deploy-sync-content input.table-plugin').click(function () {
        if ($(this).is(':checked')) {
            $(this).closest('.wrapper-checkbox-table').next().find('input.class-deploy-sync-content-setting-track').prop('checked', true);
            $(this).closest('.wrapper-checkbox-table').next().css('display', 'block');
        } else {
            $(this).closest('.wrapper-checkbox-table').next().find('input.class-deploy-sync-content-setting-track').prop('checked', false);
            $(this).closest('.wrapper-checkbox-table').next().find('input.class-deploy-sync-content-setting-follow').prop('checked', false);
            $(this).closest('.wrapper-checkbox-table').next().css('display', 'none');
        }
    });

    const updateItemValueHandlerValue = function (jQueryElement) {
        if (jQueryElement.val() !== '' && jQueryElement.val() !== 'none') {
            // Set this input value and show the dependency checkbox.
            jQueryElement.parent().next().find('input').val(jQueryElement.val() + ':' + jQueryElement.parent().prev().html());
        } else {
            // Empty this input value and hide the dependency checkbox.
            jQueryElement.parent().next().find('input').val('');
        }

        if (jQueryElement.val().startsWith('reference:')) {
            // Reference value handlers make subordination available.
            jQueryElement.parent().next().show();
        } else {
            jQueryElement.parent().next().hide();
        }
    };

    const rebuildItemValueHandlerSubform = (selectMappingJqueryElement) => {
        // Detect which sub form to load.
        const selectedItemValueHandlerFullId = selectMappingJqueryElement?.val() ?? '';
        const selectedItemValueHandlerMainId = selectedItemValueHandlerFullId.indexOf(':') > 0 ? selectedItemValueHandlerFullId.substring(0, selectedItemValueHandlerFullId.indexOf(':')) : selectedItemValueHandlerFullId;

        // Remove all subforms.
        const ivhSubformWrapper = selectMappingJqueryElement.closest('.form-group').find('.ivh-subform');
        ivhSubformWrapper?.html('');

        // Find the subform template, if any.
        const template = selectMappingJqueryElement.closest('.accordion').find('.deploy-sync-content--settings--item-value-handler-subform--' + selectedItemValueHandlerMainId + '[data-dtt-template]');

        if (template[0] ?? false) {
            // There is a template. Copy it and build it.
            ivhSubformWrapper.html(template.prop('outerHTML'));

            const for_table = selectMappingJqueryElement.closest('.wrapper-options-table')[0]?.dataset.table ?? '';
            const for_field = selectMappingJqueryElement.closest('.form-group')[0]?.dataset.col ?? '';

            processTemplates(ivhSubformWrapper[0], {for_table: for_table, for_field: for_field})
        }
    };

    // For select ref_table / ref_post - Advanced Settings
    $('.toplevel_page_deploy-sync-content select.select-mapping').change(function () {
        updateItemValueHandlerValue($(this));
        rebuildItemValueHandlerSubform($(this));
    });

    $('.toplevel_page_deploy-sync-content .select-mapping').each(function () {
        updateItemValueHandlerValue($(this));
    });

    // Toogle Dependancy
    $('.is-dependency input[type=checkbox]').click(function () {
        if ($(this).is(':checked')) {
            $('.is-dependency input[name=' + $(this).attr('name') + ']').prop('checked', false);
            $(this).prop('checked', true);
        }
    });

    // Add New Line Processor
    $('.toplevel_page_deploy-sync-content #add-new-line').click(function () {
        // Copy the template line.
        const _html_new_line = $('.processor-line-origin').prop('outerHTML').replace(/ selected/g, '');

        // Place the copy at the end of the list.
        const lastLine = $('#nav-processors > .processor-line:last');

        lastLine.after(_html_new_line);

        // This is the new duplicated line.
        const _dom_new_line = $('#nav-processors > .processor-line:last');

        // Set the row index.
        _dom_new_line[0].dataset.lineIndex = Number.parseInt(lastLine[0].dataset.lineIndex) + 1;

        // Prepare the row field names.
        processTemplates(_dom_new_line[0], {line_index: _dom_new_line[0].dataset.lineIndex});

        // The line is no longer a template. Remove the class.
        _dom_new_line.removeClass('processor-line-origin');

        const _dom_new_line_select = _dom_new_line.find('select');

        // Initialize the default selected value.
        _dom_new_line_select.attr('data-selected', '');

        // Make this line inputs submittable.
        _dom_new_line.find('input,select,textarea').removeAttr('disabled');

        applySelectProcessor();

        const _all_tables_label = getAllTableLabelsAndValues();
        addFieldsOptionsProcessor($('#nav-processors > .processor-line:last .processor-select'), _all_tables_label[0]);
        applyremoveLine();

        if ($('.tab-pane.active .row').length > 1) {
            $('.tab-pane.active .row .remove-line').show();
        }

        // Recreate the processor subform.
        updateSubformForProcessorLine(_dom_new_line);
    });

    $('.toplevel_page_deploy-sync-content #add-new-line-exclusion').click(function () {
        const _html_new_line = $('#nav-exclusions > .exclusion-line-origin').prop('outerHTML').replace(/ selected/g, '');

        // Place the copy at the end of the list.
        const lastLine = $('#nav-exclusions > .exclusion-line:last');

        lastLine.after(_html_new_line);

        // The new line.
        const _dom_new_line = $('#nav-exclusions > .exclusion-line:last');

        // Set the row index.
        _dom_new_line[0].dataset.lineIndex = Number.parseInt(lastLine[0].dataset.lineIndex) + 1;

        // Prepare the row field names.
        processTemplates(_dom_new_line[0], {line_index: _dom_new_line[0].dataset.lineIndex});

        // The line is no longer a template. Remove the class.
        _dom_new_line.removeClass('exclusion-line-origin');

        const _dom_new_line_select = _dom_new_line.find('select');

        // Initialize the default selected value.
        _dom_new_line_select.attr('data-selected', '');

        // Make this line inputs submittable.
        _dom_new_line.find('input,select,textarea').removeAttr('disabled');

        // Initialize the textarea of the exclusions.
        _dom_new_line.find('textarea').val('');

        applySelectExclusion();

        // This will initialize the options for the first table.
        const _all_tables_label = getAllTableLabelsAndValues();
        addFieldsOptionsExclusion($('#nav-exclusions > .exclusion-line:last .exclusion-field-select'), _all_tables_label[0]);

        applyremoveLine();

        if ($('.tab-pane.active .row').length > 1) {
            $('.tab-pane.active .row .remove-line').show();
        }
    });

    // init tooltip track / follow
    $(function () {
        if ($.fn.tooltip) {
            $('.tooltip-icon').tooltip();
        }
    });

    $('.toplevel_page_deploy-sync-content .deploy-sync-content--settings-label').keyup(function () {
        var _inputVal = $(this).val();
        var _tableName = $(this).data('table');
        var _newLabel = _inputVal + ' (' + _tableName + ')';
        if (_inputVal.trim() === '') {
            _newLabel = _tableName;
        }
        $('#deploy_sync_content__settings_tb_' + _tableName).html(_newLabel);
    });

    function loadProcessors() {
        prepareSelect(getAllTableLabelsAndValues(), '.processor-line .processor-select', addFieldsOptionsProcessor);
    }

    $('.toplevel_page_deploy-sync-content #nav-processors-tab').click(function () {
        loadProcessors();
    });

    applySelectProcessor();

    function applySelectProcessor() {
        $('.toplevel_page_deploy-sync-content #nav-processors select.processor-select').change(function () {
            var _tablename = $(this).val();
            addFieldsOptionsProcessor($(this), {"value": _tablename});

            // Recreate the processor subform.
            const processorLine = $(this).closest('.processor-line');
            updateSubformForProcessorLine(processorLine);
        });

        $('.toplevel_page_deploy-sync-content #nav-processors select.select-field').change(function () {
            const processorLine = $(this).closest('.processor-line');
            updateSubformForProcessorLine(processorLine);
        });

        $('.toplevel_page_deploy-sync-content #nav-processors select.processor-option').change(function () {
            const processorLine = $(this).closest('.processor-line');
            updateSubformForProcessorLine(processorLine);
        });
    }

    // For select fields by Table - Processors
    function addFieldsOptionsProcessor(selectElement, tableLabelAndValue) {
        const tablename = tableLabelAndValue?.value;

        const _all_cols_table = $(".col-table-" + tablename).map(function () {
            return $(this).find('label').html();
        }).get();

        const lineElement = selectElement.closest('.processor-line');

        lineElement.find('.select-field option').remove();

        let _elSelect = lineElement.find('.select-field');

        let selectedProcessorId = null;

        $.each(_all_cols_table, function (i, item) {
            let _selectedOption = '';

            if (_elSelect.data('selected') === item) {
                _selectedOption = 'selected';
                selectedProcessorId = item;
            }

            _elSelect.append('<option value="' + item + '" ' + _selectedOption + '>' + item + '</option>');
        });
    }

    // For select fields by Table - Exclusions
    function addFieldsOptionsExclusion(selectElement, tableLabelAndValue) {
        const tablename = tableLabelAndValue.value;

        const _all_cols_table = $(".col-table-" + tablename).map(function () {
            return $(this).find('label').html();
        }).get();

        selectElement.closest('.exclusion-line').find('.exclusion-field-select option').remove();

        let _elSelect = selectElement.closest('.exclusion-line').find('.exclusion-field-select');

        $.each(_all_cols_table, function (i, item) {
            let _selectedOption = '';

            if (_elSelect.data('selected') === item) {
                _selectedOption = 'selected';
            }

            _elSelect.append('<option value="' + item + '" ' + _selectedOption + '>' + item + '</option>');
        });
    }

    /**
     * Gets all enabled table labels (pretty name) and values (table real name).
     */
    function getAllTableLabelsAndValues() {
        return $(".toplevel_page_deploy-sync-content input.table-plugin:checked").map(function () {
            return {
                "label": $(this).next().html(), "value": $(this).val(),
            };
        }).get();
    }

    function prepareSelect(availableOptionsLabelsAndValues, selectSelectors, selectPostProcessCallback) {
        const _elSelect = $(selectSelectors);

        _elSelect.each(function (index, elt) {
            // Remove the previous <option> tags; we are rebuilding them.
            // Dev note: unsaved configured data will be lost.
            $(elt).find('option').remove();

            // Find the default selected option.
            let _selected_index = 0;

            $.each(availableOptionsLabelsAndValues, function (i, item) {
                let _selectedOption = '';

                if ($(elt).data('selected') === item.value) {
                    _selected_index = i;
                    _selectedOption = ' selected';
                }

                $(elt).append('<option value="' + item.value + '"' + _selectedOption + '>' + item.label + '</option>');
            });

            selectPostProcessCallback($(elt), availableOptionsLabelsAndValues[_selected_index]);
        });
    }

    function loadExclusions() {
        prepareSelect(getAllTableLabelsAndValues(), '.exclusion-line .exclusion-table-select', addFieldsOptionsExclusion);
    }

    $('.toplevel_page_deploy-sync-content #nav-exclusions-tab').click(function () {
        loadExclusions();
    });

    applySelectExclusion();

    function applySelectExclusion() {
        $('.toplevel_page_deploy-sync-content select.exclusion-table-select').change(function () {
            const _tablename = $(this).val();

            // Refresh the options for the new selected table.
            addFieldsOptionsExclusion($(this), {"value": _tablename});
        });
    }

    applyremoveLine();

    function applyremoveLine() {
        $('.toplevel_page_deploy-sync-content .remove-line').click(function () {
            if ($('.toplevel_page_deploy-sync-content .tab-pane.active .row').length > 1) {
                $('.toplevel_page_deploy-sync-content .tab-pane.active .row .remove-line').show();
                $(this).parent().closest('.row').remove();
                if ($('.toplevel_page_deploy-sync-content .tab-pane.active .row').length < 2) {
                    $('.toplevel_page_deploy-sync-content .tab-pane.active .row .remove-line').hide();
                }
            }
        });
    }

    loadProcessors();
    loadExclusions();

    function updateSubformForProcessorLine(lineElement) {
        /*
         * Processor subform code.
         */
        const subformWrapperElement = lineElement.find('.subform-wrapper');

        // Empty the processor subform first.
        subformWrapperElement.html('');

        // Find the selected processor ID.
        const selectedProcessorId = lineElement.find('.processor-option :selected')?.val();
        const selectedTable = lineElement.find('.processor-select :selected')?.val();
        const selectedField = lineElement.find('.select-field :selected')?.val();
        const lineIndex = lineElement[0].dataset.lineIndex ?? 0;

        // Add the processor subform, if any.
        const appended = lineElement.closest('#nav-processors')
            ?.find('.deploy-sync-content--settings--processor-subform--' + selectedProcessorId)
            ?.first()
            ?.clone()
            ?.appendTo(subformWrapperElement);

        if (appended.length) {
            // Process the template.
            processTemplates(appended[0], {for_table: selectedTable, for_field: selectedField, line_index: lineIndex});
        }
    }

    $('.toplevel_page_deploy-sync-content form#form-data-advanced-settings').submit(function (event) {
        if ($(this).hasClass('is-submitting')) {
            return;
        }

        const form = $(this);

        form.addClass('is-submitting');
        form.find('#submit-advanced-settings').attr('disabled', 'disabled');

        // $('.processor-line-origin').remove();
        // $('.exclusion-line-origin').remove();

        /*loadProcessors();
        loadExclusions();

        if ( $('.processor-line-origin').length <= 0 || $('.exclusion-line-origin').length <= 0 ) {
            return;
        }

        $('form#form-data-advanced-settings').submit();*/

        event.preventDefault(); // Prevent form submission
        const formData = new FormData(this);
        const jsonObject = {};

        // Convert FormData to JSON
        formData.forEach(function (value, key) {
            jsonObject[key] = value;
            // jsonObject[key] = formData.getAll(key);
            if (key.includes("localid-")) {
                jsonObject[key] = $('#' + key).val();
            }
        });

        // Convert JSON to string and display
        const jsonData = JSON.stringify(jsonObject);
        var formAction = $('.toplevel_page_deploy-sync-content #form-data-advanced-settings').attr("action");

        // Send the JSON data to PHP file for processing
        $.post(formAction, {payload: jsonData}, function (data, status) {
            // console.log("Data: " + data + "\nStatus: " + status);
            form.find('#submit-advanced-settings').removeAttr('disabled');
            form.removeClass('is-submitting');
        });
    });

    $('.toplevel_page_deploy-sync-content .multiselect-deploy-sync-content').select2?.({
        theme: "bootstrap-5",
        width: $(this).data('width') ? $(this).data('width') : $(this).hasClass('w-100') ? '100%' : 'style',
        placeholder: $(this).data('placeholder'),
        closeOnSelect: false
    });

	registerPostFormDataPreSubmitCallback( ( form, action, fetchInit ) => {
		// Disable the submit button.
		const submitButton = $( form ).find( "button[type=submit]" );
		submitButton.prop( "disabled", true );
		submitButton.addClass( ["in-progress"] );
	} );

	registerPostFormDataSubmittedCallback( ( form, action, fetchInit, response ) => {
		if ( "deploy-sync-content--merge" !== form.id
			&& "deploy-sync-content--export" !== form.id
			&& "deploy-sync-content--import" !== form.id ) {
			// Unlock the submit button when not on those forms.
			submitButton.removeClass( ["in-progress"] );
			submitButton.prop( "disabled", false );
			return;
		}

		// We are in a merge form, or the classic export or import form.
		if ( ! response.ok ) {
			// Keep the button locked if no error; a redirection or another callback may do something.
			submitButton.removeClass( ["in-progress"] );
			submitButton.prop( "disabled", false );
			throw new Error( "A network error occurred." );
		}
	} );

	registerPostFormDataSubmittedCallback( ( form, action, fetchInit, response ) => {
		if ( "deploy-sync-content--merge" !== form.id ) {
			return;
		}

		// We are in a merge form.
		if ( ! response.ok ) {
			return;
		}

		// Find the return button.
		const moveTo = $( form ).prev( "a[data-return]" ).attr( "href" );

		if ( moveTo ) {
			window.location.href = moveTo;
		} else {
			// If no return button is found, it's probably an embed mode, so we may close the container.
			window.parent.postMessage( "closeResolveModal", window.location.origin );
		}

		return true;
	} );

	registerPostFormDataSubmittedCallback( ( form, action, fetchInit, response ) => {
		if ( "deploy-sync-content--export" !== form.id
			&& "deploy-sync-content--import" !== form.id ) {
			return;
		}

		// We are in the classic export or import form.
		if ( ! response.ok ) {
			return;
		}

		if ( response.url === window.location.href ) {
			window.location.reload();
		} else {
			// Redirect to the URL where the backoffice wants us to be after submitting,
			// generally the bundle listing page for import/export, or the import batch page.
			window.location.href = response.url;
		}

		return true;
	} );
});

window.addEventListener("load", () => {
    const waitAndDisplay = async () => {
        // Wait 0.2s for CSS load.
        await new Promise(res => setTimeout(res, 200));

        // This class is used to prevent some flickering on load that display:none nor inline styling cannot prevent.
        document.querySelectorAll(".deploy-sync-content--invisible-during-load").forEach(item => {item.classList.remove("deploy-sync-content--invisible-during-load")});
    };

    waitAndDisplay();
});
