<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Artisan;
use Carbon\Carbon;

class BackupController extends Controller
{
    /**
     * Afficher la liste des sauvegardes
     */
    public function index()
    {
        $backups = [];
        
        // Lister les fichiers de sauvegarde existants
        if (Storage::exists('backups')) {
            $files = Storage::files('backups');
            foreach ($files as $file) {
                $backups[] = (object)[
                    'id' => md5($file),
                    'filename' => basename($file),
                    'path' => $file,
                    'size' => $this->formatBytes(Storage::size($file)),
                    'created_at' => Carbon::createFromTimestamp(Storage::lastModified($file)),
                ];
            }
        }
        
        // Trier par date décroissante
        usort($backups, fn($a, $b) => $b->created_at <=> $a->created_at);

        return view('admin.backups.index', compact('backups'));
    }

    /**
     * Créer une nouvelle sauvegarde
     */
    public function create()
    {
        try {
            // Créer le dossier si nécessaire
            if (!Storage::exists('backups')) {
                Storage::makeDirectory('backups');
            }

            $timestamp = now()->format('Y-m-d_H-i-s');
            $filename = "backup_{$timestamp}.sql";

            // Export de la base de données (méthode simplifiée)
            $dbHost = config('database.connections.mysql.host');
            $dbName = config('database.connections.mysql.database');
            $dbUser = config('database.connections.mysql.username');
            $dbPass = config('database.connections.mysql.password');

            $command = sprintf(
                'mysqldump --host=%s --user=%s --password=%s %s > %s',
                escapeshellarg($dbHost),
                escapeshellarg($dbUser),
                escapeshellarg($dbPass),
                escapeshellarg($dbName),
                storage_path("app/backups/{$filename}")
            );

            // Note: Cette commande nécessite que mysqldump soit installé
            exec($command, $output, $returnCode);

            if ($returnCode !== 0) {
                // Alternative: sauvegarder uniquement les tables importantes via PHP
                $this->createPhpBackup($filename);
            }

            return back()->with('success', 'Sauvegarde créée avec succès: ' . $filename);
        } catch (\Exception $e) {
            \Log::error('Backup error: ' . $e->getMessage());
            return back()->with('error', 'Erreur lors de la création de la sauvegarde: ' . $e->getMessage());
        }
    }

    /**
     * Créer une sauvegarde via PHP (fallback)
     */
    private function createPhpBackup(string $filename)
    {
        $tables = \DB::select('SHOW TABLES');
        $tableKey = 'Tables_in_' . config('database.connections.mysql.database');
        
        $sql = "-- Backup créé le " . now()->toDateTimeString() . "\n";
        $sql .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";

        foreach ($tables as $table) {
            $tableName = $table->$tableKey;
            
            // Structure
            $create = \DB::select("SHOW CREATE TABLE `{$tableName}`");
            $sql .= "DROP TABLE IF EXISTS `{$tableName}`;\n";
            $sql .= $create[0]->{'Create Table'} . ";\n\n";
            
            // Données (limité pour éviter les problèmes de mémoire)
            $rows = \DB::table($tableName)->limit(10000)->get();
            foreach ($rows as $row) {
                $values = array_map(function($v) {
                    if ($v === null) return 'NULL';
                    return "'" . addslashes($v) . "'";
                }, (array)$row);
                $sql .= "INSERT INTO `{$tableName}` VALUES (" . implode(', ', $values) . ");\n";
            }
            $sql .= "\n";
        }

        $sql .= "SET FOREIGN_KEY_CHECKS = 1;\n";

        Storage::put("backups/{$filename}", $sql);
    }

    /**
     * Restaurer une sauvegarde
     */
    public function restore(Request $request, $backup)
    {
        try {
            // Trouver le fichier par ID
            $files = Storage::files('backups');
            $targetFile = null;
            
            foreach ($files as $file) {
                if (md5($file) === $backup) {
                    $targetFile = $file;
                    break;
                }
            }

            if (!$targetFile || !Storage::exists($targetFile)) {
                return back()->with('error', 'Fichier de sauvegarde introuvable.');
            }

            $sql = Storage::get($targetFile);
            
            // Exécuter la restauration
            \DB::unprepared($sql);

            return back()->with('success', 'Sauvegarde restaurée avec succès.');
        } catch (\Exception $e) {
            \Log::error('Restore error: ' . $e->getMessage());
            return back()->with('error', 'Erreur lors de la restauration: ' . $e->getMessage());
        }
    }

    /**
     * Télécharger une sauvegarde
     */
    public function download($backup)
    {
        $files = Storage::files('backups');
        
        foreach ($files as $file) {
            if (md5($file) === $backup) {
                return Storage::download($file);
            }
        }

        return back()->with('error', 'Fichier de sauvegarde introuvable.');
    }

    /**
     * Supprimer une sauvegarde
     */
    public function destroy($backup)
    {
        $files = Storage::files('backups');
        
        foreach ($files as $file) {
            if (md5($file) === $backup) {
                Storage::delete($file);
                return back()->with('success', 'Sauvegarde supprimée.');
            }
        }

        return back()->with('error', 'Fichier de sauvegarde introuvable.');
    }

    /**
     * Programmer des sauvegardes automatiques
     */
    public function schedule(Request $request)
    {
        $frequency = $request->input('frequency', 'daily');
        
        // Sauvegarder la préférence
        \App\Models\Setting::set('backup_frequency', $frequency);

        return back()->with('success', "Sauvegardes programmées: {$frequency}");
    }

    /**
     * Formater les bytes en unités lisibles
     */
    private function formatBytes($bytes, $precision = 2)
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];

        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);

        $bytes /= pow(1024, $pow);

        return round($bytes, $precision) . ' ' . $units[$pow];
    }
}
