<?php

declare(strict_types=1);

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

namespace App\Services\Plugin;

use DBCore\Support\Results\OperationResult;

/**
 * 将随产品内置的官方插件写入 core_plugins，并保留 manifest 中的目录路径等元数据。
 */
final class BundledOfficialPluginRegistrar
{
    public function __construct(
        private readonly DberpPluginDiscoveryManager $discoveryManager,
        private readonly DberpOfficialPluginGuard $officialPluginGuard,
        private readonly HostPluginLifecycleInstallService $lifecycleInstallService,
        private readonly DberpDatabasePluginRepository $repository,
    ) {}

    public function register(string $identifier): OperationResult
    {
        $normalized = trim($identifier);

        if ($normalized === '') {
            return OperationResult::failure('插件标识符不能为空。');
        }

        $this->discoveryManager->scan();

        $manifest = $this->discoveryManager->find($normalized);

        if ($manifest === null) {
            return OperationResult::failure("插件 [{$normalized}] 未在发现列表中，无法注册。");
        }

        if (! $this->officialPluginGuard->isOfficialManifest($manifest)) {
            return OperationResult::failure("插件 [{$normalized}] 未通过官方路径校验，已拒绝注册。");
        }

        $existing = $this->repository->find($normalized);

        if ($existing?->isInstalled()) {
            return OperationResult::skipped("插件 [{$normalized}] 已注册，跳过重复操作。");
        }

        /** @var array<string, mixed> $extra */
        $extra = is_array($manifest['extra'] ?? null) ? $manifest['extra'] : [];
        $pluginPath = trim((string) ($extra['path'] ?? ''));

        return $this->lifecycleInstallService->registerInstalledPlugin(
            $normalized,
            array_filter([
                'display_name' => trim((string) ($manifest['name'] ?? $normalized)),
                'path' => $pluginPath !== '' ? $pluginPath : null,
                'source' => 'bundled',
            ], static fn (mixed $value): bool => $value !== null && $value !== ''),
        );
    }
}
