'use strict';

/**
 * Entity Management Module
 *
 * Handles CRUD operations for entity addresses, contacts, and documents
 * using offcanvas forms with AJAX submissions.
 *
 * Usage:
 *   EntityManager.init({
 *       entityType: 'customer',
 *       entityId: 123,
 *       urls: {
 *           addresses: { store: '...', show: '...', update: '...', destroy: '...', setPrimary: '...' },
 *           contacts: { store: '...', show: '...', update: '...', destroy: '...', setPrimary: '...' },
 *           documents: { store: '...', show: '...', update: '...', destroy: '...', download: '...' }
 *       },
 *       labels: { ... }
 *   });
 */
(function(window, $) {
    'use strict';

    // Module configuration
    let config = {
        entityType: null,
        entityId: null,
        urls: {
            addresses: {},
            contacts: {},
            documents: {}
        },
        labels: {}
    };

    // Bootstrap Offcanvas instances
    let addressOffcanvas = null;
    let contactOffcanvas = null;
    let documentOffcanvas = null;

    // Flatpickr instances
    let flatpickrInstances = {};

    /**
     * Initialize the Entity Manager
     * @param {Object} options - Configuration options
     */
    function init(options) {
        // Merge options with defaults
        config = $.extend(true, {}, config, options);

        // Setup CSRF token for all AJAX requests
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        // Initialize offcanvas instances
        initOffcanvas();

        // Initialize Flatpickr date pickers
        initFlatpickr();

        // Bind form submission handlers
        bindFormHandlers();

        // Bind offcanvas reset on close
        bindOffcanvasReset();
    }

    /**
     * Initialize Bootstrap Offcanvas instances
     */
    function initOffcanvas() {
        const addressOffcanvasEl = document.getElementById('addressOffcanvas');
        const contactOffcanvasEl = document.getElementById('contactOffcanvas');
        const documentOffcanvasEl = document.getElementById('documentOffcanvas');

        if (addressOffcanvasEl) {
            addressOffcanvas = new bootstrap.Offcanvas(addressOffcanvasEl);
        }

        if (contactOffcanvasEl) {
            contactOffcanvas = new bootstrap.Offcanvas(contactOffcanvasEl);
        }

        if (documentOffcanvasEl) {
            documentOffcanvas = new bootstrap.Offcanvas(documentOffcanvasEl);
        }
    }

    /**
     * Initialize Flatpickr date pickers
     */
    function initFlatpickr() {
        // Contact birthday field
        const birthdayInput = document.getElementById('contact_birthday');
        if (birthdayInput && typeof flatpickr !== 'undefined') {
            flatpickrInstances.contactBirthday = flatpickr(birthdayInput, {
                dateFormat: 'Y-m-d',
                altInput: true,
                altFormat: 'M j, Y',
                allowInput: true
            });
        }

        // Document expiry date field
        const expiryDateInput = document.getElementById('document_expiry_date');
        if (expiryDateInput && typeof flatpickr !== 'undefined') {
            flatpickrInstances.documentExpiry = flatpickr(expiryDateInput, {
                dateFormat: 'Y-m-d',
                altInput: true,
                altFormat: 'M j, Y',
                allowInput: true,
                minDate: 'today'
            });
        }

        // Document issue date field
        const issueDateInput = document.getElementById('document_issue_date');
        if (issueDateInput && typeof flatpickr !== 'undefined') {
            flatpickrInstances.documentIssue = flatpickr(issueDateInput, {
                dateFormat: 'Y-m-d',
                altInput: true,
                altFormat: 'M j, Y',
                allowInput: true
            });
        }
    }

    /**
     * Bind form submission handlers
     */
    function bindFormHandlers() {
        // Address form
        const addressForm = $('#addressForm');
        if (addressForm.length) {
            addressForm.on('submit', function(e) {
                e.preventDefault();
                handleAddressSubmit();
            });
        }

        // Contact form
        const contactForm = $('#contactForm');
        if (contactForm.length) {
            contactForm.on('submit', function(e) {
                e.preventDefault();
                handleContactSubmit();
            });
        }

        // Document form
        const documentForm = $('#documentForm');
        if (documentForm.length) {
            documentForm.on('submit', function(e) {
                e.preventDefault();
                handleDocumentSubmit();
            });
        }
    }

    /**
     * Bind offcanvas reset events
     */
    function bindOffcanvasReset() {
        $('#addressOffcanvas').on('hidden.bs.offcanvas', function() {
            resetAddressForm();
        });

        $('#contactOffcanvas').on('hidden.bs.offcanvas', function() {
            resetContactForm();
        });

        $('#documentOffcanvas').on('hidden.bs.offcanvas', function() {
            resetDocumentForm();
        });
    }

    // =========================================================================
    // ADDRESS FUNCTIONS
    // =========================================================================

    /**
     * Open address offcanvas for add/edit
     * @param {number|null} id - Address ID for edit, null for create
     */
    function openAddressOffcanvas(id) {
        resetAddressForm();

        if (id) {
            // Edit mode - load address data
            $('#addressOffcanvasLabel').text(config.labels.editAddress || 'Edit Address');
            loadAddress(id);
        } else {
            // Create mode
            $('#addressOffcanvasLabel').text(config.labels.addAddress || 'Add Address');
        }

        addressOffcanvas?.show();
    }

    /**
     * Load address data for editing
     * @param {number} id - Address ID
     */
    function loadAddress(id) {
        const url = config.urls.addresses.show?.replace(':id', id);
        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        setButtonLoading('#submitAddressBtn', true);

        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'json',
            success: function(response) {
                if (response.success && response.data) {
                    const data = response.data;
                    $('#address_id').val(data.id);
                    $('#address_type').val(data.address_type || '').trigger('change');
                    $('#address_label').val(data.label || '');
                    $('#address_line_1').val(data.address_line_1 || '');
                    $('#address_line_2').val(data.address_line_2 || '');
                    $('#address_city').val(data.city || '');
                    $('#address_state').val(data.state || '');
                    $('#address_postal_code').val(data.postal_code || '');
                    $('#address_country').val(data.country || '').trigger('change');
                    $('#address_is_primary').prop('checked', data.is_primary || false);
                    $('#address_is_billing').prop('checked', data.is_billing || false);
                    $('#address_is_shipping').prop('checked', data.is_shipping || false);
                    $('#address_notes').val(data.notes || '');
                } else {
                    showError(response.message || config.labels.loadError || 'Failed to load address');
                    addressOffcanvas?.hide();
                }
            },
            error: function(xhr) {
                showError(xhr.responseJSON?.message || config.labels.loadError || 'Failed to load address');
                addressOffcanvas?.hide();
            },
            complete: function() {
                setButtonLoading('#submitAddressBtn', false);
            }
        });
    }

    /**
     * Handle address form submission
     */
    function handleAddressSubmit() {
        clearValidationErrors('#addressForm');

        const addressId = $('#address_id').val();
        const isUpdate = !!addressId;
        const url = isUpdate
            ? config.urls.addresses.update?.replace(':id', addressId)
            : config.urls.addresses.store;

        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        const formData = new FormData($('#addressForm')[0]);

        // Handle checkbox value
        const isPrimary = $('#address_is_primary').is(':checked');
        formData.delete('is_primary');
        formData.append('is_primary', isPrimary ? '1' : '0');

        if (isUpdate) {
            formData.append('_method', 'PUT');
        }

        setButtonLoading('#submitAddressBtn', true);

        $.ajax({
            url: url,
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    addressOffcanvas?.hide();
                    showSuccess(response.message || config.labels.addressSaved || 'Address saved successfully');
                    reloadPage();
                } else {
                    showError(response.message || config.labels.saveError || 'Failed to save address');
                }
            },
            error: function(xhr) {
                handleValidationErrors(xhr, '#addressForm');
            },
            complete: function() {
                setButtonLoading('#submitAddressBtn', false);
            }
        });
    }

    /**
     * Reset address form
     */
    function resetAddressForm() {
        const form = $('#addressForm');
        if (form.length) {
            form[0].reset();
            $('#address_id').val('');
            clearValidationErrors('#addressForm');

            // Reset Select2 fields
            $('#address_type').val('').trigger('change');
            $('#address_country').val('').trigger('change');
        }
    }

    /**
     * Delete address with confirmation
     * @param {number} id - Address ID
     */
    function deleteAddress(id) {
        Swal.fire({
            title: config.labels.confirmDelete || 'Are you sure?',
            text: config.labels.deleteAddressWarning || 'This address will be permanently deleted.',
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: config.labels.yesDelete || 'Yes, delete it!',
            cancelButtonText: config.labels.cancel || 'Cancel',
            customClass: {
                confirmButton: 'btn btn-danger me-3',
                cancelButton: 'btn btn-label-secondary'
            },
            buttonsStyling: false
        }).then(function(result) {
            if (result.isConfirmed) {
                const url = config.urls.addresses.destroy?.replace(':id', id);
                if (!url) {
                    showError(config.labels.urlNotConfigured || 'URL not configured');
                    return;
                }

                $.ajax({
                    url: url,
                    type: 'POST',
                    data: { _method: 'DELETE' },
                    dataType: 'json',
                    success: function(response) {
                        if (response.success) {
                            showSuccess(response.message || config.labels.addressDeleted || 'Address deleted successfully');
                            reloadPage();
                        } else {
                            showError(response.message || config.labels.deleteError || 'Failed to delete address');
                        }
                    },
                    error: function(xhr) {
                        showError(xhr.responseJSON?.message || config.labels.deleteError || 'Failed to delete address');
                    }
                });
            }
        });
    }

    /**
     * Set address as primary
     * @param {number} id - Address ID
     */
    function setPrimaryAddress(id) {
        const url = config.urls.addresses.setPrimary?.replace(':id', id);
        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        $.ajax({
            url: url,
            type: 'POST',
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    showSuccess(response.message || config.labels.primaryAddressSet || 'Primary address updated');
                    reloadPage();
                } else {
                    showError(response.message || config.labels.error || 'Failed to set primary address');
                }
            },
            error: function(xhr) {
                showError(xhr.responseJSON?.message || config.labels.error || 'Failed to set primary address');
            }
        });
    }

    // =========================================================================
    // CONTACT FUNCTIONS
    // =========================================================================

    /**
     * Open contact offcanvas for add/edit
     * @param {number|null} id - Contact ID for edit, null for create
     */
    function openContactOffcanvas(id) {
        resetContactForm();

        if (id) {
            // Edit mode - load contact data
            $('#contactOffcanvasLabel').text(config.labels.editContact || 'Edit Contact');
            loadContact(id);
        } else {
            // Create mode
            $('#contactOffcanvasLabel').text(config.labels.addContact || 'Add Contact');
        }

        contactOffcanvas?.show();
    }

    /**
     * Load contact data for editing
     * @param {number} id - Contact ID
     */
    function loadContact(id) {
        const url = config.urls.contacts.show?.replace(':id', id);
        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        setButtonLoading('#submitContactBtn', true);

        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'json',
            success: function(response) {
                if (response.success && response.data) {
                    const data = response.data;
                    $('#contact_id').val(data.id);
                    $('#contact_type').val(data.contact_type || '').trigger('change');
                    $('#contact_first_name').val(data.first_name || '');
                    $('#contact_last_name').val(data.last_name || '');
                    $('#contact_job_title').val(data.job_title || '');
                    $('#contact_department').val(data.department || '');
                    $('#contact_email').val(data.email || '');
                    $('#contact_phone').val(data.phone || '');
                    $('#contact_mobile').val(data.mobile || '');
                    $('#contact_fax').val(data.fax || '');

                    // Set birthday using Flatpickr
                    if (flatpickrInstances.contactBirthday && data.birthday) {
                        flatpickrInstances.contactBirthday.setDate(data.birthday, true);
                    }

                    $('#contact_is_primary').prop('checked', data.is_primary || false);
                    $('#contact_notes').val(data.notes || '');
                } else {
                    showError(response.message || config.labels.loadError || 'Failed to load contact');
                    contactOffcanvas?.hide();
                }
            },
            error: function(xhr) {
                showError(xhr.responseJSON?.message || config.labels.loadError || 'Failed to load contact');
                contactOffcanvas?.hide();
            },
            complete: function() {
                setButtonLoading('#submitContactBtn', false);
            }
        });
    }

    /**
     * Handle contact form submission
     */
    function handleContactSubmit() {
        clearValidationErrors('#contactForm');

        const contactId = $('#contact_id').val();
        const isUpdate = !!contactId;
        const url = isUpdate
            ? config.urls.contacts.update?.replace(':id', contactId)
            : config.urls.contacts.store;

        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        const formData = new FormData($('#contactForm')[0]);

        // Handle checkbox value
        const isPrimary = $('#contact_is_primary').is(':checked');
        formData.delete('is_primary');
        formData.append('is_primary', isPrimary ? '1' : '0');

        if (isUpdate) {
            formData.append('_method', 'PUT');
        }

        setButtonLoading('#submitContactBtn', true);

        $.ajax({
            url: url,
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    contactOffcanvas?.hide();
                    showSuccess(response.message || config.labels.contactSaved || 'Contact saved successfully');
                    reloadPage();
                } else {
                    showError(response.message || config.labels.saveError || 'Failed to save contact');
                }
            },
            error: function(xhr) {
                handleValidationErrors(xhr, '#contactForm');
            },
            complete: function() {
                setButtonLoading('#submitContactBtn', false);
            }
        });
    }

    /**
     * Reset contact form
     */
    function resetContactForm() {
        const form = $('#contactForm');
        if (form.length) {
            form[0].reset();
            $('#contact_id').val('');
            clearValidationErrors('#contactForm');

            // Reset Select2 fields
            $('#contact_type').val('').trigger('change');

            // Reset Flatpickr
            if (flatpickrInstances.contactBirthday) {
                flatpickrInstances.contactBirthday.clear();
            }
        }
    }

    /**
     * Delete contact with confirmation
     * @param {number} id - Contact ID
     */
    function deleteContact(id) {
        Swal.fire({
            title: config.labels.confirmDelete || 'Are you sure?',
            text: config.labels.deleteContactWarning || 'This contact will be permanently deleted.',
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: config.labels.yesDelete || 'Yes, delete it!',
            cancelButtonText: config.labels.cancel || 'Cancel',
            customClass: {
                confirmButton: 'btn btn-danger me-3',
                cancelButton: 'btn btn-label-secondary'
            },
            buttonsStyling: false
        }).then(function(result) {
            if (result.isConfirmed) {
                const url = config.urls.contacts.destroy?.replace(':id', id);
                if (!url) {
                    showError(config.labels.urlNotConfigured || 'URL not configured');
                    return;
                }

                $.ajax({
                    url: url,
                    type: 'POST',
                    data: { _method: 'DELETE' },
                    dataType: 'json',
                    success: function(response) {
                        if (response.success) {
                            showSuccess(response.message || config.labels.contactDeleted || 'Contact deleted successfully');
                            reloadPage();
                        } else {
                            showError(response.message || config.labels.deleteError || 'Failed to delete contact');
                        }
                    },
                    error: function(xhr) {
                        showError(xhr.responseJSON?.message || config.labels.deleteError || 'Failed to delete contact');
                    }
                });
            }
        });
    }

    /**
     * Set contact as primary
     * @param {number} id - Contact ID
     */
    function setPrimaryContact(id) {
        const url = config.urls.contacts.setPrimary?.replace(':id', id);
        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        $.ajax({
            url: url,
            type: 'POST',
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    showSuccess(response.message || config.labels.primaryContactSet || 'Primary contact updated');
                    reloadPage();
                } else {
                    showError(response.message || config.labels.error || 'Failed to set primary contact');
                }
            },
            error: function(xhr) {
                showError(xhr.responseJSON?.message || config.labels.error || 'Failed to set primary contact');
            }
        });
    }

    // =========================================================================
    // DOCUMENT FUNCTIONS
    // =========================================================================

    /**
     * Open document offcanvas for add/edit
     * @param {number|null} id - Document ID for edit, null for create
     */
    function openDocumentOffcanvas(id) {
        resetDocumentForm();

        if (id) {
            // Edit mode - load document data
            $('#documentOffcanvasLabel').text(config.labels.editDocument || 'Edit Document');
            loadDocument(id);
            // Hide file input in edit mode (optional - show current file info instead)
            $('#document_file_group').hide();
            $('#document_current_file_group').show();
        } else {
            // Create mode
            $('#documentOffcanvasLabel').text(config.labels.addDocument || 'Add Document');
            $('#document_file_group').show();
            $('#document_current_file_group').hide();
        }

        documentOffcanvas?.show();
    }

    /**
     * Load document data for editing
     * @param {number} id - Document ID
     */
    function loadDocument(id) {
        const url = config.urls.documents.show?.replace(':id', id);
        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        setButtonLoading('#submitDocumentBtn', true);

        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'json',
            success: function(response) {
                if (response.success && response.data) {
                    const data = response.data;
                    $('#document_id').val(data.id);
                    $('#document_type').val(data.document_type || '').trigger('change');
                    $('#document_name').val(data.name || '');
                    $('#document_number').val(data.document_number || '');
                    $('#document_description').val(data.description || '');

                    // Set dates using Flatpickr
                    if (flatpickrInstances.documentIssue && data.issue_date) {
                        flatpickrInstances.documentIssue.setDate(data.issue_date, true);
                    }
                    if (flatpickrInstances.documentExpiry && data.expiry_date) {
                        flatpickrInstances.documentExpiry.setDate(data.expiry_date, true);
                    }

                    // Show current file info
                    if (data.original_filename) {
                        $('#document_current_file_name').text(data.original_filename);
                        $('#document_current_file_size').text(data.file_size_formatted || '');
                    }

                    $('#document_notes').val(data.notes || '');
                } else {
                    showError(response.message || config.labels.loadError || 'Failed to load document');
                    documentOffcanvas?.hide();
                }
            },
            error: function(xhr) {
                showError(xhr.responseJSON?.message || config.labels.loadError || 'Failed to load document');
                documentOffcanvas?.hide();
            },
            complete: function() {
                setButtonLoading('#submitDocumentBtn', false);
            }
        });
    }

    /**
     * Handle document form submission
     */
    function handleDocumentSubmit() {
        clearValidationErrors('#documentForm');

        const documentId = $('#document_id').val();
        const isUpdate = !!documentId;
        const url = isUpdate
            ? config.urls.documents.update?.replace(':id', documentId)
            : config.urls.documents.store;

        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        const formData = new FormData($('#documentForm')[0]);

        if (isUpdate) {
            formData.append('_method', 'PUT');
        }

        setButtonLoading('#submitDocumentBtn', true);

        $.ajax({
            url: url,
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    documentOffcanvas?.hide();
                    showSuccess(response.message || config.labels.documentSaved || 'Document saved successfully');
                    reloadPage();
                } else {
                    showError(response.message || config.labels.saveError || 'Failed to save document');
                }
            },
            error: function(xhr) {
                handleValidationErrors(xhr, '#documentForm');
            },
            complete: function() {
                setButtonLoading('#submitDocumentBtn', false);
            }
        });
    }

    /**
     * Reset document form
     */
    function resetDocumentForm() {
        const form = $('#documentForm');
        if (form.length) {
            form[0].reset();
            $('#document_id').val('');
            clearValidationErrors('#documentForm');

            // Reset Select2 fields
            $('#document_type').val('').trigger('change');

            // Reset Flatpickr
            if (flatpickrInstances.documentIssue) {
                flatpickrInstances.documentIssue.clear();
            }
            if (flatpickrInstances.documentExpiry) {
                flatpickrInstances.documentExpiry.clear();
            }

            // Reset file input display
            $('#document_file_group').show();
            $('#document_current_file_group').hide();
            $('#document_current_file_name').text('');
            $('#document_current_file_size').text('');
        }
    }

    /**
     * Delete document with confirmation
     * @param {number} id - Document ID
     */
    function deleteDocument(id) {
        Swal.fire({
            title: config.labels.confirmDelete || 'Are you sure?',
            text: config.labels.deleteDocumentWarning || 'This document will be permanently deleted.',
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: config.labels.yesDelete || 'Yes, delete it!',
            cancelButtonText: config.labels.cancel || 'Cancel',
            customClass: {
                confirmButton: 'btn btn-danger me-3',
                cancelButton: 'btn btn-label-secondary'
            },
            buttonsStyling: false
        }).then(function(result) {
            if (result.isConfirmed) {
                const url = config.urls.documents.destroy?.replace(':id', id);
                if (!url) {
                    showError(config.labels.urlNotConfigured || 'URL not configured');
                    return;
                }

                $.ajax({
                    url: url,
                    type: 'POST',
                    data: { _method: 'DELETE' },
                    dataType: 'json',
                    success: function(response) {
                        if (response.success) {
                            showSuccess(response.message || config.labels.documentDeleted || 'Document deleted successfully');
                            reloadPage();
                        } else {
                            showError(response.message || config.labels.deleteError || 'Failed to delete document');
                        }
                    },
                    error: function(xhr) {
                        showError(xhr.responseJSON?.message || config.labels.deleteError || 'Failed to delete document');
                    }
                });
            }
        });
    }

    /**
     * Download document
     * @param {number} id - Document ID
     */
    function downloadDocument(id) {
        const url = config.urls.documents.download?.replace(':id', id);
        if (!url) {
            showError(config.labels.urlNotConfigured || 'URL not configured');
            return;
        }

        // Open download in new tab/window
        window.open(url, '_blank');
    }

    // =========================================================================
    // UTILITY FUNCTIONS
    // =========================================================================

    /**
     * Handle validation errors from Laravel
     * @param {Object} xhr - jQuery XHR object
     * @param {string} formSelector - Form selector
     */
    function handleValidationErrors(xhr, formSelector) {
        if (xhr.status === 422 && xhr.responseJSON?.errors) {
            const errors = xhr.responseJSON.errors;
            const $form = $(formSelector);

            Object.keys(errors).forEach(function(field) {
                // Find the input by name
                let $input = $form.find(`[name="${field}"]`);

                // Handle nested field names (e.g., address.city -> address_city)
                if (!$input.length) {
                    const altFieldName = field.replace(/\./g, '_');
                    $input = $form.find(`[name="${altFieldName}"]`);
                }

                if ($input.length) {
                    // Add is-invalid class
                    $input.addClass('is-invalid');

                    // Handle Select2 fields
                    if ($input.hasClass('select2-hidden-accessible')) {
                        $input.siblings('.select2-container').addClass('is-invalid');
                    }

                    // Find or create feedback element
                    let $feedback = $input.siblings('.invalid-feedback');
                    if (!$feedback.length) {
                        $feedback = $input.closest('.mb-3, .col-md-6, .col-12').find('.invalid-feedback');
                    }

                    if ($feedback.length) {
                        $feedback.text(errors[field][0]).show();
                    } else {
                        $input.after(`<div class="invalid-feedback d-block">${errors[field][0]}</div>`);
                    }
                }
            });

            // Show general validation error
            showError(xhr.responseJSON.message || config.labels.validationError || 'Please check your input');
        } else {
            // General server error
            showError(xhr.responseJSON?.message || config.labels.error || 'An error occurred');
        }
    }

    /**
     * Clear validation errors from a form
     * @param {string} formSelector - Form selector
     */
    function clearValidationErrors(formSelector) {
        const $form = $(formSelector);
        $form.find('.is-invalid').removeClass('is-invalid');
        $form.find('.invalid-feedback').text('').hide();
        $form.find('.select2-container.is-invalid').removeClass('is-invalid');
    }

    /**
     * Set button loading state
     * @param {string} selector - Button selector
     * @param {boolean} isLoading - Loading state
     */
    function setButtonLoading(selector, isLoading) {
        const $btn = $(selector);
        const originalText = $btn.data('original-text') || $btn.html();

        if (isLoading) {
            $btn.data('original-text', originalText);
            $btn.prop('disabled', true);
            $btn.html('<span class="spinner-border spinner-border-sm me-1"></span> ' + (config.labels.processing || 'Processing...'));
        } else {
            $btn.prop('disabled', false);
            $btn.html($btn.data('original-text') || originalText);
        }
    }

    /**
     * Show success message using SweetAlert2
     * @param {string} message - Success message
     */
    function showSuccess(message) {
        Swal.fire({
            icon: 'success',
            title: config.labels.success || 'Success!',
            text: message,
            customClass: {
                confirmButton: 'btn btn-success'
            },
            buttonsStyling: false,
            timer: 3000,
            timerProgressBar: true
        });
    }

    /**
     * Show error message using SweetAlert2
     * @param {string} message - Error message
     */
    function showError(message) {
        Swal.fire({
            icon: 'error',
            title: config.labels.error || 'Error!',
            text: message,
            customClass: {
                confirmButton: 'btn btn-danger'
            },
            buttonsStyling: false
        });
    }

    /**
     * Reload the current page
     */
    function reloadPage() {
        window.location.reload();
    }

    // =========================================================================
    // EXPOSE PUBLIC API
    // =========================================================================

    window.EntityManager = {
        init: init,

        // Address functions
        openAddressOffcanvas: openAddressOffcanvas,
        deleteAddress: deleteAddress,
        setPrimaryAddress: setPrimaryAddress,

        // Contact functions
        openContactOffcanvas: openContactOffcanvas,
        deleteContact: deleteContact,
        setPrimaryContact: setPrimaryContact,

        // Document functions
        openDocumentOffcanvas: openDocumentOffcanvas,
        deleteDocument: deleteDocument,
        downloadDocument: downloadDocument,

        // Utility functions (exposed for advanced use)
        showSuccess: showSuccess,
        showError: showError,
        reloadPage: reloadPage
    };

})(window, jQuery);
