<?php

declare(strict_types=1);

namespace FleekDash\API;

/**
 * Shared menu REST payload fields: integrity, cache version, schema.
 * Used by MenuDataAPI for /menu and /menu/{role} responses.
 *
 * @package FleekDash\API
 */
final class MenuPayloadContract
{
    public const SCHEMA_VERSION = 1;

    /**
     * @param array<string, mixed> $payload
     *
     * @return array<string, mixed>
     */
    public static function enrichFromResolver(array $payload, string $source): array
    {
        $items = $payload['items'] ?? [];
        $formattedCount = self::resolveFormattedCount($payload, $items);
        $payload['menu_source'] = $source;
        $payload['menu_integrity'] = self::deriveIntegrityFromResolver($source, $formattedCount);
        $payload['cache_version'] = self::cacheVersionString();
        $payload['schema_version'] = self::SCHEMA_VERSION;
        if (isset($payload['debug']) && \is_array($payload['debug'])) {
            $payload['debug']['menu_source'] = $source;
            $payload['debug']['menu_integrity'] = $payload['menu_integrity'];
        }

        return $payload;
    }

    /**
     * @param array<string, mixed> $payload
     *
     * @return array<string, mixed>
     */
    public static function enrichFromCapture(array $payload, string $lastSource, int $snapshotUpdatedAt): array
    {
        $items = $payload['items'] ?? [];
        $formattedCount = self::resolveFormattedCount($payload, $items);
        $payload['menu_source'] = $lastSource;
        $payload['menu_integrity'] = self::deriveIntegrityFromCapture($lastSource, $formattedCount);
        $payload['cache_version'] = self::cacheVersionString();
        $payload['schema_version'] = self::SCHEMA_VERSION;
        $debug = isset($payload['debug']) && \is_array($payload['debug']) ? $payload['debug'] : [];
        $debug['last_source'] = $lastSource;
        $debug['snapshot_updated_at'] = $snapshotUpdatedAt;
        $debug['menu_integrity'] = $payload['menu_integrity'];
        $payload['debug'] = $debug;

        return $payload;
    }

    public static function cacheVersionString(): string
    {
        return (string) (int) \get_option('fleekdash_invalidate_frontend_cache', 0);
    }

    /**
     * @param mixed $items
     */
    private static function resolveFormattedCount(array $payload, $items): int
    {
        if (isset($payload['debug']['formatted_count'])) {
            return (int) $payload['debug']['formatted_count'];
        }
        if (\is_array($items)) {
            return \count($items);
        }

        return 0;
    }

    private static function deriveIntegrityFromResolver(string $source, int $formattedCount): string
    {
        $integrity = 'unknown';
        if ($source === 'snapshot_fresh' || $source === 'user_meta_snapshot') {
            $integrity = 'full';
        } elseif ($source === 'snapshot_stale' || $source === 'user_meta_snapshot_stale') {
            $integrity = 'partial';
        } elseif (
            $source === 'missing_snapshot'
            || $source === 'unauthenticated'
            || $source === 'error'
            || $formattedCount < 1
        ) {
            $integrity = 'insufficient';
        }

        return $integrity;
    }

    private static function deriveIntegrityFromCapture(string $lastSource, int $formattedCount): string
    {
        $integrity = 'unknown';
        if ($lastSource === 'snapshot_fresh' || $lastSource === 'user_meta_snapshot') {
            $integrity = 'full';
        } elseif ($lastSource === 'snapshot_stale' || $lastSource === 'user_meta_snapshot_stale') {
            $integrity = 'partial';
        } elseif ($lastSource === 'missing_snapshot' || $lastSource === 'none' || $formattedCount < 1) {
            $integrity = 'insufficient';
        }

        return $integrity;
    }
}
