/**
 * Enhanced File Upload Functionality
 * Provides progress indicators, drag-and-drop, and better error handling
 */

document.addEventListener('DOMContentLoaded', function () {
    // Initialize file upload enhancements for all file inputs (except those marked as disabled)
    const fileInputs = document.querySelectorAll('input[type="file"]:not([data-enhancement-disabled])');
    fileInputs.forEach(function (input) {
        enhanceFileInput(input);
    });

    // Initialize form upload enhancements
    const formsWithFiles = document.querySelectorAll('form[enctype="multipart/form-data"]');
    formsWithFiles.forEach(function (form) {
        enhanceFormWithFileUpload(form);
    });
});

function enhanceFileInput(fileInput) {
    // Create upload wrapper
    const wrapper = document.createElement('div');
    wrapper.className = 'file-upload-wrapper';

    // Insert wrapper AFTER the file input, and move enhancement UI into wrapper
    // This keeps the file input in the form and in the DOM order
    fileInput.parentNode.insertBefore(wrapper, fileInput.nextSibling);

    // Create upload area
    const uploadArea = document.createElement('div');
    uploadArea.className = 'file-upload-area border border-2 border-dashed rounded p-4 text-center';
    uploadArea.innerHTML = `
        <div class="upload-icon mb-2">
            <i class="bi bi-cloud-upload fs-1 text-muted"></i>
        </div>
        <div class="upload-text">
            <p class="">You can drag and drop your file here<br><button type="button" class="btn btn-link p-0 text-decoration-none">Select a file...</button></p>
            <small class="text-muted" id="file-restrictions-${fileInput.id || 'file'}">
                ${getFileRestrictions(fileInput)}
            </small>
        </div>
        <div class="selected-file" style="display: none;">
            <i class="bi bi-file-earmark"></i>
            <span class="file-name"></span>
            <button type="button" class="btn btn-sm btn-outline-danger ms-2 remove-file">
                <i class="bi bi-x"></i> Remove
            </button>
        </div>
    `;

    // Hide original input and add upload area
    fileInput.style.display = 'none';
    wrapper.appendChild(uploadArea);

    // Create progress bar
    const progressBar = document.createElement('div');
    progressBar.className = 'upload-progress mt-2';
    progressBar.style.display = 'none';
    progressBar.innerHTML = `
        <div class="progress progress-mobile">
            <div class="progress-bar" role="progressbar" style="width: 0%">
                <span class="progress-text">0%</span>
            </div>
        </div>
        <small class="upload-status text-muted mt-1 d-block"></small>
    `;
    wrapper.appendChild(progressBar);

    // Add event listeners
    const browseButton = uploadArea.querySelector('.btn-link');
    const removeButton = uploadArea.querySelector('.remove-file');
    const selectedFileDiv = uploadArea.querySelector('.selected-file');
    const fileNameSpan = uploadArea.querySelector('.file-name');

    // Browse button click
    browseButton.addEventListener('click', function () {
        fileInput.click();
    });

    // Remove file button
    removeButton.addEventListener('click', function () {
        fileInput.value = '';
        selectedFileDiv.style.display = 'none';
        uploadArea.querySelector('.upload-text').style.display = 'block';
        uploadArea.classList.remove('file-selected');
    });

    // File input change
    fileInput.addEventListener('change', function () {
        handleFileSelection(this, uploadArea, selectedFileDiv, fileNameSpan);
    });

    // Drag and drop functionality
    uploadArea.addEventListener('dragover', function (e) {
        e.preventDefault();
        uploadArea.classList.add('drag-over');
    });

    uploadArea.addEventListener('dragleave', function (e) {
        e.preventDefault();
        uploadArea.classList.remove('drag-over');
    });

    uploadArea.addEventListener('drop', function (e) {
        e.preventDefault();
        uploadArea.classList.remove('drag-over');

        const files = e.dataTransfer.files;
        if (files.length > 0) {
            const file = files[0];

            // Validate file
            if (validateFile(file, fileInput)) {
                // Create a new FileList-like object
                const dt = new DataTransfer();
                dt.items.add(file);
                fileInput.files = dt.files;

                handleFileSelection(fileInput, uploadArea, selectedFileDiv, fileNameSpan);
            }
        }
    });
}

function handleFileSelection(fileInput, uploadArea, selectedFileDiv, fileNameSpan) {
    if (fileInput.files.length > 0) {
        const file = fileInput.files[0];

        if (validateFile(file, fileInput)) {
            fileNameSpan.textContent = `${file.name} (${formatFileSize(file.size)})`;
            selectedFileDiv.style.display = 'block';
            uploadArea.querySelector('.upload-text').style.display = 'none';
            uploadArea.classList.add('file-selected');
        } else {
            fileInput.value = '';
        }
    }
}

function validateFile(file, fileInput) {
    // Get max file size from data attribute or default
    const maxSize = parseInt(fileInput.dataset.maxSize) || (10 * 1024 * 1024); // 10MB default
    const allowedTypes = fileInput.dataset.allowedTypes ?
        fileInput.dataset.allowedTypes.split(',').map(t => t.trim()) :
        [];

    // Check file size
    if (file.size > maxSize) {
        showFileError(`File size (${formatFileSize(file.size)}) exceeds the maximum limit of ${formatFileSize(maxSize)}`);
        return false;
    }

    // Check file type
    if (allowedTypes.length > 0) {
        const fileExtension = file.name.split('.').pop().toLowerCase();
        const mimeType = file.type.toLowerCase();

        const isValidExtension = allowedTypes.includes(fileExtension);
        const isValidMimeType = allowedTypes.some(type => mimeType.includes(type));

        if (!isValidExtension && !isValidMimeType) {
            showFileError(`File type "${fileExtension}" is not allowed. Allowed types: ${allowedTypes.join(', ')}`);
            return false;
        }
    }

    return true;
}

function getFileRestrictions(fileInput) {
    const maxSize = parseInt(fileInput.dataset.maxSize) || (10 * 1024 * 1024);
    const allowedTypes = fileInput.dataset.allowedTypes ?
        fileInput.dataset.allowedTypes.split(',').map(t => t.trim()) :
        [];

    let restrictions = ``;
    if (allowedTypes.length > 0) {
        restrictions += ``;
    }

    return restrictions;
}

function formatFileSize(bytes) {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function showFileError(message) {
    // Create or update error alert
    let errorAlert = document.querySelector('.file-upload-error');
    if (!errorAlert) {
        errorAlert = document.createElement('div');
        errorAlert.className = 'alert alert-danger alert-dismissible fade show file-upload-error';
        errorAlert.innerHTML = `
            <i class="bi bi-exclamation-triangle-fill"></i>
            <span class="error-message"></span>
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        `;

        // Insert at the top of the main content
        const main = document.querySelector('main');
        if (main) {
            main.insertBefore(errorAlert, main.firstChild);
        }
    }

    errorAlert.querySelector('.error-message').textContent = message;

    // Auto-dismiss after 5 seconds
    setTimeout(function () {
        if (errorAlert && errorAlert.parentNode) {
            errorAlert.remove();
        }
    }, 5000);
}

function enhanceFormWithFileUpload(form) {
    form.addEventListener('submit', function (e) {
        const fileInputs = form.querySelectorAll('input[type="file"]');
        let hasFiles = false;

        fileInputs.forEach(function (input) {
            if (input.files.length > 0) {
                hasFiles = true;
            }
        });

        if (hasFiles) {
            showUploadProgress(form);
        }
    });
}

function showUploadProgress(form) {
    // Find or create progress indicators
    const progressBars = form.querySelectorAll('.upload-progress');

    progressBars.forEach(function (progressContainer) {
        const progressBar = progressContainer.querySelector('.progress-bar');
        const statusText = progressContainer.querySelector('.upload-status');

        progressContainer.style.display = 'block';

        // Simulate upload progress (since we can't track real progress easily with standard form submission)
        let progress = 0;
        const interval = setInterval(function () {
            progress += Math.random() * 15;
            if (progress > 90) progress = 90; // Don't complete until actual upload finishes

            progressBar.style.width = progress + '%';
            progressBar.querySelector('.progress-text').textContent = Math.round(progress) + '%';

            if (progress < 30) {
                statusText.textContent = 'Preparing upload...';
            } else if (progress < 70) {
                statusText.textContent = 'Uploading file...';
            } else {
                statusText.textContent = 'Almost done...';
            }
        }, 100);

        // Store interval ID for cleanup
        progressContainer.dataset.intervalId = interval;
    });

    // Submit button disabling removed to prevent UI hangs if submission redirect is slow
    /*
    const submitButtons = form.querySelectorAll('button[type="submit"], input[type="submit"]');
    submitButtons.forEach(function(button) {
        button.disabled = true;
        if (button.tagName === 'BUTTON') {
            const originalText = button.innerHTML;
            button.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Uploading...';
            button.dataset.originalText = originalText;
        }
    });
    */
}

// CSS styles for enhanced upload (to be added inline)
const uploadStyles = `
<style>
.file-upload-area {
    transition: all 0.3s ease;
    cursor: pointer;
    min-height: 120px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.file-upload-area:hover {
    border-color: #0d6efd !important;
    background-color: #f8f9fa;
}

.file-upload-area.drag-over {
    border-color: #0d6efd !important;
    background-color: #e7f3ff;
    transform: scale(1.02);
}

.file-upload-area.file-selected {
    border-color: #198754 !important;
    background-color: #f8fff9;
}

.upload-icon {
    transition: all 0.3s ease;
}

.file-upload-area:hover .upload-icon i {
    color: #0d6efd !important;
    transform: scale(1.1);
}

.progress-mobile {
    height: 6px;
    background-color: #e9ecef;
    border-radius: 3px;
    overflow: hidden;
}

.progress-mobile .progress-bar {
    background-color: #0d6efd;
    transition: width 0.3s ease;
    height: 100%;
    position: relative;
    overflow: hidden;
}

.progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 10px;
    font-weight: bold;
    color: white;
    text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
}

@media (max-width: 768px) {
    .file-upload-area {
        min-height: 100px;
        padding: 1rem !important;
    }
    
    .upload-icon i {
        font-size: 2rem !important;
    }
}
</style>
`;

// Inject styles
document.head.insertAdjacentHTML('beforeend', uploadStyles); 