<?php

namespace App\Http\Controllers\Install;

use App\Http\Controllers\Controller;
use App\Services\InstallerService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class InstallController extends Controller
{
    public function __construct(protected InstallerService $installer)
    {
        $this->middleware('not.installed')->except('complete');
    }

    public function welcome()
    {
        return view('install.welcome');
    }

    public function requirements()
    {
        return view('install.requirements', ['check' => $this->installer->requirements()]);
    }

    public function database()
    {
        return view('install.database');
    }

    public function testDatabase(Request $request)
    {
        $data = $request->validate([
            'connection' => ['required', 'in:mysql,sqlite'],
            'host' => ['required_if:connection,mysql'],
            'port' => ['required_if:connection,mysql'],
            'database' => ['required'],
            'username' => ['nullable'],
            'password' => ['nullable'],
        ]);

        $result = $this->installer->testConnection($data);
        $request->session()->put('install.db', $data);
        $request->session()->put('install.db_test', $result);

        if (! $result['ok']) {
            return back()->withErrors(['database' => $result['message'] ?? __('messages.db_connection_failed')])->withInput();
        }

        if ($result['has_app_tables'] && ! $request->boolean('confirm_existing')) {
            return back()->with('existing_tables', true)->withInput();
        }

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

    public function application()
    {
        if (! session('install.db')) {
            return redirect()->route('install.database');
        }

        return view('install.application');
    }

    public function admin()
    {
        if (! session('install.app')) {
            return redirect()->route('install.application');
        }

        return view('install.admin');
    }

    public function storeApplication(Request $request)
    {
        $data = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'url' => ['required', 'url'],
            'locale' => ['required', 'in:ar,en'],
            'timezone' => ['required', 'string'],
        ]);
        $request->session()->put('install.app', $data);

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

    public function install(Request $request)
    {
        $admin = $request->validate([
            'admin_name' => ['required', 'string', 'max:255'],
            'admin_email' => ['required', 'email'],
            'admin_password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);

        $db = $request->session()->get('install.db');
        $app = $request->session()->get('install.app');
        if (! $db || ! $app) {
            return redirect()->route('install.welcome');
        }

        $test = $this->installer->testConnection($db);
        if (! $test['ok']) {
            return redirect()->route('install.database')->withErrors(['database' => $test['message']]);
        }

        if ($test['has_app_tables'] && ! $request->boolean('confirm_existing')) {
            return redirect()->route('install.database')->with('existing_tables', true);
        }

        $this->installer->writeEnv($app, $db);
        $this->installer->migrateAndSeed(false);
        $this->installer->createAdmin([
            'name' => $admin['admin_name'],
            'email' => $admin['admin_email'],
            'password' => $admin['admin_password'],
            'language' => $app['locale'] ?? 'ar',
        ]);
        $this->installer->finish($app);
        $request->session()->forget(['install.db', 'install.app', 'install.db_test']);

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

    public function complete()
    {
        return view('install.complete');
    }
}
