<?php

namespace App\Http\Controllers;

use App\Services\Installer\InstallerService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rules\Password;
use Illuminate\View\View;
use Throwable;

class InstallerController extends Controller
{
    public function index(InstallerService $installer): View
    {
        return view('installer.index', [
            'checks' => $installer->requirementChecks(),
            'requirementsPass' => $installer->requirementsPass(),
        ]);
    }

    public function store(Request $request, InstallerService $installer): RedirectResponse
    {
        $data = $request->validate([
            'app_name' => ['required', 'string', 'max:120'],
            'app_url' => ['required', 'url', 'max:2048'],
            'timezone' => ['required', 'timezone'],
            'db_host' => ['required', 'string', 'max:255'],
            'db_port' => ['required', 'integer', 'min:1', 'max:65535'],
            'db_database' => ['required', 'string', 'max:255'],
            'db_username' => ['required', 'string', 'max:255'],
            'db_password' => ['nullable', 'string', 'max:255'],
            'admin_name' => ['required', 'string', 'max:120'],
            'admin_email' => ['required', 'email', 'max:255'],
            'admin_password' => ['required', 'confirmed', Password::default()],
        ]);

        if (! $installer->requirementsPass()) {
            return back()
                ->withInput($request->except(['admin_password', 'admin_password_confirmation', 'db_password']))
                ->withErrors(['installer' => 'Fix the failed server requirement checks before installing.']);
        }

        try {
            $installer->install($data);
        } catch (Throwable $exception) {
            Log::error('RemoteMatch web installer failed.', [
                'exception' => $exception,
            ]);

            return back()
                ->withInput($request->except(['admin_password', 'admin_password_confirmation', 'db_password']))
                ->withErrors(['installer' => $exception->getMessage()]);
        }

        return redirect()->route('install.complete');
    }

    public function complete(): View
    {
        if (! app(InstallerService::class)->isInstalled()) {
            abort(404);
        }

        return view('installer.complete');
    }
}
