<?php
/**
 * Inception Database Backup & Restore
 *
 * Changes:
 * - Uses wp-content/uploads/inception-backups/ for backup storage (portable)
 * - Falls back to pure-PHP DB export/import when shell exec isn't available
 * - Fixes double-restore execution bug (restore was being called twice)
 * - Hardens shell calls with escapeshellarg() and captures stderr
 */

// -----------------------------
// Helpers (portable + fallback)
// -----------------------------

require_once INCEPTION_TECHBOOST_DIR . 'backup/inception-backup-lib.php';

// -----------------------------
// Actions
// -----------------------------

function backup_action()
{
    if (!current_user_can('manage_options')) {
        return;
    }

    check_admin_referer('backup_nonce');

    $result = inception_backup_db_php();
    $status = (int)$result['status'];
    $output = (array)$result['output'];

    if ($status !== 0) {
        echo '<div class="notice notice-error"><p>' . esc_html__('ERROR!', 'text-domain') . '</p>';
        foreach ($output as $output_line) {
            echo '<p><strong>' . esc_html($output_line) . '</strong></p>';
        }
        echo '</div>';
    } else {
        echo '<div class="notice notice-success">';
        echo '<p>' . esc_html__('Successfully Created Backup File!', 'text-domain') . '</p>';
        echo '<p><strong>' . esc_html__('Have Fun Making Your Changes!', 'text-domain') . '</strong></p>';
        echo '</div>';
    }
}

function restore_action($selectedFile)
{
    if (!current_user_can('manage_options')) {
        return [
            'status' => 1,
            'output' => ['Access denied.'],
        ];
    }

    // Accept either our custom field OR the default _wpnonce (some setups strip custom fields)
    $nonce = '';
    if (isset($_POST['restore_nonce_field'])) {
        $nonce = trim((string)wp_unslash($_POST['restore_nonce_field']));
    } elseif (isset($_POST['_wpnonce'])) {
        $nonce = trim((string)wp_unslash($_POST['_wpnonce']));
    }

    if ($nonce === '' || !wp_verify_nonce($nonce, 'restore_nonce')) {
        return [
            'status' => 1,
            'output' => [
                'Security check failed (nonce missing/invalid). Please refresh this page and try again.',
                'If this persists, a security/caching plugin may be stripping POST fields on admin pages.',
            ],
        ];
    }

    $selectedFile = (string)$selectedFile;
    if ($selectedFile === '') {
        return [
            'status' => 1,
            'output' => ['No restore file selected.'],
        ];
    }

    // Deep restore if we can locate a matching uploads zip (closest in time)
    $zipCandidate = function_exists('inception_find_matching_uploads_zip_for_sql')
        ? inception_find_matching_uploads_zip_for_sql($selectedFile)
        : '';

    if ($zipCandidate !== '') {
        $result = inception_restore_deep_backup_php($selectedFile);
    } else {
        $result = inception_restore_db_php($selectedFile);
    }

    return [
        'status' => (int)($result['status'] ?? 1),
        'output' => (array)($result['output'] ?? []),
    ];
}

// -----------------------------
// Handle submissions (run once)
// -----------------------------

$restore_result = null;

if (isset($_POST['action'])) {
    $action = sanitize_text_field((string)$_POST['action']);

    if ($action === 'backup') {
        backup_action();
    }

    if ($action === 'restore' && isset($_POST['confirm_restore'])) {
        $selectedFile = isset($_POST['restore_file']) ? sanitize_text_field((string)$_POST['restore_file']) : '';
        $restore_result = restore_action($selectedFile);
    }
}


// -----------------------------
// UI
// -----------------------------
?>
<div class="wrap">
    <h1>Inception Database Backup & Restore</h1>

    <!-- Initially hidden "Please Wait" GIF -->
    <div id="please-wait" style="opacity: 0; height: 0; overflow: hidden; transition: opacity 1s, height 1s;">
        <p><img src="<?php echo esc_url(plugins_url('please-wait.gif', __FILE__)); ?>" alt="Please wait" style="width: 400px;" /></p>
    </div>

    <p>To make a local backup of this site, please click the Backup Now button.</p>

    <form method="post" action="">
        <input type="hidden" name="action" value="backup">
        <?php wp_nonce_field('backup_nonce'); ?>
        <?php submit_button('Backup Now'); ?>
    </form>

    <br>

    <?php
    // Show restore success/error message (if restore ran)
    if (is_array($restore_result)) {
        $status = (int)$restore_result['status'];
        $output = (array)$restore_result['output'];

        if ($status === 0) {
            echo '<div class="notice notice-success"><p>' . esc_html__('Successfully Restored Backup!', 'text-domain') . '</p>';
            foreach ($output as $line) {
                echo '<p><strong>' . esc_html($line) . '</strong></p>';
            }
            echo '</div>';
        } else {
            echo '<div class="notice notice-error"><p>' . esc_html__('Error Restoring Backup!', 'text-domain') . '</p>';
            foreach ($output as $line) {
                echo '<p><strong>' . esc_html($line) . '</strong></p>';
            }
            echo '</div>';
        }
    }

    // Portable backup directory (uploads)
    $backupDir = inception_backup_dir();
    
    $sqlFiles = glob(trailingslashit($backupDir) . '*.sql') ?: [];
    
    if (!empty($sqlFiles)) {
        ?>
        <p>To restore from a backup, please select a backup file and click the Restore Backup button.</p>
        <form method="post" action="<?php echo esc_url(menu_page_url('inception-techboost-backup', false)); ?>">
            <input type="hidden" name="action" value="restore">
        
            <?php
            // Custom-named nonce (nice to avoid collisions)
            wp_nonce_field('restore_nonce', 'restore_nonce_field', true, true);
        
            // Default WP nonce name fallback (_wpnonce) in case something strips custom fields
            wp_nonce_field('restore_nonce');
            ?>
        
            <select name="restore_file">
                <?php
                usort($sqlFiles, function ($a, $b) {
                    return filemtime($b) - filemtime($a);
                });

                $backupDir = inception_backup_dir();
                
                foreach ($sqlFiles as $file) {
                    $timezone = new DateTimeZone('America/Chicago');
                    $filename = basename($file);
                    $fileModifiedTime = filemtime($file);
                    $dateTime = new DateTime("@$fileModifiedTime");
                    $dateTime->setTimezone($timezone);
                    $fileCreated = $dateTime->format('m-d-Y h:i:s A');
                
                    // Deep restore is defined by whether we can locate a matching uploads zip
                    $zipCandidate = function_exists('inception_find_matching_uploads_zip_for_sql')
                        ? inception_find_matching_uploads_zip_for_sql($filename)
                        : '';
                
                    $isDeep = ($zipCandidate !== '');
                    $label  = $isDeep ? 'Deep Restore' : 'Regular Restore';
                
                    echo '<option value="' . esc_attr($filename) . '">'
                        . esc_html("{$label} — {$fileCreated}")
                        . '</option>';
                }
                ?>
            </select>

            <?php submit_button('Restore Backup', 'button', 'confirm_restore', false, array('onclick' => 'return confirmRestore();')); ?>
        </form>
        <?php
    } else {
        echo '<p>Could not find any local backup files for this site to restore from. All local backup files are removed after 48 hours.</p>';
    }
    ?>
</div>

<script>
    function confirmRestore() {
        if (confirm("Are you sure you want to restore the backup?")) {
            showGif();
            return true;
        } else {
            return false;
        }
    }

    function showGif() {
        var gifContainer = document.getElementById('please-wait');
        gifContainer.style.opacity = '1';
        gifContainer.style.height = 'auto';
    }
</script>
