<script>
  //* Global Variables
    // SAT Catalogs
    window.moral_tax_systems = @json($moral_tax_systems);
    window.physical_tax_systems = @json($physical_tax_systems);
    window.moral_cfdi_uses = @json($moral_cfdi_uses);
    window.physical_cfdi_uses = @json($physical_cfdi_uses);

    window.tax_objects = @json($tax_objects_catalog->pluck('label','item_key'));

    // Special Data
    window.tax_decrypt_data = "4ar51-e3067mnt-ba02-4cb2-95b1";
    window.conceptModalContext = { skipResetOnOpen: false, isEditing: false, lineNumber: "", allowDbStorage: false, lastAutoProdServKey: null };

    // Loader
    window.loader = window.loader || {
        show(text = translateAndReplace("common_responses_and_messages.loading")) {
            Swal.fire({
                title: text,
                html: '<p style="margin-top:0.5rem;">' + translateAndReplace("common_responses_and_messages.please_wait") + '</p>',
                allowOutsideClick: false,
                allowEscapeKey: false,
                backdrop: true,
                didOpen: () => {
                    Swal.showLoading();
                }
            });
        },
        hide() {
            if (Swal.isVisible()) Swal.close();
        }
    };

  //* Execute OnLoad
    $(document).ready(function () {
      //- Actions
        defineOptionalStates();

      //- Behavior
        // Scroll Table Control
        $('#concepts-table').on('scroll', function () {
            if ($(this).scrollTop() > 30) {
                $('#concepts-table-header').addClass('glass-background');
            } else {
                $('#concepts-table-header').removeClass('glass-background');
            }
        });

        $('#additional-docs-table').on('scroll', function () {
            if ($(this).scrollTop() > 30) {
                $('#additional-docs-table-header').addClass('glass-background');
            } else {
                $('#additional-docs-table-header').removeClass('glass-background');
            }
        });

        //- Save as Draft
        $('#save-as-draft').on('click', function(event){
          // Stop Propagation
            event.preventDefault();

          // Update Draft
            syncDraftData();
        });

        //- Preview Draft
        $('#preview-draft').on('click', function(event){
          // Stop Propagation
            event.preventDefault();

          // Validate Before Launch
            if (!validateFormAsDraft()) return;

          // Sync Form Data
            try {
              // Save Form Data
                syncDraftData(false);

              // Parse Data
                const form_data = parseFormData( $('#create_tax_invoice').serializeArray() );
                const data = parseInvoiceData(form_data);
                delete data.id;

              // Control Data
                // const preview_win = window.open('about:blank', '_blank');

              // AJAX
                $.ajax({
                    headers: {
                        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                    },
                    url: `{{ route('invoices.drafts.previewForm') }}`,
                    method: "POST",
                    data,
                    xhrFields: { responseType: 'blob' },

                    success: function (blob, _status, xhr) {
                        // Parse Data
                        const cd = xhr.getResponseHeader('Content-Disposition') || '';
                        const match = cd.match(/filename\*?=(?:UTF-8''|")?([^\";]+)/i);
                        const filename = match ? decodeURIComponent(match[1].replace(/"/g, '')) : 'preview.pdf';

                        const url = URL.createObjectURL(blob);

                        // Preview
                        // if (preview_win) preview_win.location = url; // Open pdf_page using URL
                        // else window.open(url, '_blank'); // Fallback (try again)

                        // Force Download on Open
                        const a = document.createElement('a');
                            a.href = url;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                            a.remove();

                        setTimeout(() => URL.revokeObjectURL(url), 60_000);
                    },
                    error: function (data) {
                        // Close pdf_page on error
                        // if (preview_win) preview_win.close();
                        const response = data.responseJSON;

                        if (response && response.errors) {
                            const errors = response.errors;
                            const onPreviewErrors = {};

                            // Define error types
                            Object.keys(errors).forEach((key) => {
                                if (key.startsWith('on_save')) { // If it's an error occurred on parsing data
                                    onPreviewErrors[key] = errors[key]; // Group as OnPreview Errors
                                } else {
                                    errors[key].forEach(message => showToast(message, "#C34808", "#78350F")); // Display as Validation Error
                                }
                            });

                            Object.keys(onPreviewErrors).forEach(key => { // Display as OnPreview Errors
                                onPreviewErrors[key].forEach(message => showToast(message, "#C34808", "#78350F"));
                            });

                        } else {
                            showToast('No se pudo generar el PDF de vista previa.', "#C34808", "#78350F");
                        }
                    }
                });
            } catch (error) {
                showToast('No se pudo generar el PDF de vista previa.', "#C34808", "#78350F");
            }
        });

        //- Main Form Submit
        $('#create_tax_invoice').on('submit', function(event){
          // Validate Form
            event.preventDefault();
                if (!validateForm()) return;

            window.loader.show(translateAndReplace("common_responses_and_messages.saving_data"));

          // Parse Data
            const form_data = parseFormData( $(this).serializeArray() );
            const data = parseInvoiceData(form_data);

          // AJAX
            const draft_origin = !['', null, undefined].includes(data.id);
            const draft_id = draft_origin ? `/${data.id}` : '';
            delete data.id;

          // AJAX
            $.ajax({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                url: `/invoicing/invoices/certify${draft_id}`,
                method: "POST",
                data,

                success: function (data) {
                  // Toggle Loader status
                    window.loader.hide()

                  // Messages
                    launchSwalToast(
                        'success',
                        data.success,
                    );

                    setTimeout(() => {
                        window.open(`/invoicing/invoices/${data.invoice_id}`, '_blank');
                        window.location.href = "{{ route('invoices.index') }}";
                    }, 1000);
                },

                error: function(data){
                    // Toggle Loader status
                    window.loader.hide()

                    // Extract Data
                    const response = data.responseJSON;

                    // Record limit reached
                    if (response.limit_message) {
                        Swal.fire({
                            title: "{{ __('common_responses_and_messages')['rejected_action'] }}",
                            html: response.limit_message,
                            icon:'error'
                        });

                        return;
                    }

                    // OnSave/Validator Errors
                    const onSaveErrors = {};

                        // Define error types
                        if(response?.errors && typeof response?.errors === 'object'){
                            const errors = response.errors;
                            Object.keys(errors).forEach((key) => {
                                if (key.startsWith('on_save')) { // If it's an error occurred on save data
                                    onSaveErrors[key] = errors[key]; // Group as OnSave Error
                                } else {
                                    errors[key].forEach(message => showToast(message, "#C34808", "#78350F")); // Display as Validation Error
                                }
                            });
                        }else if(response?.message){
                            showToast(response.message, "#C34808", "#78350F" );
                        }else{
                            showToast("{{ __('common_responses_and_messages')['data_not_loaded'] }}", "#C34808", "#78350F");
                        }
                        

                        Object.keys(onSaveErrors).forEach(key => { // Display as OnSave Errors
                            onSaveErrors[key].forEach(message => showToast(message, "#C34808", "#78350F"));
                        });

                    return;
                },
            });

        });
    });

  //* Complementary
    // Individual Input
    function defineOptionalStates() {
        if (getCountrySettings() !== "MEX") {
            $('#tx-mx-states, #receiver-mx-states').html("");
            return;
        }

        // Only México States for now
        const tax_mx_states = [
            "Aguascalientes",
            "Baja California",
            "Baja California Sur",
            "Campeche",
            "Chiapas",
            "Chihuahua",
            "Ciudad de México",
            "Coahuila de Zaragoza",
            "Colima",
            "Durango",
            "Guanajuato",
            "Guerrero",
            "Hidalgo",
            "Jalisco",
            "México",
            "Michoacán de Ocampo",
            "Morelos",
            "Nayarit",
            "Nuevo León",
            "Oaxaca",
            "Puebla",
            "Querétaro",
            "Quintana Roo",
            "San Luis Potosí",
            "Sinaloa",
            "Sonora",
            "Tabasco",
            "Tamaulipas",
            "Tlaxcala",
            "Veracruz de Ignacio de la Llave",
            "Yucatán",
            "Zacatecas",
        ];

        let state_options = "";
        tax_mx_states.forEach(state => {
            state_options += `<option value="${state}"></option>`;
        });
        $('#tx-mx-states, #receiver-mx-states').html(state_options);
    }

    // General Forms
    function validateFormAsDraft () {
      // Validate External Inputs
        const $date = $('#date');
        const invoice_date = moment($date.val(), "YYYY-MM-DDTHH:mm:ss").startOf('minute');
        const seventy_two_hours_ago = moment().startOf('minute').subtract(72, 'hours');

        if (invoice_date.isBefore(seventy_two_hours_ago )) {
            showToast("No puedes generar facturas con fecha mayor a 3 días atrás.", "#C34808", "#78350F");
            $date[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
            $date.focus();
            return false
        } else if (invoice_date.isAfter(moment())) {
            showToast("No puedes generar facturas para fechas u horas futuras.", "#C34808", "#78350F");
            $date[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
            $date.focus();
            return false
        }

      // Validate Receivers Section
        const {receiver_valid, show_receiver_error, receiver_error_message} = validateReceiverSection();
            if (!receiver_valid) {
                if (show_receiver_error) showToast(receiver_error_message, "#C34808", "#78350F");
                return false
            }

      // Validate Global/Generic Section
        const {
            section_valid: generic_section_valid,
            show_error_detected: show_generic_error_detected,
            section_error_message: generic_error_message
        } = sharedSectionValidator('global-form');

            if (!generic_section_valid) {
                if (show_generic_error_detected) showToast(generic_error_message, "#C34808", "#78350F");
                return false;
            }

      // Validate Issuer Section
        const {
            section_valid: issuer_section_valid,
            show_error_detected: issuer_error_detected,
            section_error_message: issuer_error_message
        } = sharedSectionValidator('issuer-form');

            if (!issuer_section_valid) {
                if (issuer_error_detected) showToast(issuer_error_message, "#C34808", "#78350F");
                return false;
            }

      // Validate Concepts Section
        const {concepts_valid, show_concepts_error, concepts_error_message} = validateConceptsSection();
            if (!concepts_valid) {
                if (show_concepts_error) showToast(concepts_error_message, "#C34808", "#78350F");
                return false
            }

      // Validate Additional Docs Section
        const {docs_valid, show_docs_error, docs_error_message} = validateAdditionalDocsSection();
            if (!docs_valid) {
                if (show_docs_error) showToast(docs_error_message, "#C34808", "#78350F");
                return false
            }

        return true;
    }

    function validateForm () {
      // Validate External Inputs
        const $date = $('#date');
        const invoice_date = moment($date.val(), "YYYY-MM-DDTHH:mm:ss").startOf('minute');
        const seventy_two_hours_ago = moment().startOf('minute').subtract(72, 'hours');

        if (invoice_date.isBefore(seventy_two_hours_ago )) {
            showToast("No puedes generar facturas con fecha mayor a 3 días atrás.", "#C34808", "#78350F");
            $date[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
            $date.focus();
            return false
        } else if (invoice_date.isAfter(moment())) {
            showToast("No puedes generar facturas para fechas u horas futuras.", "#C34808", "#78350F");
            $date[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
            $date.focus();
            return false
        }

      // Validate Receivers Section
        const {receiver_valid, show_receiver_error, receiver_error_message} = validateReceiverSection();
            if (!receiver_valid) {
                if (show_receiver_error) showToast(receiver_error_message, "#C34808", "#78350F");
                return false
            }

      // Validate Global/Generic Section
        const {
            section_valid: generic_section_valid,
            show_error_detected: show_generic_error_detected,
            section_error_message: generic_error_message
        } = sharedSectionValidator('global-form');

            if (!generic_section_valid) {
                if (show_generic_error_detected) showToast(generic_error_message, "#C34808", "#78350F");
                return false;
            }

      // Validate Issuer Section
        const {
            section_valid: issuer_section_valid,
            show_error_detected: issuer_error_detected,
            section_error_message: issuer_error_message
        } = sharedSectionValidator('issuer-form');

            if (!issuer_section_valid) {
                if (issuer_error_detected) showToast(issuer_error_message, "#C34808", "#78350F");
                return false;
            }

      // Validate Concepts Section
        const {concepts_valid, show_concepts_error, concepts_error_message} = validateConceptsSection(true);
            if (!concepts_valid) {
                if (show_concepts_error) showToast(concepts_error_message, "#C34808", "#78350F");
                return false
            }

      // Validate Additional Docs Section
        const {docs_valid, show_docs_error, docs_error_message} = validateAdditionalDocsSection();
            if (!docs_valid) {
                if (show_docs_error) showToast(docs_error_message, "#C34808", "#78350F");
                return false
            }

        return true;
    }

    // Form Actions
    function syncDraftData(save_and_leave = true) {
      // Validate as Draft
        if (!validateFormAsDraft()) return;

      // Parse Data
        const form_data = parseFormData( $('#create_tax_invoice').serializeArray() );
        const data = parseInvoiceData(form_data);

      // AJAX
        const is_editing = !['', null, undefined].includes(data.id);
        const draft_id = is_editing ? `/${data.id}` : '';
        delete data.id;

        $.ajax({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            url: `/invoicing/draft-invoices/upsert${draft_id}`,
            method: "POST",
            data,

            success: function (data) {
                // Messages
                launchSwalToast(
                    'success',
                    translateAndReplace(`common_responses_and_messages.${
                        !save_and_leave
                            ? 'updating_data'
                            : is_editing ? 'updated_successfully': 'saved_successfully'
                    }`),
                );

                // Actions
                if (save_and_leave) { // Save draft and leave
                    setTimeout(() => {
                        window.location.href = "{{ route('invoices.index') }}";
                    }, 2000);
                } else { // Save draft and Set invoice ID
                    const is_empty_draft = ['', null, undefined].includes( $('#hidden_id').val() );

                    if (is_empty_draft) {
                        $('#hidden_id_block').show()
                        $('#hidden_id, #illusionary_id').val(data.invoice_id)
                    }
                }
            },

            error: function(data){
                const response = data.responseJSON;

                // OnSave/Validator Errors
                if(response.errors){
                    const errors = response.errors;
                    const onSaveErrors = {};

                    // Define error types
                    Object.keys(errors).forEach((key) => {
                        if (key.startsWith('on_save')) { // If it's an error occurred on save data
                            onSaveErrors[key] = errors[key]; // Group as OnSave Error
                        } else {
                            errors[key].forEach(message => showToast(message, "#C34808", "#78350F")); // Display as Validation Error
                        }
                    });

                    Object.keys(onSaveErrors).forEach(key => { // Display as OnSave Errors
                        onSaveErrors[key].forEach(message => showToast(message, "#C34808", "#78350F"));
                    });
                }else if(response.message){
                    showToast(response.message, "#C34808", "#78350F")
                }else{
                    showToast("{{ __('common_responses_and_messages')['data_not_loaded'] }}", "#C34808", "#78350F");
                }
                
                return;
            },
        });

    }

    // Forms Helpers
    function parseInvoiceData(data) {
      // Receiver
        const receiver_data = [null, ""].includes(data.client_id)
            ? {}
            : {
                receiver: {
                    id: data.client_id,
                    is_moral_person: data.is_moral_person === 'on',
                    tax_identifier: data.tax_identifier,
                    legal_name: data.legal_name,
                    tax_system: data.tax_system,
                    email: data.email_billing,
                    phone: data.phone_billing,
                    zip: data.individual_zip,

                    address: {
                        street : data.individual_street,
                        int_number : data.individual_int_number,
                        ext_number : data.individual_ext_number,
                        neighborhood : data.individual_neighborhood,
                        city : data.individual_city,
                        municipality : data.individual_municipality,
                        state : data.individual_state,
                        country : data.individual_country,
                    },
                },
            }

      // Global/Generic Data
        const global_data = !["XAXX010101000"].includes(data?.tax_identifier)
            ? {}
            : {
                global: {
                    periodicity: data.periodicity,
                    months: data.months,
                    year: data.year,
                }
            }


      // Issuer
        const exchange_rate = data.currency === "MXN" ? "1.00" : data.exchange_rate;
        const is_deferred_invoice = data.payment_method === "PPD";
        const payment_form = is_deferred_invoice ? "99" : data.payment_form;

        const credit_env = is_deferred_invoice ? {credit_days: data.credit_days, due_date: data.due_date} : {};

      // Item Summary
        const items_summary = [];
        (data.concept_summary ?? []).forEach(function (e, index) {
            const byte_data = CryptoJS.AES.decrypt(e, window.tax_decrypt_data);
            const decrypt_data = byte_data.toString(CryptoJS.enc.Utf8) || "{}";

            const parsed =  parseInvoiceItemData(JSON.parse(decrypt_data), data.line_numbers[index]);
            items_summary.push(parsed);
        });

      // Additional Docs
        const { doc_relation_types = [], doc_uuids = [], doc_descriptions = [] } = data;
        const additional_docs = doc_uuids.map((uuid, i) => ({
            uuid,
            relation_type: doc_relation_types[i],
            description: doc_descriptions[i] ?? "",
        }));

      // Parse Data
        return {
            id: data.hidden_id,
            date: data.date,
            system_service: {
                type: data.system_service_type,
                id: data.system_service_id
            },

            ...receiver_data,
            ...global_data,

            tax_branch_id: data.tax_branch_id,
            cfdi_use: data.cfdi_use,
            invoice_type: data.invoice_type,
            currency: data.currency,
            exchange_rate,
            export: data.export,
            payment_method: data.payment_method,
            payment_form,
            ...credit_env,
            notes: data.notes ?? translateAndReplace('neutral_words.none'),

            items_summary,
            subtotal: data.invoice_subtotal,
            total: data.invoice_total,

            additional_docs,
            tax_format_id: data.tax_format_id,
        };
    }

    function parseInvoiceItemData(data, line_number = "") {
      // Federal Taxes
        const {
            tax_summary = [],
            tax_application_summary = [],
            rate_quotes_summary = [],
            tax_charges_summary = []
        } = data;

        const taxes = ['01', '03'].includes(data.concept_object_tax)
            ? []
            : tax_summary.map((tax, i) => ({
                tax,
                tax_application: tax_application_summary[i],
                rate_quote: rate_quotes_summary[i],
                charges: tax_charges_summary[i],
            }));

      // Local Taxes
        const {
            local_tax_names_summary = [],
            local_tax_application_summary = [],
            local_rate_quotes_summary = [],
            local_tax_charges_summary = []
        } = data;

        const local_taxes = local_tax_names_summary.map((name, i) => ({
            name,
            tax_application: local_tax_application_summary[i],
            rate_quote: local_rate_quotes_summary[i],
            charges: local_tax_charges_summary[i],
        }));

      // Parse Data
        return {
            line_number,
            prod_serv_id: data.concept_prod_serv_id,
            name: data.concept_name,

            prod_serv_key: data.concept_prod_serv_key,
            sat_description: data.concept_sat_description,
            object_tax: data.concept_object_tax,
            unit_key: data.concept_unit_key,
            unit_price: data.concept_unit_price,
            quantity: data.concept_quantity,
            subtotal: data.subtotal,

            discount_type: data.discount_format,
            discount_value: data.concept_discount,
            discount_total: data.concept_discount_rate,
            description: data.concept_description ?? translateAndReplace('neutral_words.none'),

            taxes,
            local_taxes,

            third_account_data: {
                tax_identifier: data.third_account_tax_identifier ?? "",
                legal_name: data.third_account_legal_name ?? "",
                tax_system: data.third_account_tax_system ?? "",
                zip: data.third_account_zip ?? "",
            },
            property_tax_account: data.concept_property_tax_account,

            total: data.total,
        }
    }

    // Specific Form Sections
    function sharedSectionValidator(section_id) {
        const $section = $(`#${section_id}`);

        let is_valid = true;
        let section_error_message = "";
        let first_invalid = null;

        // Check not disabled inputs
        $section.find('input, select, textarea')
        .filter(':not(:disabled):not([type="hidden"])')
        .each(function () {
            const el = this;

            // Limpia estados previos
            el.setCustomValidity && el.setCustomValidity('');
            $(el).removeClass('is-invalid');

            // Pequeño trim en campos de texto/email/tel para evitar espacios accidentales
            if ($(el).is('input[type="text"], input[type="email"], input[type="tel"]'))
                el.value = el.value.trim();

            // Usa validación nativa HTML5
            if (!el.checkValidity()) {
                is_valid = false;
                first_invalid = el;

                if (el.validity.patternMismatch && el.title)
                    section_error_message = el.title;
                else
                    section_error_message = el.validationMessage;

                $(el).addClass('is-invalid');
                return false;
            }
        });

        // Report Errors
        if (!is_valid && first_invalid) {
            const $accordion = $(first_invalid).closest('.accordion-collapse.collapse');
                if ($accordion.length) $accordion.collapse('show');

            first_invalid.scrollIntoView({ behavior: 'smooth', block: 'center' });
            first_invalid.focus({ preventScroll: true });
            first_invalid.reportValidity();
        }

        // Return validations
        return {section_valid: is_valid, show_error_detected: true, section_error_message};
    }

    function validateReceiverSection() {
        const $section = $('#receiver-form');

        let is_valid = true;
        let receiver_error_message = "";
        let first_invalid = null;

        // Ensure receiver have been selected
        if (!$section.is(':visible') && !$('#client_id').val()) {
            restoreReceiverSection();
            $('#receiver-unique').collapse('show');
            $('html, body').animate({
                scrollTop: $section.offset().top - ($(window).height() / 2) + ($section.height() / 2)
            }, 600);

            receiver_error_message = "Debes seleccionar/registrar un receptor.";
            return {receiver_valid: false, show_receiver_error: true, receiver_error_message};
        }

        // Check not disabled inputs
        $section.find('input, select, textarea')
        .filter(':not(:disabled):not([type="hidden"])')
        .each(function () {
            const el = this;

            // Limpia estados previos
            el.setCustomValidity && el.setCustomValidity('');
            $(el).removeClass('is-invalid');

            // Pequeño trim en campos de texto/email/tel para evitar espacios accidentales
            if ($(el).is('input[type="text"], input[type="email"], input[type="tel"]'))
                el.value = el.value.trim();

            // Usa validación nativa HTML5
            if (!el.checkValidity()) {
                is_valid = false;
                first_invalid = el;

                if (el.validity.patternMismatch && el.title)
                    receiver_error_message = el.title;
                else
                    receiver_error_message = el.validationMessage;

                $(el).addClass('is-invalid');
                return false;
            }
        });

        // Report Errors
        if (!is_valid && first_invalid) {
            const $accordion = $(first_invalid).closest('.accordion-collapse.collapse');
                if ($accordion.length) $accordion.collapse('show');

            first_invalid.scrollIntoView({ behavior: 'smooth', block: 'center' });
            first_invalid.focus({ preventScroll: true });
            first_invalid.reportValidity();
        }

        // Return validations
        return {receiver_valid: is_valid, show_receiver_error: true, receiver_error_message};
    }

    function validateConceptsSection(require_concepts = false) {
      //* Control Data
        // Structures
        const $concept_table_records = $('#concepts-table-body');
        const $firstTd = $concept_table_records.find('tr:first').find('td:first');

        const rowCount = $firstTd.length && $firstTd.attr('colspan')
            ? 0 // Case: No Concepts Registered
            : $concept_table_records.find("tr").length;

        const $concept_summaries  = $concept_table_records.find('input[name="concept_summary[]"]');

        // Control Variables
        let is_valid = true;
        let concepts_error_message = "";

        if (require_concepts && rowCount === 0) {
            is_valid = false;
            concepts_error_message = "Debes registrar al menos un concepto para continuar.";
        }

        if ($concept_summaries.length !== rowCount) {
            is_valid = false;
            concepts_error_message = "Alteración de Campos Detectada";
        }

        // Validación secundaria de Tipos de Relación
        if (is_valid) {
            $concept_summaries.each(function(i, el) {
                const val = (el.value || "");
                const byte_data = CryptoJS.AES.decrypt(val, window.tax_decrypt_data);
                const data = byte_data.toString(CryptoJS.enc.Utf8) || "{}";

                if (!isValidJson(data)) {
                    concepts_error_message = `El concepto #${i+1} ha sido alterado sin autorización`;
                    is_valid = false;

                    const $row = el.closest('tr');
                    $row[0]?.focus({ preventScroll: true });

                    return false;
                }
            });
        }

        return {concepts_valid: is_valid, show_concepts_error: true, concepts_error_message};
    }

    function validateAdditionalDocsSection() {
      //* Control Data
        // Structures
        const $docs_table_records = $('#additional-docs-table-body');
        const $firstTd = $docs_table_records.find('tr:first').find('td:first');

        const rowCount = $firstTd.length && $firstTd.attr('colspan')
            ? 0 // Case: No Docs Registered
            : $docs_table_records.find("tr").length;

        const $doc_relations  = $docs_table_records.find('input[name="doc_relation_types[]"]');
        const $doc_uuids = $docs_table_records.find('input[name="doc_uuids[]"]');
        const $doc_descriptions = $docs_table_records.find('input[name="doc_descriptions[]"]');

        // Control Variables
        const valid_relations = @json($document_relations->pluck('item_key'));
        const uuid_regex = /^[A-Fa-f0-9\-]{36}$/;

        let is_valid = true;
        let docs_error_message = "";

        if ($doc_relations.length !== rowCount || $doc_uuids.length !== rowCount || $doc_descriptions.length !== rowCount) {
            is_valid = false;
            docs_error_message = "Alteración de Campos Detectada";
        }

        // Validación secundaria de Tipos de Relación
        if (is_valid) {
            $doc_relations.each(function(i, el) {
                const val = (el.value || "").trim();

                if (!valid_relations.includes(val)) {
                    docs_error_message = `El documento #${i+1} no cuenta con un Tipo de Relación válido`;
                    is_valid = false;

                    const $row = el.closest('tr');
                    $row[0]?.focus({ preventScroll: true });

                    return false;
                }
            });
        }

        // Validación secundaria de UUIDs
        if (is_valid) {
            $doc_uuids.each(function(i, el) {
                const val = (el.value || "").trim();

                if (!uuid_regex.test(val)) {
                    docs_error_message = `El documento #${i+1} no cuenta con un UUID válido`;
                    is_valid = false;

                    const $row = el.closest('tr');
                    $row[0]?.focus({ preventScroll: true });

                    return false;
                }
            });
        }

        // If section is invalid display accordion
        if(!is_valid) {
            const $accordion = $docs_table_records.closest('.accordion-collapse.collapse');
                if ($accordion.length) $accordion.collapse('show');

            $docs_table_records[0]?.scrollIntoView({ behavior: 'smooth', block: 'center' });
            $docs_table_records[0]?.focus({ preventScroll: true });
        }

        return {docs_valid: is_valid, show_docs_error: true, docs_error_message};
    }

    // Special Validators
    function isValidJson(str) {
        if (typeof str !== 'string') return false;

        const trimmed = str.trim();
            if (!trimmed) return false;

        try {
            const data = JSON.parse(trimmed);

            if (data === null || typeof data !== 'object' || Array.isArray(data))
                return false;

            return true;
        } catch (e) {
            return false;
        }
    }

</script>
