jQuery(document).ready(function($) {
    const ajaxurl = migratequillData.ajax_url;
    const nonce   = migratequillData.nonce;

    // ==========================================
    // UI ELEMENT VARIABLES
    // ==========================================
    const $exportStatus       = $('#mq-export-status');
    const $progressText       = $('#mq-progress-text');
    const $progressBar        = $('#mq-progress-bar');
    const $progressWrap       = $('#mq-progress-wrapper');
    const $downloadBtn        = $('#mq-download-btn');
    const $downloadWrap       = $('#mq-download-container');
    const $exportBtn          = $('#mq-start-export');
    
    const $importStatusText   = $('#mq-import-status-text');
    const $importProgressText = $('#mq-import-progress-text');
    const $importProgressBar  = $('#mq-import-progress-bar');
    const $importProgressWrap = $('#mq-import-progress-wrapper');
    const $importBtn          = $('#mq-start-import');
    
    let totalFilesToZip = 0;

    // ==========================================
    // HELPER FUNCTIONS
    // ==========================================
    function updateProgress(message, percentage) {
        $progressWrap.css('display', 'block');
        $exportStatus.text(message);
        $progressText.text(percentage + '%');
        $progressBar.css('width', percentage + '%');
    }

    function handleAjaxError(xhr, status, error) {
        updateProgress('Server Error: ' + error, 100);
        $progressBar.css('background', '#d63638');
        $exportStatus.css('color', '#d63638');
        $exportBtn.prop('disabled', false);
    }

    function updateImportProgress(message, percentage) {
        $importProgressWrap.show();
        $importStatusText.text(message);
        $importProgressText.text(percentage + '%');
        $importProgressBar.css('width', percentage + '%');
    }

    // ==========================================
    // 1. EXPORT ROUTING
    // ==========================================
    $exportBtn.on('click', function(e) {
        e.preventDefault();
        
        let exportType = $('#mq-export-type').val();
        $exportBtn.prop('disabled', true);
        $downloadWrap.hide();
        
        $progressBar.css('background', '#2271b1').css('width', '0%');
        $exportStatus.css('color', '#2271b1');
        
        if (exportType === 'db') {
            startDatabaseExport(cleanUpExport);
        } else if (exportType === 'files') {
            startFilesExport(cleanUpExport);
        } else if (exportType === 'full') {
            startDatabaseExport(function() {
                startFilesExport(cleanUpExport);
            });
        }
    });

    // ==========================================
    // 2. DB CHUNKING
    // ==========================================
    function startDatabaseExport(onComplete) {
        updateProgress('Initializing database export...', 0);
        
        $.post(ajaxurl, { action: 'migratequill_export_db', security: nonce })
            .done(function(response) {
                if (response.success && response.data.status === 'init') {
                    processDbTable(response.data.tables, 0, 0, onComplete);
                } else {
                    handleAjaxError(null, null, response.data || 'Failed to initialize DB');
                }
            })
            .fail(handleAjaxError);
    }

    function processDbTable(tables, tableIndex, offset, onComplete) {
        if (tableIndex >= tables.length) {
            updateProgress('Database exported!', 100);
            if (onComplete) onComplete();
            return;
        }

        let percentage = Math.round((tableIndex / tables.length) * 100);
        updateProgress(`Exporting DB Table: ${tables[tableIndex]}...`, percentage);

        $.post(ajaxurl, { action: 'migratequill_export_db', security: nonce, table: tables[tableIndex], offset: offset })
            .done(function(response) {
                if (response.success) {
                    if (response.data.status === 'chunk_complete') {
                        processDbTable(tables, tableIndex, response.data.next_offset, onComplete);
                    } else if (response.data.status === 'table_complete') {
                        processDbTable(tables, tableIndex + 1, 0, onComplete);
                    }
                } else {
                    handleAjaxError(null, null, response.data || 'Failed to export table');
                }
            })
            .fail(handleAjaxError);
    }

    // ==========================================
    // 3. FILE CHUNKING
    // ==========================================
    function startFilesExport(onComplete) {
        updateProgress('Scanning files to compress...', 0);
        processFileBatch(0, onComplete);
    }

    function processFileBatch(batchIndex, onComplete) {
        $.post(ajaxurl, { action: 'migratequill_export_files', security: nonce, batch_index: batchIndex })
            .done(function(response) {
                if (response.success) {
                    if (response.data.status === 'init_complete') {
                        totalFilesToZip = response.data.total_files; 
                        processFileBatch(1, onComplete);
                    } else if (response.data.status === 'chunk_zipped') {
                        let filesProcessed = batchIndex * 200;
                        if (filesProcessed > totalFilesToZip) filesProcessed = totalFilesToZip;
                        let percentage = Math.round((filesProcessed / totalFilesToZip) * 100);
                        
                        updateProgress(`Zipping files (${filesProcessed} of ${totalFilesToZip})...`, percentage);
                        processFileBatch(response.data.next_batch_index, onComplete);
                    } else if (response.data.status === 'all_files_zipped') {
                        updateProgress('Files compressed!', 100);
                        if (onComplete) onComplete();
                    }
                } else {
                    handleAjaxError(null, null, response.data || 'Failed to compress files');
                }
            })
            .fail(handleAjaxError);
    }

    // ==========================================
    // 4. CLEANUP & DOWNLOAD
    // ==========================================
    function cleanUpExport() {
        updateProgress('Finalizing ZIP archive...', 100);
        
        $.post(ajaxurl, { action: 'migratequill_clean_export', security: nonce })
            .done(function(response) {
                if (response.success) {
                    updateProgress('Export Complete! Download below.', 100);
                    $progressBar.css('background', '#00a32a'); 
                    $exportStatus.css('color', '#00a32a');
                    
                    let downloadUrl = ajaxurl.replace('admin-ajax.php', 'admin-post.php') + 
                                      '?action=migratequill_download&file=' + response.data.filename + 
                                      '&_wpnonce=' + migratequillData.download_nonce;
                    
                    $downloadBtn.attr('href', downloadUrl);
                    $downloadWrap.fadeIn();
                    $exportBtn.prop('disabled', false);

                    setTimeout(function() { location.reload(); }, 4000);
                } else {
                    handleAjaxError(null, null, response.data || 'Cleanup failed');
                }
            })
            .fail(handleAjaxError);
    }

    // ==========================================
    // 5. DELETE BACKUP
    // ==========================================
    $(document).on('click', '.mq-delete-backup', function(e) {
        e.preventDefault();
        if (!confirm('Are you sure you want to delete this backup?')) return;

        let $btn = $(this);
        let $row = $btn.closest('tr');
        let filename = $row.data('filename');

        $btn.text('Deleting...').prop('disabled', true);

        $.post(ajaxurl, { action: 'migratequill_delete_backup', security: nonce, filename: filename })
            .done(function(response) {
                if (response.success) {
                    $row.fadeOut(400, function() { 
                        $(this).remove(); 
                        if ($('#mq-backup-list tr').length === 0) {
                            $('#mq-backup-list').append('<tr><td colspan="4" style="padding: 20px; text-align: center;">No backups found.</td></tr>');
                        }
                    });
                } else {
                    alert('Error: ' + response.data);
                    $btn.text('Delete').prop('disabled', false);
                }
            })
            .fail(function() {
                alert('A server error occurred. The file could not be deleted.');
                $btn.text('Delete').prop('disabled', false);
            });
    });

    // ==========================================
    // 6. IMPORT UPLOAD (CHUNKED) & RESTORE
    // ==========================================
    $importBtn.on('click', function(e) {
        e.preventDefault();
        
        let fileInput = $('#mq-import-file')[0].files[0];
        if (!fileInput) {
            alert('Please select a MigrateQuill .zip backup file first.');
            return;
        }

        $importBtn.prop('disabled', true);
        $importProgressBar.css('background', '#2271b1').css('width', '0%');
        $importStatusText.css('color', '#2271b1');

        // File Chunking Setup (2MB pieces)
        const chunkSize = 2 * 1024 * 1024; 
        const totalChunks = Math.ceil(fileInput.size / chunkSize);
        
        uploadChunk(fileInput, 0, chunkSize, totalChunks);
    });

    function uploadChunk(file, currentChunk, chunkSize, totalChunks) {
        let start = currentChunk * chunkSize;
        let end = Math.min(start + chunkSize, file.size);
        let chunk = file.slice(start, end);

        let formData = new FormData();
        formData.append('action', 'migratequill_upload_chunk');
        formData.append('security', nonce);
        formData.append('file_chunk', chunk);
        formData.append('chunk_index', currentChunk);
        formData.append('total_chunks', totalChunks);

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: formData,
            contentType: false,
            processData: false,
            success: function(response) {
                if (response.success) {
                    
                    let percentComplete = Math.round(((currentChunk + 1) / totalChunks) * 100);
                    let displayPercent = Math.floor(percentComplete / 2); // Upload takes up 0-50% of the bar
                    
                    updateImportProgress('Uploading archive (' + percentComplete + '%)...', displayPercent);

                    if (response.data.status === 'chunk_saved') {
                        uploadChunk(file, currentChunk + 1, chunkSize, totalChunks);
                    } else if (response.data.status === 'complete') {
                        updateImportProgress('Upload Complete! Extracting files (This may take a minute)...', 55);
                        runImportExtraction();
                    }
                } else {
                    updateImportProgress('Upload failed: ' + response.data, 100);
                    $importProgressBar.css('background', '#d63638');
                    $importStatusText.css('color', '#d63638');
                    $importBtn.prop('disabled', false);
                }
            },
            error: function(xhr, status, error) {
                updateImportProgress('Chunk upload failed (' + xhr.status + '). Check firewall logs.', 100);
                $importProgressBar.css('background', '#d63638');
                $importStatusText.css('color', '#d63638');
                $importBtn.prop('disabled', false);
            }
        });
    }

    function runImportExtraction() {
        $.post(ajaxurl, { action: 'migratequill_run_import', security: nonce })
            .done(function(response) {
                if (response.success) {
                    updateImportProgress('Import Successful! Data restored.', 100);
                    $importProgressBar.css('background', '#00a32a'); 
                    $importStatusText.css('color', '#00a32a');
                } else {
                    updateImportProgress('Error: ' + response.data, 100);
                    $importProgressBar.css('background', '#d63638'); 
                    $importStatusText.css('color', '#d63638');
                    $importBtn.prop('disabled', false);
                }
            })
            .fail(function() {
                updateImportProgress('Server timed out during extraction. Check logs.', 100);
                $importProgressBar.css('background', '#d63638');
                $importStatusText.css('color', '#d63638');
                $importBtn.prop('disabled', false);
            });
    }
});<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://testing.wpcodequill.com/wp-sitemap.xsl" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>https://testing.wpcodequill.com/</loc><lastmod>2026-05-21T06:38:28+00:00</lastmod></url></urlset>
