/*
 * NGBVD data-entry form fixes.
 * Scope: functional JavaScript only. No UI/UX layout or visual style changes.
 */
(function ($) {
    'use strict';

    if (!$) {
        return;
    }

    function getCsrfToken() {
        return $('meta[name="csrf-token"]').attr('content') || $('input[name="_token"]').first().val() || '';
    }

    function normaliseOptionsPayload(data) {
        if (!data) {
            return [];
        }

        if (Array.isArray(data)) {
            return data;
        }

        if (Array.isArray(data.data)) {
            return data.data;
        }

        if (Array.isArray(data.items)) {
            return data.items;
        }

        if (Array.isArray(data.results)) {
            return data.results;
        }

        return [];
    }

    function getOptionLabel(item) {
        return item.name || item.title || item.label || item.text || item.value || '';
    }

    function getOptionValue(item) {
        return item.id || item.uuid || item.value || '';
    }

    function hasSelectize($select) {
        return $select.length && $select[0] && $select[0].selectize;
    }

    function clearSelectize($select) {
        if (hasSelectize($select)) {
            var control = $select[0].selectize;
            control.clear(true);
            control.clearOptions();
            return control;
        }
        return null;
    }

    function setSelectOptions($select, items, placeholder, selectedValue) {
        var options = normaliseOptionsPayload(items);
        var required = $select.prop('required') || $select.attr('required') === 'required';
        var control = clearSelectize($select);

        if (control) {
            control.addOption({ value: '', text: placeholder || 'Choose One' });
            options.forEach(function (item) {
                var value = String(getOptionValue(item));
                if (value !== '') {
                    control.addOption({ value: value, text: getOptionLabel(item) });
                }
            });
            control.refreshOptions(false);

            if (selectedValue) {
                control.setValue(String(selectedValue), true);
            } else {
                control.clear(true);
            }
        } else {
            var html = '<option value="">' + (placeholder || 'Choose One') + '</option>';
            options.forEach(function (item) {
                var value = String(getOptionValue(item));
                var selected = selectedValue && String(selectedValue) === value ? ' selected' : '';
                html += '<option value="' + value + '"' + selected + '>' + getOptionLabel(item) + '</option>';
            });
            $select.html(html);
        }

        // If no categories exist for a selected status, do not let an empty required
        // drop-down silently block saving the survivor form.
        if (required && options.length === 0) {
            $select.prop('required', false).removeAttr('required').attr('data-required-suspended', 'true');
        } else if ($select.attr('data-required-suspended') === 'true') {
            $select.prop('required', true).attr('required', 'required').removeAttr('data-required-suspended');
        }

        return options.length;
    }

    function syncSurvivorCode() {
        var $reference = $('#crb_number');
        var $survivorCode = $('#survivor_code');

        if (!$reference.length || !$survivorCode.length) {
            return;
        }

        var value = ($reference.val() || '').trim();
        if (value !== '') {
            $survivorCode.val(value);
        }
    }

    function resolveNationalStatusCategorySelect($status) {
        var $container = $('#ns_category');
        var $select = $('#nstatuscategory, [name="ns_categornsy"]').first();

        if (!$select.length && $container.length) {
            $container.html(
                '<select class="form-control search-select" name="ns_categornsy" id="nstatuscategory" data-national-status-category="true" required>' +
                '<option value="">Choose One</option>' +
                '</select>'
            );
            $select = $('#nstatuscategory');
        }

        return $select;
    }

    function cascadeNationalStatusCategory(selectedValue) {
        var $status = $('#nstatus');
        var nstatusId = $status.val();
        var $category = resolveNationalStatusCategorySelect($status);

        if (!$status.length || !$category.length) {
            return;
        }

        if (!nstatusId) {
            setSelectOptions($category, [], 'Choose One', null);
            return;
        }

        $category.prop('disabled', true);

        $.ajax({
            type: 'GET',
            url: window.NGBVD_FIND_NS_CATEGORY_URL || '/findNSCategory',
            data: { id: nstatusId },
            headers: { 'X-CSRF-TOKEN': getCsrfToken() }
        }).done(function (data) {
            var selected = selectedValue || $category.attr('data-selected') || $category.val();
            setSelectOptions($category, data, 'Choose One', selected);
        }).fail(function () {
            // Keep the form saveable even if the lookup endpoint fails.
            setSelectOptions($category, [], 'Choose One', null);
        }).always(function () {
            $category.prop('disabled', false);
        });
    }

    function markSubmitter($button) {
        var $form = $button.closest('form');
        if (!$form.length) {
            return;
        }

        var $action = $form.find('input[name="action"], #action').first();
        if (!$action.length) {
            $action = $('<input>', { type: 'hidden', name: 'action', id: 'action' }).appendTo($form);
        }

        if ($button.is('[data-save-draft], .draftsave, .save-draft')) {
            $action.val('draft');
        } else if ($button.is('[data-submit-final], .submitfinal, .save-submit')) {
            $action.val('submit');
        } else if (!$action.val()) {
            $action.val('save');
        }

        var successUrl = $button.attr('successurl') || $button.data('successurl');
        if (successUrl) {
            var $success = $form.find('input[name="URL_SUCCESS"]').first();
            if ($success.length) {
                $success.val(successUrl);
            }
        }
    }

    function prepareFormForSubmit($form) {
        syncSurvivorCode();

        var $category = resolveNationalStatusCategorySelect($('#nstatus'));
        if ($category.length && (!$category.val()) && $category.find('option').length <= 1) {
            // Prevent required-but-unpopulated cascading fields from blocking save
            // when no categories are returned from the reference table.
            $category.prop('required', false).removeAttr('required').attr('data-required-suspended', 'true');
        }

        $form.find(':input:disabled[data-disabled-for-loading="true"]').prop('disabled', false).removeAttr('data-disabled-for-loading');
    }

    function boot() {
        $(document).on('input keyup change paste', '#crb_number', syncSurvivorCode);

        $(document).on('change', '#nstatus', function () {
            cascadeNationalStatusCategory(null);
        });

        $(document).on('click', 'button[type="submit"], input[type="submit"]', function () {
            markSubmitter($(this));
        });

        $(document).on('submit', 'form#indexform, form.ngbvd-form-section', function () {
            prepareFormForSubmit($(this));
            return true;
        });

        // Initial sync when the page opens in create or edit mode.
        syncSurvivorCode();

        var $status = $('#nstatus');
        var $category = $('#nstatuscategory, [name="ns_categornsy"]').first();
        if ($status.length && $status.val()) {
            var hasRealOptions = $category.find('option').filter(function () {
                return String($(this).val() || '') !== '';
            }).length > 0;

            // In create mode the category list is empty until the status is selected.
            // In edit mode, retain existing populated categories.
            if (!hasRealOptions) {
                cascadeNationalStatusCategory($category.attr('data-selected') || null);
            }
        }
    }

    $(document).ready(boot);
})(window.jQuery);
