<?php

declare(strict_types=1);

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

namespace App\Services\Plugin;

/**
 * 官方插件目录条目（已归一化字段）。
 */
final class HostPluginCatalogItem
{
    /**
     * @param  list<string>  $compatibleDberpVersions
     */
    public function __construct(
        public readonly string $pluginCode,
        public readonly string $pluginName,
        public readonly ?string $latestVersion,
        public readonly ?string $description,
        public readonly array $compatibleDberpVersions,
        public readonly ?string $requiredLicense,
        public readonly string $availability,
        public readonly ?string $changelog,
        public readonly ?string $remoteReasonCode = null,
    ) {}

    /**
     * @param  array<string, mixed>  $payload
     */
    public static function fromRemotePayload(array $payload): self
    {
        $code = self::firstString($payload, ['plugin_code', 'code', 'identifier', 'alias']);

        return new self(
            pluginCode: $code ?? '',
            pluginName: self::firstString($payload, ['plugin_name', 'name', 'title']) ?? ($code ?? ''),
            latestVersion: self::firstString($payload, ['latest_version', 'version']),
            description: self::firstString($payload, ['description', 'summary']),
            compatibleDberpVersions: self::stringList($payload['compatible_dberp_versions'] ?? $payload['compatible_versions'] ?? []),
            requiredLicense: self::firstString($payload, ['required_license', 'license_required']),
            availability: self::firstString($payload, ['availability_state', 'availability', 'status']) ?? 'unknown',
            changelog: self::firstString($payload, ['changelog', 'release_notes']),
            remoteReasonCode: self::firstString($payload, ['reason_code', 'availability_reason']),
        );
    }

    /**
     * @param  array<string, mixed>  $payload
     * @param  list<string>  $keys
     */
    private static function firstString(array $payload, array $keys): ?string
    {
        foreach ($keys as $key) {
            $value = $payload[$key] ?? null;

            if (is_string($value) && trim($value) !== '') {
                return trim($value);
            }
        }

        return null;
    }

    /**
     * @return list<string>
     */
    private static function stringList(mixed $value): array
    {
        if (! is_array($value)) {
            return [];
        }

        $items = [];

        foreach ($value as $item) {
            if (is_string($item) && trim($item) !== '') {
                $items[] = trim($item);
            }
        }

        return array_values(array_unique($items));
    }
}
