<?php

declare(strict_types=1);

namespace PpPhp\Core\Events;

/**
 * Canonical contract for application-wide events.
 */
final class GlobalEvent
{
    /** @var array<string, mixed> */
    private array $groups;

    /** @param array<string, mixed>|null $groups */
    public function __construct(?array $groups = null)
    {
        $this->groups = EventCatalogue::enrich($groups ?? EventCatalogue::globalGroups());
    }

    /** @return array<string, mixed> */
    public function groups(): array
    {
        return $this->groups;
    }

    /** @return array<string, mixed>|null */
    public function definition(string $group, string $event): ?array
    {
        $definition = $this->groups[$group]['events'][$event] ?? null;
        return is_array($definition) ? $definition : null;
    }

    /** @return array<string, mixed> */
    public function describe(string $group, string $event, ?string $language = null): array
    {
        $definition = $this->definition($group, $event) ?? [];
        $resolvedLanguage = $language
            ?? (string) ($definition['lang'] ?? EventCatalogue::LANG_PHP);

        return [
            'scope' => 'global',
            'group' => $group,
            'event' => $event,
            'label' => (string) ($definition['label'] ?? $event),
            'language' => $resolvedLanguage,
            'signature' => $this->signature($event, $definition),
            'description' => (string) ($definition['desc'] ?? ''),
            'arguments' => (array) ($definition['args'] ?? []),
            'returns' => (string) ($definition['returns'] ?? 'void'),
        ];
    }

    /** @return array<int, array<string, mixed>> */
    public function intellisense(string $group, string $event, ?string $language = null): array
    {
        $definition = $this->definition($group, $event) ?? [];
        $resolvedLanguage = $language
            ?? (string) ($definition['lang'] ?? EventCatalogue::LANG_PHP);

        return EventIntellisense::suggestions($definition, $resolvedLanguage, [], [
            'scope' => 'global',
            'group' => $group,
            'event' => $event,
        ]);
    }

    /** @param array<string, mixed> $definition */
    private function signature(string $event, array $definition): string
    {
        $arguments = array_keys((array) ($definition['args'] ?? []));
        return $event . '(' . implode(', ', array_map('strval', $arguments)) . ')';
    }
}
