/**
 * WPUF Profile Image Upload with Cropper.js
 * Generalized handler for profile image uploads (avatar, cover photo, etc.)
 *
 * @since 4.2.3
 */

(function($) {
    'use strict';

    class WPUFProfileImageUpload {
        constructor(config) {
            this.config = {
                type: config.type || 'avatar',
                aspectRatio: config.aspectRatio || 1,
                croppedSize: config.croppedSize || { width: 300, height: 300 },
                modalTitle: config.modalTitle || 'Upload Image',
                fileInputName: config.fileInputName || 'image',
                ajaxAction: config.ajaxAction || 'wpuf_upload_image',
                updateSelector: config.updateSelector || '.wpuf-user-avatar img',
                nonceName: config.nonceName || 'wpuf_avatar_upload_nonce',
                nonce: config.nonce || '', // Store nonce from config
                maxSize: config.maxSize || 5 * 1024 * 1024, // 5MB default
                prefix: config.prefix || 'wpuf-avatar'
            };

            this.modal = null;
            this.cropper = null;
            this.currentUserId = null;
            this.isUploading = false;
            this.init();
        }

        /**
         * Initialize the upload system
         */
        init() {
            this.createModal();
            this.bindEvents();
        }

        /**
         * Create the upload modal HTML structure
         */
        createModal() {
            const prefix = this.config.prefix;
            const modalHtml = `
                <div id="${prefix}-upload-modal" class="wpuf-upload-modal wpuf-fixed wpuf-inset-0 wpuf-z-50" style="display: none;">
                    <div class="${prefix}-modal-overlay wpuf-absolute wpuf-inset-0 wpuf-bg-black wpuf-bg-opacity-50 wpuf-flex wpuf-items-center wpuf-justify-center wpuf-p-5">
                        <div class="wpuf-bg-white wpuf-rounded-xl wpuf-shadow-2xl wpuf-max-w-2xl wpuf-w-full wpuf-max-h-screen wpuf-overflow-hidden wpuf-flex wpuf-flex-col">
                            <div class="wpuf-flex wpuf-items-center wpuf-justify-between wpuf-p-6 wpuf-border-b wpuf-border-gray-200 wpuf-bg-gray-50">
                                <h3 class="wpuf-m-0 wpuf-text-lg wpuf-font-semibold wpuf-text-gray-900">${this.config.modalTitle}</h3>
                                <button type="button" class="${prefix}-modal-close wpuf-flex wpuf-items-center wpuf-justify-center wpuf-w-8 wpuf-h-8 wpuf-bg-transparent wpuf-border-0 wpuf-rounded-md wpuf-cursor-pointer wpuf-text-gray-500 wpuf-transition-colors wpuf-duration-200 hover:wpuf-bg-gray-200 hover:wpuf-text-gray-700 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50" aria-label="Close modal">
                                    <svg class="wpuf-w-6 wpuf-h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
                                    </svg>
                                </button>
                            </div>
                            <div class="wpuf-p-6 wpuf-flex-1 wpuf-overflow-y-auto">
                                <!-- Upload Area -->
                                <div class="${prefix}-upload-area wpuf-text-center">
                                    <input type="file" id="${prefix}-file-input" accept="image/*" style="display: none;">
                                    <div class="${prefix}-drop-zone wpuf-border-2 wpuf-border-dashed wpuf-border-gray-300 wpuf-rounded-lg wpuf-p-10 wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-gray-50 hover:wpuf-border-green-600 hover:wpuf-bg-green-50 focus:wpuf-outline-none" tabindex="0" role="button" aria-label="Click to select image or drag and drop">
                                        <div class="wpuf-flex wpuf-flex-col wpuf-items-center wpuf-gap-3">
                                            <svg class="wpuf-w-12 wpuf-h-12 wpuf-text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
                                            </svg>
                                            <p class="wpuf-m-0 wpuf-text-base wpuf-font-medium wpuf-text-gray-700">Click to select image or drag and drop</p>
                                            <p class="wpuf-m-0 wpuf-text-sm wpuf-text-gray-500">Supports JPG, PNG, GIF up to ${Math.round(this.config.maxSize / 1024 / 1024)}MB</p>
                                        </div>
                                    </div>
                                </div>

                                <!-- Crop Area -->
                                <div class="${prefix}-crop-area" style="display: none;">
                                    <div class="wpuf-flex wpuf-flex-col wpuf-gap-4">
                                        <div class="wpuf-relative wpuf-flex wpuf-justify-center wpuf-items-center wpuf-min-h-80 wpuf-bg-gray-50 wpuf-rounded-lg wpuf-overflow-hidden">
                                            <img id="${prefix}-crop-image" style="max-width: 100%; max-height: 400px;">
                                            <!-- Dark overlay for non-cropped areas -->
                                            <div class="${prefix}-crop-overlay wpuf-absolute wpuf-inset-0 wpuf-pointer-events-none" style="background: rgba(0, 0, 0, 0.5);"></div>
                                        </div>
                                        <div class="${prefix}-crop-controls wpuf-flex wpuf-justify-center wpuf-gap-2 wpuf-flex-wrap">
                                            <button type="button" class="${prefix}-zoom-out wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-3 wpuf-py-1.5 wpuf-text-xs wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-white wpuf-text-gray-700 wpuf-border-gray-300 hover:wpuf-bg-gray-50 hover:wpuf-border-gray-400 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50">
                                                <svg class="wpuf-w-4 wpuf-h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4"></path>
                                                </svg>
                                            </button>
                                            <button type="button" class="${prefix}-zoom-in wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-3 wpuf-py-1.5 wpuf-text-xs wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-white wpuf-text-gray-700 wpuf-border-gray-300 hover:wpuf-bg-gray-50 hover:wpuf-border-gray-400 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50">
                                                <svg class="wpuf-w-4 wpuf-h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
                                                </svg>
                                            </button>
                                            <button type="button" class="${prefix}-rotate wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-3 wpuf-py-1.5 wpuf-text-xs wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-white wpuf-text-gray-700 wpuf-border-gray-300 hover:wpuf-bg-gray-50 hover:wpuf-border-gray-400 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50">
                                                Rotate
                                            </button>
                                            <button type="button" class="${prefix}-reset wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-3 wpuf-py-1.5 wpuf-text-xs wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-white wpuf-text-gray-700 wpuf-border-gray-300 hover:wpuf-bg-gray-50 hover:wpuf-border-gray-400 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50">
                                                Reset
                                            </button>
                                        </div>
                                    </div>
                                </div>
                                <div class="wpuf-text-center" style="display: none;">
                                    <div class="wpuf-w-full wpuf-h-2 wpuf-bg-gray-200 wpuf-rounded-full wpuf-overflow-hidden wpuf-mb-3">
                                        <div class="wpuf-h-full wpuf-bg-green-600 wpuf-rounded-full wpuf-transition-all wpuf-duration-300" style="width: 0%;"></div>
                                    </div>
                                    <p class="wpuf-m-0 wpuf-text-sm wpuf-text-gray-500">Uploading...</p>
                                </div>
                                <div class="wpuf-text-center wpuf-p-4 wpuf-bg-red-50 wpuf-border wpuf-border-red-200 wpuf-rounded-lg wpuf-mb-4" style="display: none;">
                                    <div class="wpuf-flex wpuf-items-center wpuf-justify-center wpuf-gap-2">
                                        <svg class="wpuf-w-5 wpuf-h-5 wpuf-text-red-600 wpuf-flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                                        </svg>
                                        <p class="wpuf-m-0 wpuf-text-sm wpuf-text-red-600 wpuf-font-medium"></p>
                                    </div>
                                </div>
                            </div>
                            <div class="wpuf-flex wpuf-justify-end wpuf-gap-3 wpuf-p-6 wpuf-border-t wpuf-border-gray-200 wpuf-bg-gray-50">
                                <button type="button" class="${prefix}-cancel wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-4 wpuf-py-2 wpuf-border wpuf-border-transparent wpuf-rounded-md wpuf-text-sm wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-white wpuf-text-gray-700 wpuf-border-gray-300 hover:wpuf-bg-gray-50 hover:wpuf-border-gray-400 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50">Cancel</button>
                                <button type="button" class="${prefix}-crop wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-4 wpuf-py-2 wpuf-border wpuf-border-transparent wpuf-rounded-md wpuf-text-sm wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-green-600 wpuf-text-white wpuf-border-green-600 hover:wpuf-bg-green-700 hover:wpuf-border-green-700 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50" style="display: none;">Crop & Save</button>
                                <button type="button" class="${prefix}-upload wpuf-inline-flex wpuf-items-center wpuf-justify-center wpuf-gap-2 wpuf-px-4 wpuf-py-2 wpuf-border wpuf-border-transparent wpuf-rounded-md wpuf-text-sm wpuf-font-medium wpuf-no-underline wpuf-cursor-pointer wpuf-transition-all wpuf-duration-200 wpuf-bg-green-600 wpuf-text-white wpuf-border-green-600 hover:wpuf-bg-green-700 hover:wpuf-border-green-700 focus:wpuf-outline-none focus:wpuf-ring-2 focus:wpuf-ring-blue-500 focus:wpuf-ring-opacity-50" style="display: none;">Save</button>
                            </div>
                        </div>
                    </div>
                </div>
            `;

            $('body').append(modalHtml);
            this.modal = $(`#${prefix}-upload-modal`);
        }

        /**
         * Bind event handlers
         */
        bindEvents() {
            const prefix = this.config.prefix;

            // File input change
            $(document).on('change', `#${prefix}-file-input`, (e) => {
                this.handleFileSelect(e.target.files[0]);
            });

            // Drop zone events
            $(document).on('click', `.${prefix}-drop-zone`, () => {
                $(`#${prefix}-file-input`).click();
            });

            // Drag and drop events
            $(document).on('dragover', `.${prefix}-drop-zone`, (e) => {
                e.preventDefault();
                e.stopPropagation();
                $(e.currentTarget).addClass('wpuf-drag-over');
            });

            $(document).on('dragleave', `.${prefix}-drop-zone`, (e) => {
                e.preventDefault();
                e.stopPropagation();
                $(e.currentTarget).removeClass('wpuf-drag-over');
            });

            $(document).on('drop', `.${prefix}-drop-zone`, (e) => {
                e.preventDefault();
                e.stopPropagation();
                $(e.currentTarget).removeClass('wpuf-drag-over');

                const files = e.originalEvent.dataTransfer.files;
                if (files.length > 0) {
                    this.handleFileSelect(files[0]);
                }
            });

            // Modal close events
            $(document).on('click', `.${prefix}-modal-close, .${prefix}-cancel`, () => {
                this.closeModal();
            });

            // Overlay click to close
            $(document).on('click', `.${prefix}-modal-overlay`, (e) => {
                if (e.target === e.currentTarget) {
                    this.closeModal();
                }
            });

            // Crop and upload
            $(document).on('click', `.${prefix}-crop`, () => {
                this.cropAndUpload();
            });

            // Direct upload (no crop)
            $(document).on('click', `.${prefix}-upload`, () => {
                this.uploadImage();
            });

            // Crop controls
            $(document).on('click', `.${prefix}-zoom-in`, () => {
                if (this.cropper) {
                    this.cropper.zoom(0.1);
                }
            });

            $(document).on('click', `.${prefix}-zoom-out`, () => {
                if (this.cropper) {
                    this.cropper.zoom(-0.1);
                }
            });

            $(document).on('click', `.${prefix}-rotate`, () => {
                if (this.cropper) {
                    this.cropper.rotate(90);
                }
            });

            $(document).on('click', `.${prefix}-reset`, () => {
                if (this.cropper) {
                    this.cropper.reset();
                }
            });

            // Keyboard events
            $(document).on('keydown', (e) => {
                if (this.modal.is(':visible')) {
                    if (e.key === 'Escape') {
                        this.closeModal();
                    }
                }
            });
        }

        /**
         * Open the upload modal
         * @param {number} userId - The user ID
         */
        openModal(userId) {
            this.currentUserId = userId;
            this.modal.show();
            this.resetModal();

            // Focus management
            this.modal.find(`.${this.config.prefix}-drop-zone`).focus();
        }

        /**
         * Close the upload modal
         */
        closeModal() {
            this.modal.hide();
            if (this.cropper) {
                this.cropper.destroy();
                this.cropper = null;
            }
            this.resetModal();
        }

        /**
         * Handle file selection
         * @param {File} file - The selected file
         */
        handleFileSelect(file) {
            if (!file) {
                this.showError('No file selected');
                return;
            }

            // Validate file type
            if (!file.type.startsWith('image/')) {
                this.showError('Please select a valid image file (JPG, PNG, GIF)');
                return;
            }

            // Validate file size
            if (file.size > this.config.maxSize) {
                this.showError(`File size must be less than ${Math.round(this.config.maxSize / 1024 / 1024)}MB`);
                return;
            }

            // Clear any previous errors
            this.hideError();

            // Read the file
            const reader = new FileReader();
            reader.onload = (e) => {
                this.showCropArea(e.target.result);
            };
            reader.onerror = () => {
                this.showError('Failed to read the file');
            };
            reader.readAsDataURL(file);
        }

        /**
         * Show the crop area with the selected image
         * @param {string} imageSrc - The image data URL
         */
        showCropArea(imageSrc) {
            const prefix = this.config.prefix;
            $(`.${prefix}-upload-area`).hide();
            $(`.${prefix}-crop-area`).show();
            $(`.${prefix}-crop`).show();

            const $cropImage = $(`#${prefix}-crop-image`);
            $cropImage.attr('src', imageSrc);

            // Check if Cropper is available
            if (typeof Cropper === 'undefined') {
                this.showError('Image cropping library not loaded. Please refresh the page and try again.');
                return;
            }

            // Initialize Cropper.js
            this.cropper = new Cropper($cropImage[0], {
                aspectRatio: this.config.aspectRatio,
                viewMode: 1,
                dragMode: 'move',
                autoCropArea: 0.8,
                restore: false,
                guides: true,
                center: true,
                highlight: false,
                cropBoxMovable: true,
                cropBoxResizable: true,
                toggleDragModeOnDblclick: false,
                responsive: true,
                checkCrossOrigin: false,
                background: false,
                modal: false,
                scalable: true,
                zoomable: true,
                rotatable: true,
                cropstart: () => {
                    $(`.${prefix}-crop-controls`).addClass('wpuf-cropping');
                },
                cropend: () => {
                    $(`.${prefix}-crop-controls`).removeClass('wpuf-cropping');
                    this.updateDarkOverlay();
                },
                cropmove: () => {
                    this.updateDarkOverlay();
                },
                ready: () => {
                    this.updateDarkOverlay();
                }
            });
        }

        /**
         * Update the dark overlay to create a window effect around the crop area
         */
        updateDarkOverlay() {
            if (!this.cropper) return;

            const $overlay = $(`.${this.config.prefix}-crop-overlay`);
            if ($overlay.length === 0) return;

            // Get crop box data
            const cropBoxData = this.cropper.getCropBoxData();
            const containerData = this.cropper.getContainerData();

            if (!cropBoxData || !containerData) return;

            // Calculate the crop box position relative to the container
            const left = cropBoxData.left;
            const top = cropBoxData.top;
            const width = cropBoxData.width;
            const height = cropBoxData.height;

            // Create CSS clip-path to cut out the crop area
            const clipPath = `polygon(
                0% 0%,
                0% 100%,
                ${left}px 100%,
                ${left}px ${top}px,
                ${left + width}px ${top}px,
                ${left + width}px ${top + height}px,
                ${left}px ${top + height}px,
                ${left}px 100%,
                100% 100%,
                100% 0%
            )`;

            $overlay.css('clip-path', clipPath);
        }

        /**
         * Crop the image and upload
         */
        cropAndUpload() {
            if (!this.cropper) {
                this.showError('No image to crop');
                return;
            }

            // Set uploading state
            this.isUploading = true;
            this.updateButtonStates();

            this.showProgress('Processing your image...');

            const canvas = this.cropper.getCroppedCanvas({
                width: this.config.croppedSize.width,
                height: this.config.croppedSize.height,
                imageSmoothingEnabled: true,
                imageSmoothingQuality: 'high',
            });

            canvas.toBlob((blob) => {
                if (blob) {
                    this.uploadImage(blob);
                } else {
                    this.showError('Failed to process the image');
                    this.resetUploadState();
                }
            }, 'image/jpeg', 0.9);
        }

        /**
         * Update button states during upload
         */
        updateButtonStates() {
            const prefix = this.config.prefix;
            const $cropBtn = $(`.${prefix}-crop`);
            const $cancelBtn = $(`.${prefix}-cancel`);

            if (this.isUploading) {
                // Disable both buttons
                $cropBtn.prop('disabled', true).addClass('wpuf-loading');
                $cancelBtn.prop('disabled', true);

                // Update crop button text and add spinner
                $cropBtn.html(`
                    <svg class="wpuf-w-4 wpuf-h-4 wpuf-animate-spin wpuf-mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
                    </svg>
                    Processing...
                `);
            } else {
                // Re-enable buttons
                $cropBtn.prop('disabled', false).removeClass('wpuf-loading');
                $cancelBtn.prop('disabled', false);

                // Reset crop button text
                $cropBtn.html('Crop & Save');
            }
        }

        /**
         * Reset upload state
         */
        resetUploadState() {
            this.isUploading = false;
            this.updateButtonStates();
            this.hideProgress();
        }

        /**
         * Show success state and auto-close
         */
        showSuccessAndClose() {
            const prefix = this.config.prefix;
            const $cropBtn = $(`.${prefix}-crop`);

            // Show success state
            $cropBtn.html(`
                <svg class="wpuf-w-4 wpuf-h-4 wpuf-mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
                </svg>
                Uploaded!
            `).removeClass('wpuf-loading').addClass('wpuf-success');

            // Auto-close after delay
            setTimeout(() => {
                this.closeModal();
            }, 1500);
        }

        /**
         * Upload the image
         * @param {Blob} blob - The image blob to upload
         */
        uploadImage(blob) {
            this.showProgress('Uploading image...');

            const formData = new FormData();
            formData.append(this.config.fileInputName, blob, `${this.config.type}.jpg`);
            formData.append('user_id', this.currentUserId);
            formData.append('action', this.config.ajaxAction);
            // Use nonce from config if provided, otherwise fall back to appropriate variable based on type
            let nonce = this.config.nonce;
            if (!nonce) {
                // Fallback based on type
                if (this.config.type === 'cover-photo' && typeof wpuf_ud_cover_photo !== 'undefined') {
                    nonce = wpuf_ud_cover_photo.nonce;
                } else if (typeof wpuf_ud !== 'undefined') {
                    nonce = wpuf_ud.nonce;
                }
            }
            formData.append('nonce', nonce || '');

            $.ajax({
                url: (typeof wpuf_ud !== 'undefined' ? wpuf_ud.ajaxUrl : (typeof wpuf_ud_cover_photo !== 'undefined' ? wpuf_ud_cover_photo.ajaxUrl : admin_url('admin-ajax.php'))),
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                xhr: () => {
                    const xhr = new window.XMLHttpRequest();
                    xhr.upload.addEventListener('progress', (e) => {
                        if (e.lengthComputable) {
                            const percentComplete = (e.loaded / e.total) * 100;
                            this.updateProgress(percentComplete);
                        }
                    }, false);
                    return xhr;
                },
                success: (response) => {
                    if (response.success) {
                        // Try multiple possible response keys
                        const imageUrl = response.data[`${this.config.type}_url`] ||
                                       response.data.image_url ||
                                       response.data.avatar_url ||
                                       response.data.cover_photo_url;
                        if (imageUrl) {
                            this.updateImage(imageUrl);
                            this.showSuccessAndClose();
                        } else {
                            this.showError('Upload succeeded but no image URL received.');
                            this.resetUploadState();
                        }
                    } else {
                        this.showError(response.data?.message || 'Upload failed. Please try again.');
                        this.resetUploadState();
                    }
                },
                error: (xhr, status, error) => {
                    console.error('Upload error:', error);
                    this.showError('Upload failed. Please check your connection and try again.');
                    this.resetUploadState();
                }
            });
        }

        /**
         * Update the image on the page
         * @param {string} imageUrl - The new image URL
         */
        updateImage(imageUrl) {
            // Update using the configured selector
            $(this.config.updateSelector).attr('src', imageUrl);

            // Trigger a custom event for other components
            $(document).trigger(`wpuf:${this.config.type}:updated`, [imageUrl]);
        }

        /**
         * Show progress indicator
         * @param {string} message - Progress message
         */
        showProgress(message) {
            const prefix = this.config.prefix;
            $(`.${prefix}-upload-progress`).show();
            $(`.${prefix}-progress-text`).text(message);
            $(`.${prefix}-progress-fill`).css('width', '0%');
        }

        /**
         * Update progress percentage
         * @param {number} percent - Progress percentage
         */
        updateProgress(percent) {
            const prefix = this.config.prefix;
            $(`.${prefix}-progress-fill`).css('width', percent + '%');
        }

        /**
         * Hide progress indicator
         */
        hideProgress() {
            const prefix = this.config.prefix;
            $(`.${prefix}-upload-progress`).hide();
        }

        /**
         * Show error message
         * @param {string} message - Error message
         */
        showError(message) {
            const prefix = this.config.prefix;
            $(`.${prefix}-error`).show();
            $(`.${prefix}-error-text`).text(message);
            this.hideProgress();
        }

        /**
         * Hide error message
         */
        hideError() {
            const prefix = this.config.prefix;
            $(`.${prefix}-error`).hide();
        }

        /**
         * Reset the modal to initial state
         */
        resetModal() {
            const prefix = this.config.prefix;
            $(`.${prefix}-upload-area`).show();
            $(`.${prefix}-crop-area`).hide();
            $(`.${prefix}-crop`).hide();
            $(`.${prefix}-upload`).hide();
            $(`#${prefix}-file-input`).val('');
            this.hideError();
            this.hideProgress();
        }
    }

    // Export for use in other files
    window.WPUFProfileImageUpload = WPUFProfileImageUpload;

})(jQuery);

