<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Backup;

class BackupService
{
    private Backup $backupModel;

    public function __construct()
    {
        $this->backupModel = new Backup();
    }

    public function createBackup(int $userId): array
    {
        $config = require BASE_PATH . '/config/database.php';

        $filename = 'backup_' . date('Ymd_His') . '.sql';
        $subDir = STORAGE_PATH . '/backups/';
        if (!is_dir($subDir)) {
            mkdir($subDir, 0755, true);
        }
        $filePath = $subDir . $filename;

        $command = sprintf(
            'mysqldump -h %s -P %s -u %s %s %s > %s',
            escapeshellarg($config['host']),
            escapeshellarg($config['port']),
            escapeshellarg($config['user']),
            !empty($config['pass']) ? '-p' . escapeshellarg($config['pass']) : '',
            escapeshellarg($config['name']),
            escapeshellarg($filePath)
        );

        exec($command . ' 2>&1', $output, $exitCode);

        if ($exitCode !== 0 || !file_exists($filePath)) {
            throw new \RuntimeException('Error al crear el backup', 500);
        }

        $size = filesize($filePath);

        $id = $this->backupModel->createBackupRecord([
            'file_name' => $filename,
            'file_path' => $filePath,
            'type' => 'completo',
            'size_bytes' => $size,
            'created_by' => $userId,
        ]);

        return $this->backupModel->findById($id);
    }

    public function getBackups(int $page = 1, int $perPage = 20): array
    {
        return $this->backupModel->getBackups($page, $perPage);
    }

    public function downloadBackup(int $id): array
    {
        $backup = $this->backupModel->findById($id);
        if (!$backup) {
            throw new \RuntimeException('Backup no encontrado', 404);
        }
        if (!file_exists($backup['file_path'])) {
            throw new \RuntimeException('Archivo de backup no encontrado', 404);
        }
        return $backup;
    }

    public function restoreBackup(int $id): void
    {
        $backup = $this->backupModel->findById($id);
        if (!$backup) {
            throw new \RuntimeException('Backup no encontrado', 404);
        }
        if (!file_exists($backup['file_path'])) {
            throw new \RuntimeException('Archivo de backup no encontrado', 404);
        }

        $config = require BASE_PATH . '/config/database.php';

        $command = sprintf(
            'mysql -h %s -P %s -u %s %s %s < %s',
            escapeshellarg($config['host']),
            escapeshellarg($config['port']),
            escapeshellarg($config['user']),
            !empty($config['pass']) ? '-p' . escapeshellarg($config['pass']) : '',
            escapeshellarg($config['name']),
            escapeshellarg($backup['file_path'])
        );

        exec($command . ' 2>&1', $output, $exitCode);

        if ($exitCode !== 0) {
            throw new \RuntimeException('Error al restaurar el backup', 500);
        }
    }
}
