<?php

declare(strict_types=1);

namespace FleekDash\Admin\Menu;

/**
 * Menu Source Resolver
 *
 * Resolves menu and submenu from snapshot, rebuild, or stale snapshot.
 * Used by MenuDataAPI to obtain menu data with fallback priority.
 *
 * @package FleekDash\Admin\Menu
 */
class MenuSourceResolver
{
    public function __construct(private MenuCaptureService $menuCapture)
    {
    }

    /**
     * Resolve menu and submenu from snapshot only.
     *
     * @param bool $allowStaleSnapshotFallback When false, stale snapshots are ignored.
     * @return array{0: array, 1: array, 2: string} [menu, submenu, source]
     */
    public function resolve(bool $allowStaleSnapshotFallback = true): array
    {
        $user_id = (int) \get_current_user_id();
        $menu = [];
        $submenu = [];
        $source = 'missing_snapshot';
        if ($user_id > 0) {
            $source = $this->resolveSnapshotSource($user_id, $menu, $submenu, $allowStaleSnapshotFallback);
        }
        return [$menu, $submenu, $source];
    }

    private function resolveSnapshotSource(
        int $user_id,
        array &$menu,
        array &$submenu,
        bool $allowStaleSnapshotFallback,
    ): string {
        // Once per resolve(): avoid clearing/reloading in-memory state on every trySnapshot attempt.
        // Concurrency note: MenuCaptureService state is request-scoped (new instance per PHP request),
        // so this clear/load sequence does not leak snapshot state across users under normal FPM/Apache execution.
        // If runtime model changes to shared long-lived workers, this assumption must be revisited.
        $this->menuCapture->clearInMemoryCache();
        if ($this->trySnapshot($user_id, false, $menu, $submenu)) {
            return 'snapshot_fresh';
        }
        if ($allowStaleSnapshotFallback && $this->trySnapshot($user_id, true, $menu, $submenu)) {
            return 'snapshot_stale';
        }
        return 'missing_snapshot';
    }

    private function trySnapshot(int $user_id, bool $allowStale, array &$menu, array &$submenu): bool
    {
        if (!$this->menuCapture->loadSnapshotForUser($user_id, $allowStale)) {
            return false;
        }
        $menu = $this->menuCapture->getStoredMenu();
        $submenu = $this->menuCapture->getStoredSubmenu();
        return true;
    }
}
