<?php

declare(strict_types=1);

namespace FleekDash\API;

use FleekDash\Admin\Menu\MenuCaptureService;
use FleekDash\Admin\Menu\MenuSnapshotUserMeta;

/**
 * Server-side snapshot invalidation ({@see MenuSnapshotUserMeta::markAllStale}) and SPA cache hints.
 *
 * **Related (different layers; not duplicates):**
 * - **user_meta stale flags** — this service + {@see MenuChangeNotifier::invalidateMenuAndToolbarSnapshots()}:
 *   persisted snapshots marked stale so the next real wp-admin request can recapture.
 * - **fleekdash_invalidate_frontend_cache** (option timestamp) — bumped by MenuChangeNotifier and others;
 *   read in {@see self::buildCacheStatusPayload()} vs `fleekdash_last_cache_check` so the client knows
 *   “something changed” for polling / localStorage.
 * - **postMessage / MessageBus** — iframe notifies the SPA immediately; does not replace DB stale or options.
 *
 * A single PHP entry point for “mark snapshots + bump option” could wrap the first two; MessageBus stays client-side.
 */
class MenuCacheLifecycleService
{
    public function __construct(
        private MenuCaptureService $menuCapture,
    ) {
    }

    public function invalidateSnapshots(string $context): void
    {
        try {
            // Preserve snapshots as stale so the API can still serve deterministic data
            // during rebuild windows (no "minimal menu" fallback).
            MenuSnapshotUserMeta::markAllStale();
        } catch (\Throwable $e) {
            if (\defined('WP_DEBUG') && WP_DEBUG) {
                \error_log("[FleekDash MenuDataAPI] Failed to invalidate snapshots in {$context}: " . $e->getMessage());
            }
        }
    }

    /** @return array{payload: array<string,mixed>} */
    public function executeSnapshotInvalidation(): array
    {
        try {
            MenuSnapshotUserMeta::markAllStale();
            $this->menuCapture->clearInMemoryCache();

            return [
                'payload' => [
                    'success' => true,
                    'message' => 'Menu snapshots marked as stale. Fresh snapshots will be captured on next wp-admin request.',
                    'data' => ['invalidated' => true, 'mode' => 'mark_stale', 'timestamp' => \time()],
                ],
            ];
        } catch (\Throwable $e) {
            if (\defined('WP_DEBUG') && WP_DEBUG) {
                \error_log('[FleekDash MenuDataAPI] Failed to invalidate snapshots: ' . $e->getMessage());
            }
            return [
                'payload' => [
                    'success' => false,
                    'message' => 'Failed to invalidate snapshots: ' . $e->getMessage(),
                    'fallback_data' => ['invalidated' => false],
                ],
            ];
        }
    }

    /** @return array<string,mixed> */
    public function buildCacheStatusPayload(): array
    {
        $status = $this->menuCapture->getCacheStatus();
        $lastInvalidation = (int) \get_option('fleekdash_invalidate_frontend_cache', 0);
        $lastCheck = (int) \get_option('fleekdash_last_cache_check', 0);
        $shouldInvalidate = $lastInvalidation > $lastCheck;

        return [
            'success' => true,
            'should_invalidate' => $shouldInvalidate,
            'menu' => $status,
            'timestamp' => \time(),
            'note' => 'Snapshot-driven menu system: menu snapshots stored in user_meta, captured during real wp-admin requests for 100% reliability.',
        ];
    }

    public function markCacheCleared(): void
    {
        \update_option('fleekdash_last_cache_check', \time(), false);
    }
}

