<?php
/**
 * Database Backup Script - نسخ احتياطي محسّن
 * يدعم: compression, cloud upload, notifications, verification
 */

$baseDir = dirname(__DIR__);
require_once $baseDir . '/src/Core/Database.php';
require_once $baseDir . '/src/Core/Logger.php';
require_once $baseDir . '/src/Core/ErrorHandler.php';

$config = require $baseDir . '/config/config.php';
$backupConfig = $config['backup'] ?? [];
date_default_timezone_set($config['timezone'] ?? 'Asia/Baghdad');

// تهيئة Logger
$logger = new \App\Core\Logger($baseDir . '/logs/backup.log');
\App\Core\ErrorHandler::register($logger);

if (!($backupConfig['enabled'] ?? true)) {
    $logger->info("Backup disabled in config");
    exit(0);
}

$db = $config['db'];
$backupDir = $baseDir . '/backups';
if (!is_dir($backupDir)) {
    mkdir($backupDir, 0755, true);
}

$date = date('Y-m-d_H-i-s');
$filename = 'backup_' . $date . '.sql';
$filepath = $backupDir . '/' . $filename;

$host = $db['host'] ?? 'localhost';
$port = (int)($db['port'] ?? 3306);
$name = $db['name'] ?? 'lab_lims';
$user = $db['user'] ?? 'root';
$pass = $db['pass'] ?? '';

try {
    // إنشاء backup
    $passArg = $pass !== '' ? '-p' . escapeshellarg($pass) : '';
    $cmd = sprintf(
        'mysqldump -h %s -P %d -u %s %s %s > %s 2>&1',
        escapeshellarg($host),
        $port,
        escapeshellarg($user),
        $passArg,
        escapeshellarg($name),
        escapeshellarg($filepath)
    );

    exec($cmd, $output, $ret);
    
    if ($ret !== 0) {
        throw new \Exception("Backup failed: " . implode("\n", $output));
    }

    // التحقق من حجم الملف
    if (!file_exists($filepath) || filesize($filepath) < 100) {
        throw new \Exception("Backup file is too small or doesn't exist");
    }

    $logger->info("Backup created", ['file' => $filepath, 'size' => filesize($filepath)]);

    // Compression
    $compressed = false;
    if (function_exists('gzencode')) {
        $compressedFilepath = $filepath . '.gz';
        $data = file_get_contents($filepath);
        $compressedData = gzencode($data, 9);
        file_put_contents($compressedFilepath, $compressedData);
        unlink($filepath); // حذف الملف غير المضغوط
        $filepath = $compressedFilepath;
        $compressed = true;
        $logger->info("Backup compressed", ['file' => $filepath, 'size' => filesize($filepath)]);
    }

    // Cloud Upload
    if ($backupConfig['cloud_upload'] ?? false) {
        $provider = $backupConfig['cloud_provider'] ?? null;
        $bucket = $backupConfig['cloud_bucket'] ?? null;
        
        if ($provider && $bucket) {
            try {
                require_once $baseDir . '/src/Core/CloudStorage.php';
                $cloudStorage = new \App\Core\CloudStorage(
                    $provider,
                    $backupConfig['cloud_config'] ?? [],
                    $logger
                );
                $remotePath = 'backups/' . basename($filepath);
                if ($cloudStorage->upload($filepath, $remotePath)) {
                    $logger->info("Backup uploaded to cloud", ['provider' => $provider, 'bucket' => $bucket]);
                }
            } catch (\Throwable $e) {
                $logger->error("Cloud upload failed", ['error' => $e->getMessage()]);
            }
        }
    }

    // Backup Verification
    if (verifyBackup($filepath, $compressed, $logger)) {
        $logger->info("Backup verified successfully");
    } else {
        throw new \Exception("Backup verification failed");
    }

    // Retention Policy
    $retentionDays = (int)($backupConfig['retention_days'] ?? 7);
    $maxAge = $retentionDays * 86400;
    $deleted = 0;
    
    foreach (glob($backupDir . '/backup_*.*') ?: [] as $f) {
        if (filemtime($f) < time() - $maxAge) {
            unlink($f);
            $deleted++;
        }
    }
    
    if ($deleted > 0) {
        $logger->info("Old backups deleted", ['count' => $deleted]);
    }

    // Success Notification
    sendNotification('success', $filepath, filesize($filepath), $logger, $config);

    echo "Backup completed successfully: $filepath\n";
    exit(0);

} catch (\Throwable $e) {
    $logger->error("Backup failed", ['error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
    
    // Error Notification
    sendNotification('error', $filepath, 0, $logger, $config, $e->getMessage());
    
    fwrite(STDERR, "Backup failed: " . $e->getMessage() . "\n");
    exit(1);
}

// تم نقل uploadToCloud إلى CloudStorage class

/**
 * التحقق من صحة backup
 */
function verifyBackup(string $filepath, bool $compressed, \App\Core\Logger $logger): bool
{
    if (!file_exists($filepath)) {
        return false;
    }

    $size = filesize($filepath);
    if ($size < 100) {
        return false;
    }

    // محاولة فك الضغط والتحقق من المحتوى
    if ($compressed) {
        $data = @gzdecode(file_get_contents($filepath));
        if ($data === false) {
            return false;
        }
        // التحقق من وجود SQL statements
        return strpos($data, 'CREATE TABLE') !== false || strpos($data, 'INSERT INTO') !== false;
    } else {
        $data = file_get_contents($filepath);
        return strpos($data, 'CREATE TABLE') !== false || strpos($data, 'INSERT INTO') !== false;
    }
}

/**
 * إرسال إشعار
 */
function sendNotification(string $type, string $filepath, int $size, \App\Core\Logger $logger, array $config, string $error = ''): void
{
    // Email notification (if configured)
    $emailConfig = $config['email'] ?? [];
    if (!empty($emailConfig['enabled']) && !empty($emailConfig['notification_to'])) {
        try {
            require_once $baseDir . '/src/Core/EmailService.php';
            $emailService = new \App\Core\EmailService($emailConfig);
            
            $subject = $type === 'success' 
                ? 'Backup نجح - ' . date('Y-m-d H:i:s')
                : 'Backup فشل - ' . date('Y-m-d H:i:s');
            
            $message = $type === 'success'
                ? "تم إنشاء backup بنجاح.\nالملف: " . basename($filepath) . "\nالحجم: " . round($size / 1024 / 1024, 2) . " MB"
                : "فشل إنشاء backup.\nالخطأ: " . $error;
            
            $emailService->sendSimple($emailConfig['notification_to'], $subject, $message);
        } catch (\Throwable $e) {
            $logger->error("Email notification failed", ['error' => $e->getMessage()]);
        }
    }
    
    // Log notification
    if ($type === 'success') {
        $logger->info("Backup notification sent", [
            'type' => 'success',
            'file' => basename($filepath),
            'size' => $size
        ]);
    } else {
        $logger->error("Backup notification sent", [
            'type' => 'error',
            'file' => basename($filepath),
            'error' => $error
        ]);
    }
}
