<?php

declare(strict_types=1);

namespace BotGuard\Controllers\Admin;

use BotGuard\Core\Auth;
use BotGuard\Core\Controller;
use BotGuard\Core\Csrf;
use BotGuard\Core\Request;
use BotGuard\Core\Response;
use BotGuard\Core\Session;
use BotGuard\Core\View;
use BotGuard\Models\AuditLog;
use BotGuard\Services\BackupService;
use Throwable;

/**
 * Admin: create, download and delete database backups.
 */
final class BackupController extends Controller
{
    public function __construct(
        View $view,
        Session $session,
        Csrf $csrf,
        Request $request,
        private BackupService $backups,
        private AuditLog $audit,
        private Auth $auth,
    ) {
        parent::__construct($view, $session, $csrf, $request);
    }

    public function index(Request $request): Response
    {
        return $this->render('admin.backups', [
            'title'   => 'Backups',
            'backups' => $this->backups->list(),
        ]);
    }

    public function create(Request $request): Response
    {
        try {
            $name = $this->backups->create();
            $this->audit->record($this->auth->id(), 'backup.created', $request->ip(), ['file' => $name]);

            return $this->redirect('/admin/backups', 'success', "Backup created: {$name}");
        } catch (Throwable $e) {
            return $this->redirect('/admin/backups', 'error', 'Backup failed: ' . $e->getMessage());
        }
    }

    public function download(Request $request): Response
    {
        $path = $this->backups->path((string) $request->query('file'));
        if ($path === null) {
            return $this->redirect('/admin/backups', 'error', 'Backup not found.');
        }

        return (new Response((string) file_get_contents($path)))
            ->withHeader('Content-Type', 'application/sql')
            ->withHeader('Content-Disposition', 'attachment; filename="' . basename($path) . '"')
            ->withHeader('Content-Length', (string) filesize($path))
            ->withHeader('Cache-Control', 'no-store');
    }

    public function delete(Request $request): Response
    {
        $name = (string) $request->input('file');
        if ($this->backups->delete($name)) {
            $this->audit->record($this->auth->id(), 'backup.deleted', $request->ip(), ['file' => $name]);

            return $this->redirect('/admin/backups', 'success', 'Backup deleted.');
        }

        return $this->redirect('/admin/backups', 'error', 'Could not delete that backup.');
    }
}
