<?php

namespace App\Http\Controllers;

use App\Services\DatabaseBackup;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Support\Facades\File;
use Illuminate\View\View;

class BackupController extends Controller implements HasMiddleware
{
    public function __construct(private DatabaseBackup $backup)
    {
    }

    public static function middleware(): array
    {
        // Backups are strictly Super Admin only.
        return [new Middleware(function (Request $request, $next) {
            abort_unless($request->user()?->isSuperAdmin(), 403, 'Only the Super Admin can manage backups.');

            return $next($request);
        })];
    }

    public function index(): View
    {
        return view('backups.index', [
            'backups' => $this->backup->list(),
            'settings' => $this->backup->settings(),
        ]);
    }

    public function create()
    {
        try {
            $name = $this->backup->create();
            $this->backup->prune($this->backup->settings()['keep'] ?? 14);

            return back()->with('success', "Backup created: {$name}");
        } catch (\Throwable $e) {
            return back()->with('error', 'Backup failed: '.$e->getMessage());
        }
    }

    public function download(string $file)
    {
        $path = $this->safePath($file);
        abort_unless(File::exists($path), 404);

        return response()->download($path);
    }

    public function destroy(string $file)
    {
        $path = $this->safePath($file);
        if (File::exists($path)) {
            File::delete($path);
        }

        return back()->with('success', 'Backup deleted.');
    }

    public function restore(Request $request)
    {
        $request->validate([
            'file' => ['required_without:existing', 'nullable', 'file', 'mimes:sql,txt', 'max:51200'],
            'existing' => ['nullable', 'string'],
        ]);

        try {
            if ($request->hasFile('file')) {
                $path = $request->file('file')->getRealPath();
            } elseif ($request->filled('existing')) {
                $path = $this->safePath($request->input('existing'));
                abort_unless(File::exists($path), 404);
            } else {
                return back()->with('error', 'Choose a backup file to restore.');
            }

            $this->backup->restore($path);

            return back()->with('success', 'Database restored successfully.');
        } catch (\Throwable $e) {
            return back()->with('error', 'Restore failed: '.$e->getMessage());
        }
    }

    public function schedule(Request $request)
    {
        $data = $request->validate([
            'enabled' => ['nullable', 'boolean'],
            'frequency' => ['required', 'in:daily,weekly,monthly'],
            'keep' => ['required', 'integer', 'min:1', 'max:365'],
        ]);
        $data['enabled'] = $request->boolean('enabled');
        $this->backup->saveSettings($data);

        return back()->with('success', 'Backup schedule updated.');
    }

    /** Resolve a filename to a path inside the backups dir (prevents traversal). */
    private function safePath(string $file): string
    {
        $file = basename($file);

        return $this->backup->dir().DIRECTORY_SEPARATOR.$file;
    }
}
