<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Services\ActivityLogService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;

class BackupController extends Controller
{
    public function __construct(
        private readonly ActivityLogService $activityLogService,
    ) {}

    public function download(): StreamedResponse|RedirectResponse
    {
        $connection = config('database.default');
        $driver = config("database.connections.{$connection}.driver");

        if ($driver === 'sqlite') {
            $database = config("database.connections.{$connection}.database");
            $filename = 'backup_'.now()->format('Ymd_His').'.sqlite';

            $this->activityLogService->log('backup', 'system', 'Backup database SQLite');

            return response()->download($database, $filename);
        }

        $this->activityLogService->log('backup', 'system', 'Backup database');

        $tables = DB::select('SHOW TABLES');
        $tableKey = 'Tables_in_'.config("database.connections.{$connection}.database");

        $sql = "-- e-Sijil Database Backup\n-- ".now()->toDateTimeString()."\n\n";

        foreach ($tables as $table) {
            $tableName = $table->$tableKey;
            $createTable = DB::select("SHOW CREATE TABLE `{$tableName}`");
            $sql .= $createTable[0]->{'Create Table'}.";\n\n";

            $rows = DB::table($tableName)->get();
            foreach ($rows as $row) {
                $values = collect((array) $row)->map(fn ($v) => is_null($v) ? 'NULL' : "'".addslashes($v)."'")->implode(', ');
                $sql .= "INSERT INTO `{$tableName}` VALUES ({$values});\n";
            }
            $sql .= "\n";
        }

        $filename = 'backup_'.now()->format('Ymd_His').'.sql';

        return response()->streamDownload(function () use ($sql) {
            echo $sql;
        }, $filename, ['Content-Type' => 'application/sql']);
    }

    public function maintenanceOn(): RedirectResponse
    {
        Artisan::call('down', ['--secret' => 'esijil-maintenance']);

        $this->activityLogService->log('maintenance_on', 'system', 'Mod penyelenggaraan diaktifkan');

        return back()->with('success', 'Mod penyelenggaraan telah diaktifkan.');
    }

    public function maintenanceOff(): RedirectResponse
    {
        Artisan::call('up');

        $this->activityLogService->log('maintenance_off', 'system', 'Mod penyelenggaraan dinyahaktifkan');

        return back()->with('success', 'Mod penyelenggaraan telah dinyahaktifkan.');
    }
}
