<?php

declare(strict_types=1);

namespace FleekDash\Admin\Menu;

final class MenuCapabilityImpactService
{
    /**
     * @param array<int, array<string, mixed>> $items
     * @return array{unique_ids: array<int,string>, items: array<int,array<string,mixed>>}
     */
    public function findItemsForCapability(array $items, string $capability): array
    {
        $matches = [];
        $this->collectItemsForCapability($items, $capability, $matches, null);

        $uniqueIds = [];
        foreach ($matches as $match) {
            $uniqueId = isset($match['unique_id']) && \is_string($match['unique_id']) ? $match['unique_id'] : '';
            if ($uniqueId !== '') {
                $uniqueIds[$uniqueId] = $uniqueId;
            }
        }

        return [
            'unique_ids' => \array_values($uniqueIds),
            'items' => $matches,
        ];
    }

    /**
     * @param array<int, array<string, mixed>> $items
     * @param array<int, array<string, mixed>> $matches
     */
    private function collectItemsForCapability(array $items, string $capability, array &$matches, ?array $parent): void
    {
        foreach ($items as $item) {
            if (!\is_array($item)) {
                continue;
            }

            $this->collectItemMatch($item, $capability, $matches, $parent);
            $nextParent = $this->summarizeItem($item);
            if (isset($item['submenu']) && \is_array($item['submenu'])) {
                $this->collectItemsForCapability($item['submenu'], $capability, $matches, $nextParent);
            }
            if (isset($item['children']) && \is_array($item['children'])) {
                $this->collectItemsForCapability($item['children'], $capability, $matches, $nextParent);
            }
        }
    }

    /**
     * @param array<string, mixed> $item
     * @param array<int, array<string, mixed>> $matches
     */
    private function collectItemMatch(array $item, string $capability, array &$matches, ?array $parent): void
    {
        $itemCapability = isset($item['capability']) && \is_string($item['capability']) ? $item['capability'] : '';
        if ($itemCapability !== $capability) {
            return;
        }

        $summary = $this->summarizeItem($item);
        if ($parent !== null) {
            $summary['parent_id'] = $parent['unique_id'] ?? '';
            $summary['parent_name'] = $parent['name'] ?? '';
        }
        $matches[] = $summary;
    }

    /** @param array<string, mixed> $item @return array<string, mixed> */
    private function summarizeItem(array $item): array
    {
        return [
            'unique_id' => isset($item['unique_id']) && \is_string($item['unique_id']) ? $item['unique_id'] : '',
            'id' => isset($item['id']) && \is_string($item['id']) ? $item['id'] : '',
            'name' => isset($item['name']) && \is_string($item['name']) ? $item['name'] : '',
            'title' => isset($item['title']) && \is_string($item['title']) ? $item['title'] : '',
            'capability' => isset($item['capability']) && \is_string($item['capability']) ? $item['capability'] : '',
            'source_slug' => isset($item['source_slug']) && \is_string($item['source_slug']) ? $item['source_slug'] : '',
        ];
    }
}
