/**
 * Enhanced Admin Loader System
 * Provides comprehensive loading states for admin dashboard forms
 */

class AdminLoader {
    constructor() {
        this.overlay = document.getElementById('adminLoadingOverlay');
        this.title = document.getElementById('loadingTitle');
        this.message = document.getElementById('loadingMessage');
        this.progressBar = document.getElementById('adminProgressBar');
        this.progressFill = document.getElementById('adminProgressFill');
        this.isVisible = false;

        this.init();
    }

    init() {
        // Auto-detect file uploads and show appropriate loader
        this.detectFileUploads();

        // Enhance existing form submissions
        this.enhanceFormSubmissions();

        // Add progress tracking for AJAX requests
        this.trackAjaxProgress();

        // Initialize image grid functionality
        this.initImageGrid();
    }

    /**
     * Show the loading overlay
     * @param {Object} options - Configuration options
     */
    show(options = {}) {
        const config = {
            title: window.loaderTranslations?.processing || 'Processing...',
            message: window.loaderTranslations?.please_wait || 'Please wait...',
            type: 'default', // default, file-upload, success, error
            showProgress: false,
            progress: 0,
            ...options
        };

        // Hide text messages - only show loader without text
        if (this.title) this.title.style.display = 'none';
        if (this.message) this.message.style.display = 'none';

        // Reset classes
        this.overlay.className = 'admin-loading-overlay';
        this.overlay.classList.add(config.type);

        // Show/hide progress bar
        if (config.showProgress) {
            this.progressBar.style.display = 'block';
            this.setProgress(config.progress);
        } else {
            this.progressBar.style.display = 'none';
        }

        this.overlay.style.display = 'flex';
        this.isVisible = true;

        // Prevent body scroll
        document.body.style.overflow = 'hidden';
    }

    /**
     * Hide the loading overlay
     */
    hide() {
        this.overlay.style.display = 'none';
        this.isVisible = false;

        // Restore body scroll
        document.body.style.overflow = '';

        // Reset classes after animation
        setTimeout(() => {
            this.overlay.className = 'admin-loading-overlay';
        }, 300);
    }

    /**
     * Show success state
     * @param {String} message - Success message
     * @param {Number} duration - How long to show (ms)
     */
    showSuccess(message = null, duration = 2000) {
        // Hide text messages - only show success loader without text
        this.show({
            title: '',
            message: '',
            type: 'success'
        });

        setTimeout(() => {
            this.hide();
        }, duration);
    }

    /**
     * Show error state
     * @param {String} message - Error message
     * @param {Number} duration - How long to show (ms)
     */
    showError(message = null, duration = 3000) {
        // Hide text messages - only show error loader without text
        this.show({
            title: '',
            message: '',
            type: 'error'
        });

        setTimeout(() => {
            this.hide();
        }, duration);
    }

    /**
     * Show file upload progress
     * @param {Number} progress - Progress percentage (0-100)
     * @param {String} message - Progress message
     */
    showFileUploadProgress(progress, message = null) {
        // Hide text messages - only show progress bar without text
        this.show({
            title: '',
            message: '',
            type: 'file-upload',
            showProgress: true,
            progress: progress
        });
    }

    /**
     * Set progress bar percentage
     * @param {Number} percentage - Progress percentage (0-100)
     */
    setProgress(percentage) {
        this.progressFill.style.width = `${Math.min(100, Math.max(0, percentage))}%`;
    }

    /**
     * Detect file uploads and enhance them
     */
    detectFileUploads() {
        // Find all file inputs
        const fileInputs = document.querySelectorAll('input[type="file"]');

        fileInputs.forEach(input => {
            input.addEventListener('change', (e) => {
                if (e.target.files.length > 0) {
                    const file = e.target.files[0];
                    const fileSize = file.size;
                    const fileName = file.name;

                    // Only show preview or validation messages, NOT upload progress
                    // Upload progress will be shown only during actual form submission
                    console.log(`File selected: ${fileName} (${Math.round(fileSize / 1024 / 1024 * 100) / 100} MB)`);

                    // File validation
                    if (fileSize > 100 * 1024 * 1024) { // > 100MB
                        alert(window.loaderTranslations?.file_too_large || 'File is too large. Please select a smaller file.');
                        e.target.value = ''; // Clear the input
                        return;
                    }

                    // Show file preview for all admin forms
                    this.showFilePreview(e.target, file);
                }
            });
        });
    }

    /**
     * Show file preview for any file input - Enhanced with legacy image handling
     * @param {HTMLElement} input - File input element
     * @param {File} file - Selected file
     */
    showFilePreview(input, file) {
        // Check if this is a multi-image upload (legacy pattern)
        const isImageGrid = input.closest('#imageContainer') || input.id === 'fileTemplate';

        if (isImageGrid) {
            this.handleImageGridPreview(input, file);
            return;
        }

        // Find or create preview container
        let previewContainer = input.parentNode.querySelector('.file-preview-container');

        if (!previewContainer) {
            previewContainer = document.createElement('div');
            previewContainer.className = 'file-preview-container mt-2';
            previewContainer.innerHTML = `
                <div class="alert alert-info">
                    <strong>${window.loaderTranslations?.file_selected || 'File Selected'}:</strong>
                    <span class="file-info">${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB)</span>
                </div>
                <div class="preview-content"></div>
            `;
            input.parentNode.appendChild(previewContainer);
        } else {
            // Update existing preview
            const fileInfo = previewContainer.querySelector('.file-info');
            const previewContent = previewContainer.querySelector('.preview-content');

            if (fileInfo) {
                fileInfo.textContent = `${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB)`;
            }

            if (previewContent) {
                // Show preview based on file type
                if (file.type.startsWith('video/')) {
                    previewContent.innerHTML = `
                        <video controls width="200" style="max-height: 150px;">
                            <source src="${URL.createObjectURL(file)}" type="${file.type}">
                            Your browser does not support the video tag.
                        </video>
                    `;
                } else if (file.type.startsWith('image/')) {
                    previewContent.innerHTML = `
                        <img src="${URL.createObjectURL(file)}" alt="Preview" width="200" style="max-height: 150px; object-fit: cover;">
                    `;
                } else {
                    previewContent.innerHTML = `
                        <div class="alert alert-warning">
                            <i class="fas fa-file"></i> ${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB)
                        </div>
                    `;
                }
            }
        }

        previewContainer.style.display = 'block';
    }

    /**
     * Handle image grid preview (from legacy images_grid.js)
     * @param {HTMLElement} input - File input element
     * @param {File} file - Selected file
     */
    handleImageGridPreview(input, file) {
        const reader = new FileReader();
        const inputRef = input; // Save reference for later

        reader.onload = (e) => {
            const preview = `
                <div class="col-md-4">
                    <div class="items">
                        <div class="img">
                            <a href="${e.target.result}" data-fancybox="gallery">
                                <img src="${e.target.result}" alt="" style="height: 200px; object-fit: cover;">
                            </a>
                        </div>
                        <a href="#" class="close remove-image" data-input-ref="${inputRef.id || 'temp-' + Date.now()}">
                            <i class="fas fa-times"></i>
                        </a>
                    </div>
                </div>
            `;

            const previewElement = document.createElement('div');
            previewElement.innerHTML = preview;
            const previewDiv = previewElement.firstElementChild;

            // Store reference to input for removal
            previewDiv.setAttribute('data-file-input', inputRef.id || 'temp-' + Date.now());

            // Find image container
            const imageContainer = document.getElementById('imageContainer');
            if (imageContainer) {
                imageContainer.appendChild(previewDiv);
            }

            // Add remove functionality
            const removeBtn = previewDiv.querySelector('.remove-image');
            removeBtn.addEventListener('click', (e) => {
                e.preventDefault();
                this.removeImagePreview(previewDiv, inputRef);
            });
        };

        reader.readAsDataURL(file);
    }

    /**
     * Remove image preview and associated input
     * @param {HTMLElement} previewDiv - Preview element to remove
     * @param {HTMLElement} inputRef - Associated input element
     */
    removeImagePreview(previewDiv, inputRef) {
        if (previewDiv && previewDiv.parentNode) {
            previewDiv.parentNode.removeChild(previewDiv);
        }
        if (inputRef && inputRef.parentNode) {
            inputRef.parentNode.removeChild(inputRef);
        }
    }

    /**
     * Initialize image grid functionality (replaces legacy images_grid.js)
     */
    initImageGrid() {
        // Handle add image button click
        const addImageBtn = document.getElementById('addImage');
        if (addImageBtn) {
            addImageBtn.addEventListener('click', () => {
                const fileTemplate = document.getElementById('fileTemplate');
                if (fileTemplate) {
                    const clonedInput = fileTemplate.cloneNode(true);
                    clonedInput.removeAttribute('id');
                    clonedInput.style.display = 'none';

                    const imageContainer = document.getElementById('imageContainer');
                    if (imageContainer) {
                        imageContainer.appendChild(clonedInput);
                        clonedInput.click();

                        clonedInput.addEventListener('change', (e) => {
                            const file = e.target.files[0];
                            if (!file) {
                                // If user cancels file picker, remove the input
                                if (e.target.parentNode) {
                                    e.target.parentNode.removeChild(e.target);
                                }
                                return;
                            }

                            // Use our enhanced preview system
                            this.handleImageGridPreview(e.target, file);
                        });
                    }
                }
            });
        }

        // Handle remove image functionality
        const imageContainer = document.getElementById('imageContainer');
        if (imageContainer) {
            imageContainer.addEventListener('click', (e) => {
                if (e.target.closest('.remove-image')) {
                    e.preventDefault();
                    const previewDiv = e.target.closest('.col-md-4');
                    const inputRef = previewDiv ? previewDiv.querySelector('input[type="file"]') : null;
                    this.removeImagePreview(previewDiv, inputRef);
                }
            });
        }
    }

    /**
     * Enhance form submissions with proper cleanup
     */
    enhanceFormSubmissions() {
        // Override the existing saveForm function
        const originalSaveForm = window.saveForm;

        window.saveForm = (elem) => {
            // Check if form has file inputs
            const hasFiles = elem.querySelector('input[type="file"]');
            const formData = new FormData(elem);

            // Determine loader type based on form content
            let loaderType = 'default';
            let title = window.loaderTranslations?.processing || 'Processing...';
            let message = window.loaderTranslations?.please_wait || 'Please wait...';

            if (hasFiles) {
                loaderType = 'file-upload';
                title = window.loaderTranslations?.uploading || 'Uploading...';
                message = window.loaderTranslations?.uploading_files || 'Uploading files';
            }

            // Show loader without text messages
            this.show({
                title: '',
                message: '',
                type: loaderType,
                showProgress: hasFiles
            });

            // Call original function with enhanced cleanup
            if (originalSaveForm) {
                try {
                    originalSaveForm(elem);
                } catch (error) {
                    console.error('Form submission error:', error);
                    this.showError(window.loaderTranslations?.form_error || 'Form submission failed');
                }
            }
        };
    }

    /**
     * Track AJAX progress with enhanced cleanup
     */
    trackAjaxProgress() {
        // Override the existing ajax function
        const originalAjax = window.ajax;

        if (originalAjax) {
            window.ajax = async (options) => {
                // Show loader without text messages if not disabled
                if (!options.no_load) {
                    this.show({
                        title: '',
                        message: '',
                        type: 'default'
                    });
                }

                try {
                    const result = await originalAjax(options);

                    // Hide loader and show success if needed
                    if (!options.no_load) {
                        if (result && result.success !== false) {
                            this.showSuccess(window.loaderTranslations?.request_successful || 'Request completed successfully', 1500);
                        } else {
                            this.hide();
                        }
                    }

                    return result;
                } catch (error) {
                    // Hide loader and show error
                    if (!options.no_load) {
                        this.showError(window.loaderTranslations?.request_failed || 'Request failed', 3000);
                    }
                    throw error;
                }
            };
        }
    }

    /**
     * Simulate file upload progress
     * @param {File} file - File being uploaded
     * @param {Function} callback - Callback function
     */
    simulateFileUploadProgress(file, callback) {
        let progress = 0;
        const interval = setInterval(() => {
            progress += Math.random() * 15;

            if (progress >= 100) {
                progress = 100;
                clearInterval(interval);
                this.setProgress(100);

                setTimeout(() => {
                    this.showSuccess(window.loaderTranslations?.file_uploaded_successfully || 'File uploaded successfully');
                    if (callback) callback();
                }, 500);
            } else {
                this.setProgress(progress);
                const uploadingText = window.loaderTranslations?.uploading || 'Uploading';
                this.message.textContent = `${uploadingText}: ${file.name} (${Math.round(progress)}%)`;
            }
        }, 200);
    }
}

// Initialize the loader when DOM is ready
document.addEventListener('DOMContentLoaded', function() {
    window.adminLoader = new AdminLoader();

    // Add global helper functions
    window.showAdminLoader = (options) => window.adminLoader.show(options);
    window.hideAdminLoader = () => window.adminLoader.hide();
    window.showAdminSuccess = (message, duration) => window.adminLoader.showSuccess(message, duration);
    window.showAdminError = (message, duration) => window.adminLoader.showError(message, duration);
});

// Export for module systems
if (typeof module !== 'undefined' && module.exports) {
    module.exports = AdminLoader;
}
