<?php

namespace App\Installer\Services;

use Exception;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Database Setup Service
 * Handles database connection and migration
 */
class DatabaseSetup
{
    /**
     * Test database connection
     */
    public function testConnection(array $config): array
    {
        try {
            // Parse host and port (handle format like "127.0.0.1:3307")
            $host = $config['host'];
            $port = $config['port'] ?? 3306;

            if (strpos($host, ':') !== false) {
                [$host, $port] = explode(':', $host, 2);
                $port = (int) $port;
            }

            // Temporarily set database config
            Config::set('database.connections.mysql_test', [
                'driver' => 'mysql',
                'host' => $host,
                'port' => $port,
                'database' => $config['database'],
                'username' => $config['username'],
                'password' => $config['password'] ?? '',
                'charset' => 'utf8mb4',
                'collation' => 'utf8mb4_unicode_ci',
            ]);

            // Test connection
            DB::connection('mysql_test')->getPdo();

            // Test if we can query
            DB::connection('mysql_test')->select('SELECT 1');

            return [
                'success' => true,
                'message' => 'Connection successful',
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Save database configuration to .env file
     */
    public function saveDatabaseConfig(array $config): bool
    {
        try {
            $envPath = base_path('.env');

            if (! file_exists($envPath)) {
                if (file_exists(base_path('.env.example'))) {
                    copy(base_path('.env.example'), $envPath);
                } else {
                    // Create basic .env file
                    file_put_contents($envPath, 'APP_NAME=ProInvoice'.PHP_EOL);
                }
            }

            $envContent = file_get_contents($envPath);

            // Parse host and port
            $host = $config['host'];
            $port = $config['port'] ?? 3306;

            if (strpos($host, ':') !== false) {
                [$host, $port] = explode(':', $host, 2);
                $port = (int) $port;
            }

            // Escape password for .env file
            $password = $config['password'] ?? '';
            if (! empty($password) && ! preg_match('/^["\'].*["\']$/', $password)) {
                $password = '"'.addslashes($password).'"';
            }

            // Update database configuration
            $patterns = [
                '/^DB_CONNECTION=.*/m' => 'DB_CONNECTION=mysql',
                '/^DB_HOST=.*/m' => 'DB_HOST='.$host,
                '/^DB_PORT=.*/m' => 'DB_PORT='.$port,
                '/^DB_DATABASE=.*/m' => 'DB_DATABASE='.$config['database'],
                '/^DB_USERNAME=.*/m' => 'DB_USERNAME='.$config['username'],
                '/^DB_PASSWORD=.*/m' => 'DB_PASSWORD='.$password,
            ];

            foreach ($patterns as $pattern => $replacement) {
                if (preg_match($pattern, $envContent)) {
                    $envContent = preg_replace($pattern, $replacement, $envContent);
                } else {
                    $envContent .= PHP_EOL.$replacement;
                }
            }

            file_put_contents($envPath, $envContent);

            // Clear config cache
            if (function_exists('opcache_reset')) {
                opcache_reset();
            }

            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Run database migrations, then ensure public/storage → storage/app/public symlink exists.
     */
    public function runMigrations(): array
    {
        try {
            // Reload config to get new database settings
            Artisan::call('config:clear');
            Artisan::call('migrate', ['--force' => true]);

            $message = 'Migrations completed successfully.';
            $linkExit = Artisan::call('storage:link', [
                '--force' => true,
            ]);
            if ($linkExit === 0) {
                $message .= ' Public storage symlink created.';
            } else {
                Log::warning('Installer: storage:link exited non-zero', ['code' => $linkExit]);
                $message .= ' Run `php artisan storage:link` manually if uploads or logos do not load.';
            }

            return [
                'success' => true,
                'message' => $message,
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }
}
