<?php

declare(strict_types=1);

namespace PpPhp\Core\Platform\Services\Metadata;

final class MetadataFactory
{
    public static function service(array $data): ServiceMetadata
    {
        $dependencies = array_map(
            static fn (array|string $dependency): ServiceDependency => is_string($dependency)
                ? new ServiceDependency($dependency)
                : new ServiceDependency(
                    id: (string) ($dependency['id'] ?? ''),
                    optional: (bool) ($dependency['optional'] ?? false),
                    version: (string) ($dependency['version'] ?? ''),
                    metadata: is_array($dependency['metadata'] ?? null) ? $dependency['metadata'] : []
                ),
            is_array($data['dependencies'] ?? null) ? $data['dependencies'] : []
        );

        $capabilities = array_map(
            static fn (array|string $capability): CapabilityMetadata => is_string($capability)
                ? new CapabilityMetadata($capability, ucfirst(str_replace(['-', '.'], ' ', $capability)))
                : new CapabilityMetadata(
                    id: (string) ($capability['id'] ?? ''),
                    label: (string) ($capability['label'] ?? $capability['id'] ?? ''),
                    version: (string) ($capability['version'] ?? '1.0.0'),
                    description: (string) ($capability['description'] ?? ''),
                    maturity: (string) ($capability['maturity'] ?? 'stable'),
                    experimental: (bool) ($capability['experimental'] ?? false),
                    metadata: is_array($capability['metadata'] ?? null) ? $capability['metadata'] : []
                ),
            is_array($data['capabilities'] ?? null) ? $data['capabilities'] : []
        );

        $aliases = array_map(
            static fn (array|string $alias): ServiceAlias => is_string($alias)
                ? new ServiceAlias($alias, (string) ($data['id'] ?? ''))
                : new ServiceAlias((string) ($alias['alias'] ?? ''), (string) ($alias['target'] ?? $data['id'] ?? '')),
            is_array($data['aliases'] ?? null) ? $data['aliases'] : []
        );

        $tags = array_map(
            static fn (array|string $tag): ServiceTag => is_string($tag)
                ? new ServiceTag($tag)
                : new ServiceTag((string) ($tag['name'] ?? ''), is_array($tag['attributes'] ?? null) ? $tag['attributes'] : []),
            is_array($data['tags'] ?? null) ? $data['tags'] : []
        );

        return new ServiceMetadata(
            id: (string) ($data['id'] ?? ''),
            label: (string) ($data['label'] ?? $data['name'] ?? $data['id'] ?? ''),
            version: (string) ($data['version'] ?? '1.0.0'),
            description: (string) ($data['description'] ?? ''),
            dependencies: $dependencies,
            capabilities: $capabilities,
            aliases: $aliases,
            tags: $tags,
            lifecycle: (string) ($data['lifecycle'] ?? 'singleton'),
            visibility: (string) ($data['visibility'] ?? 'public'),
            lazy: (bool) ($data['lazy'] ?? true),
            metadata: is_array($data['metadata'] ?? null) ? $data['metadata'] : []
        );
    }
}
