<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Services\Install;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Throwable;

final class DatabaseConnectionTester
{
    public const CONNECTION_NAME = 'dberp_install_verify';

    /**
     * 使用临时连接名验证 MySQL / MariaDB，不修改默认连接。
     *
     * @throws InstallerDatabaseConnectionException
     */
    public function testMysqlFamily(
        string $driver,
        string $host,
        int $port,
        string $database,
        string $username,
        #[\SensitiveParameter]
        ?string $password,
        string $tablePrefix = '',
    ): void {
        $password ??= '';

        $templateKey = $driver === 'mariadb' ? 'mariadb' : 'mysql';
        $template = (array) config('database.connections.'.$templateKey, []);

        $config = array_merge($template, [
            'driver' => $driver === 'mariadb' ? 'mariadb' : 'mysql',
            'host' => $host,
            'port' => (string) $port,
            'database' => $database,
            'username' => $username,
            'password' => $password,
            'prefix' => $tablePrefix,
        ]);

        Config::set('database.connections.'.self::CONNECTION_NAME, $config);
        DB::purge(self::CONNECTION_NAME);

        try {
            DB::connection(self::CONNECTION_NAME)->getPdo();
            DB::connection(self::CONNECTION_NAME)->select('select 1 as dberp_install_probe');
        } catch (Throwable) {
            throw new InstallerDatabaseConnectionException(
                '无法连接到数据库，请核对主机、端口、库名、用户名与密码后重试。若问题持续，请联系服务器管理员。'
            );
        } finally {
            DB::disconnect(self::CONNECTION_NAME);
            DB::purge(self::CONNECTION_NAME);
            $this->removeTemporaryConnectionConfig();
        }
    }

    private function removeTemporaryConnectionConfig(): void
    {
        $connections = (array) Config::get('database.connections', []);
        unset($connections[self::CONNECTION_NAME]);
        Config::set('database.connections', $connections);
    }
}
