<?php
/**
 * Script de backup automatique pour toutes les compagnies.
 * À planifier via cron (Linux) ou Tâche planifiée (Windows).
 * Exemple cron: 0 2 * * * /usr/bin/php /path/to/backup_cron.php
 * Sous Windows (PowerShell): php C:\wamp64\www\hiba\backup_cron.php
 */

// S'assurer que les chemins relatifs pointent vers le dossier du script (important en cron)
chdir(__DIR__);
@set_time_limit(0);
@ini_set('memory_limit','512M');

// Fonction de log harmonisée avec backup.php (INFO / SUCCESS / ERROR, rétention 80 lignes)
function writeCompagnieLog($compagnieRef, $message, $type = 'INFO') {
    // Ignorer désormais les messages INFO pour ne garder que SUCCESS / ERROR
    if ($type === 'INFO') {
        return;
    }
    try {
        $logDir = 'backup';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
        $logFile = "$logDir/{$compagnieRef}_backup.log";
        $timestamp = date('Y-m-d H:i:s');
        $logEntry = "[$timestamp] [$type] $message" . PHP_EOL;

        $existingLogs = [];
        if (file_exists($logFile)) {
            $lines = file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            if ($lines !== false) {
                $existingLogs = $lines;
            }
        }
        $existingLogs[] = rtrim($logEntry);
        if (count($existingLogs) > 80) {
            $existingLogs = array_slice($existingLogs, -80);
        }
        file_put_contents($logFile, implode(PHP_EOL, $existingLogs) . PHP_EOL, LOCK_EX);
    } catch (Exception $e) {
        error_log("Erreur écriture log compagnie $compagnieRef: " . $e->getMessage());
    }
}

// Fonction pour obtenir la liste des compagnies
function getCompagnies() {
    try {
        // Connexion spécifique à la base assurance_gestion
        $host = 'localhost';
        $username = 'root';
        $password = '';
        $gestionDbName = 'assurance_gestion';

        $dsn = "mysql:host=$host;dbname=$gestionDbName;charset=utf8";
        $gestionPdo = new PDO($dsn, $username, $password, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
        ]);

        // Récupérer les infos de connexion de chaque compagnie
        $stmt = $gestionPdo->query("SELECT compagnie_ref, compagnie_db, compagnie_db_user, compagnie_db_pass FROM compagnies_table WHERE active = 1");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Erreur récupération compagnies: " . $e->getMessage());
        return [];
    }
}

// Fonction pour créer un backup automatique pour une compagnie

function createAutoBackup($compagnieRef, $compagnieDb, $compagnieDbUser, $compagnieDbPass) {
    try {
        $host = 'localhost';
        $dbName = $compagnieDb;
        $username = $compagnieDbUser;
        $password = $compagnieDbPass;
        $dsn = "mysql:host=$host;dbname=$dbName;charset=utf8";
        $pdo = new PDO($dsn, $username, $password, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
        ]);

        $backupDir = "backup/$compagnieRef";
        if (!is_dir($backupDir)) {
            mkdir($backupDir, 0755, true);
        }

        // Rotation: garder 5 backups auto récents
        $files = glob("$backupDir/backup_auto_*.zip");
        if (count($files) >= 5) {
            usort($files, function($a, $b) { return filemtime($a) - filemtime($b); });
            while (count($files) >= 5) {
                $oldFile = array_shift($files);
                @unlink($oldFile);
            }
        }

        $timestamp = date('Y-m-d_H-i-s');
        $zipFile = "$backupDir/backup_auto_$timestamp.zip";

        if (!is_dir('backup/temp')) {
            mkdir('backup/temp', 0755, true);
        }
        $tempSqlFile = 'backup/temp/backup_auto_sql_' . time() . '.sql';

        // Dump SQL (structure + données)
        $stmt = $pdo->query('SHOW TABLES');
        $tables = $stmt->fetchAll(PDO::FETCH_COLUMN);
        $sql = "-- Backup automatique de la base de données\n";
        $sql .= '-- Date: ' . date('Y-m-d H:i:s') . "\n";
        $sql .= "-- Compagnie: $compagnieRef\n";
        $sql .= "-- Base: $dbName\n\n";

        foreach ($tables as $table) {
            $stmt = $pdo->query("SHOW CREATE TABLE `$table`");
            $createTable = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!isset($createTable['Create Table'])) {
                continue; // table non lisible
            }
            $sql .= "DROP TABLE IF EXISTS `$table`;\n";
            $sql .= $createTable['Create Table'] . ";\n\n";

            $stmt = $pdo->query("SELECT * FROM `$table`");
            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
            if ($rows) {
                $sql .= "INSERT INTO `$table` VALUES\n";
                $values = [];
                foreach ($rows as $row) {
                    $escapedValues = array_map(function($value) use ($pdo) {
                        return $value === null ? 'NULL' : $pdo->quote($value);
                    }, $row);
                    $values[] = '(' . implode(', ', $escapedValues) . ')';
                }
                $sql .= implode(",\n", $values) . ";\n\n";
            }
        }

        file_put_contents($tempSqlFile, $sql);

        $zip = new ZipArchive();
        if ($zip->open($zipFile, ZipArchive::CREATE) !== true) {
            @unlink($tempSqlFile);
            throw new Exception("Impossible de créer le fichier ZIP pour $compagnieRef");
        }
        writeCompagnieLog($compagnieRef, "[AUTO] Ouverture ZIP: $zipFile", 'INFO');

        $zip->addFile($tempSqlFile, "database_backup_auto_$timestamp.sql");

        $sourceDir = "data/$compagnieRef";
        $fileCount = 0;
        if (is_dir($sourceDir)) {
            $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sourceDir), RecursiveIteratorIterator::LEAVES_ONLY);
            foreach ($iterator as $file) {
                if (!$file->isDir()) {
                    $filePath = $file->getRealPath();
                    $relativePath = 'files/' . substr($filePath, strlen(realpath($sourceDir)) + 1);
                    $zip->addFile($filePath, $relativePath);
                    $fileCount++;
                }
            }
        }
        $zip->close();
        @unlink($tempSqlFile);

        $zipFileName = basename($zipFile);
        $fileSize = number_format(filesize($zipFile) / 1024, 1);
        writeCompagnieLog($compagnieRef, "Backup automatique réussi: $zipFileName ({$fileSize} KB, $fileCount fichiers)", 'SUCCESS');
        return true;
    } catch (Exception $e) {
        writeCompagnieLog($compagnieRef, 'Backup automatique échoué: ' . $e->getMessage(), 'ERROR');
        error_log('Erreur backup automatique pour ' . $compagnieRef . ': ' . $e->getMessage());
        return false;
    }
}

// Script principal
try {
    echo "=== DEBUT DU BACKUP AUTOMATIQUE ===\n";
    echo "Date: " . date('Y-m-d H:i:s') . "\n\n";
    
    // Récupérer la liste des compagnies actives
    $compagnies = getCompagnies();
    
    if (empty($compagnies)) {
        echo "Aucune compagnie active trouvée.\n";
        exit(1);
    }
    
    echo "Compagnies trouvées: " . count($compagnies) . "\n\n";
    
    $successCount = 0;
    $errorCount = 0;
    
    // Traiter chaque compagnie
    foreach ($compagnies as $compagnie) {
        $compagnieRef = $compagnie['compagnie_ref'];
        $compagnieDb = $compagnie['compagnie_db'];
        $compagnieDbUser = $compagnie['compagnie_db_user'];
        $compagnieDbPass = $compagnie['compagnie_db_pass'];

        echo "Traitement de la compagnie: $compagnieRef\n";

        $result = createAutoBackup($compagnieRef, $compagnieDb, $compagnieDbUser, $compagnieDbPass);

        if ($result) {
            echo "✅ Backup réussi pour $compagnieRef\n";
            $successCount++;
        } else {
            echo "❌ Backup échoué pour $compagnieRef\n";
            $errorCount++;
        }

        echo "---\n";
    }
    
    echo "\n=== RESUME ===\n";
    echo "Backups réussis: $successCount\n";
    echo "Backups échoués: $errorCount\n";
    echo "Total traité: " . count($compagnies) . "\n";
    echo "\n=== FIN DU BACKUP AUTOMATIQUE ===\n";
    
    // Code de sortie : 0 si tout s'est bien passé, 1 s'il y a eu des erreurs
    exit($errorCount > 0 ? 1 : 0);
    
} catch (Exception $e) {
    echo "ERREUR CRITIQUE: " . $e->getMessage() . "\n";
    error_log("Erreur critique backup_cron.php: " . $e->getMessage());
    exit(1);
}
?>
