<?php

declare(strict_types=1);

namespace FleekDash\Admin\Menu;

/**
 * Removes "ghost" top-level rows whose source_slug already appears under another
 * top-level item's submenu. Does NOT merge duplicate top-level slugs — merging was
 * collapsing legitimate submenu trees (e.g. Appearance, CPT menus).
 */
final class MenuFormattedTopLevelCanonicalizer
{
    /**
     * @param array<int, array<string, mixed>> $items
     * @return array<int, array<string, mixed>>
     */
    public function canonicalize(array $items): array
    {
        return $this->removeTopLevelShadowedByPeerSubmenus($items);
    }

    /**
     * @param array<int, array<string, mixed>> $items
     * @return array<int, array<string, mixed>>
     */
    private function removeTopLevelShadowedByPeerSubmenus(array $items): array
    {
        $result = [];
        $count = \count($items);
        for ($i = 0; $i < $count; $i++) {
            $item = $items[$i];
            if ($this->shouldDropAsShadowTopLevel($items, $i, $item)) {
                continue;
            }
            $result[] = $item;
        }
        return $result;
    }

    /**
     * @param array<int, array<string, mixed>> $items
     * @param array<string, mixed> $candidate
     */
    private function shouldDropAsShadowTopLevel(array $items, int $index, array $candidate): bool
    {
        $slug = $this->readSourceSlug($candidate);
        // Plugins often add a submenu link to index.php ("Dashboard"); that must NOT remove
        // the canonical WordPress Dashboard top-level item (same source_slug).
        $drop = false;
        if ($slug !== '' && $slug !== 'index.php') {
            for ($j = 0, $n = \count($items); $j < $n; $j++) {
                if ($j === $index) {
                    continue;
                }
                if ($this->submenuTreeContainsSourceSlug($items[$j], $slug)) {
                    $drop = true;
                    break;
                }
            }
        }
        return $drop;
    }

    /**
     * @param array<string, mixed> $topLevel
     */
    private function submenuTreeContainsSourceSlug(array $topLevel, string $needle): bool
    {
        $sub = $this->readSubmenu($topLevel);
        foreach ($sub as $row) {
            if (!\is_array($row)) {
                continue;
            }
            if ($this->readSourceSlug($row) === $needle) {
                return true;
            }
            if ($this->submenuTreeContainsSourceSlug($row, $needle)) {
                return true;
            }
        }
        return false;
    }

    /** @param array<string, mixed> $item */
    private function readSourceSlug(array $item): string
    {
        return isset($item['source_slug']) && \is_string($item['source_slug'])
            ? $item['source_slug']
            : '';
    }

    /**
     * @param array<string, mixed> $item
     * @return array<int, array<string, mixed>>
     */
    private function readSubmenu(array $item): array
    {
        if (!isset($item['submenu']) || !\is_array($item['submenu'])) {
            return [];
        }
        return $item['submenu'];
    }
}
