<?php

namespace App\Services;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;

class InstallerService
{
    public function requirements(): array
    {
        return [
            'php' => version_compare(PHP_VERSION, '8.2.0', '>='),
            'extensions' => [
                'openssl' => extension_loaded('openssl'),
                'pdo' => extension_loaded('pdo'),
                'mbstring' => extension_loaded('mbstring'),
                'tokenizer' => extension_loaded('tokenizer'),
                'xml' => extension_loaded('xml'),
                'ctype' => extension_loaded('ctype'),
                'json' => extension_loaded('json'),
                'curl' => extension_loaded('curl'),
            ],
            'storage_writable' => is_writable(storage_path()),
            'cache' => config('cache.default') !== null,
            'queue' => config('queue.default') !== null,
        ];
    }

    public function testDatabase(array $config): bool
    {
        config([
            'database.connections.installer' => [
                'driver' => $config['driver'] ?? 'mysql',
                'host' => $config['host'] ?? '127.0.0.1',
                'port' => $config['port'] ?? '3306',
                'database' => $config['database'] ?? '',
                'username' => $config['username'] ?? '',
                'password' => $config['password'] ?? '',
            ],
        ]);

        DB::purge('installer');
        DB::connection('installer')->getPdo();

        return true;
    }

    public function writeEnv(array $values): void
    {
        $envPath = base_path('.env');
        $env = File::exists($envPath) ? File::get($envPath) : '';

        foreach ($values as $key => $value) {
            $pattern = "/^{$key}=.*/m";
            $line = "{$key}={$value}";

            if (preg_match($pattern, $env)) {
                $env = preg_replace($pattern, $line, $env);
            } else {
                $env .= PHP_EOL.$line;
            }
        }

        File::put($envPath, $env);
    }

    public function migrateAndSeed(): void
    {
        Artisan::call('migrate', ['--force' => true]);
        Artisan::call('db:seed', ['--force' => true]);
    }

    public function markInstalled(): void
    {
        File::put(storage_path('app/installed.lock'), now()->toDateTimeString());
    }
}
