<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Selectors;

/**
 * Shared selector intent normalization for extension filter surfaces.
 */
final class SelectorResolver
{
    public const TYPE_POST_ID = 'post_id';
    public const TYPE_POST_TYPE = 'post_type';
    public const TYPE_ALL = 'all';

    public const INTENT_TARGETED = 'TARGETED';
    public const INTENT_GLOBAL = 'GLOBAL';

    /**
     * Normalize selector entries into intent-only output.
     *
     * @param array<int,mixed> $selectors Raw selector entries.
     * @return array{intent:string,post_ids:int[],post_types:string[],has_selectors:bool}
     */
    public static function resolve(array $selectors): array
    {
        $intent = self::INTENT_TARGETED;
        $postIds = [];
        $postTypes = [];
        $hasSelectors = false;

        foreach ($selectors as $selector) {
            if (!is_array($selector)) {
                continue;
            }

            $type = sanitize_key((string) ($selector['type'] ?? ''));

            if ($type === self::TYPE_ALL) {
                $hasSelectors = true;
                $intent = self::INTENT_GLOBAL;
                $postIds = [];
                $postTypes = [];
                break;
            }

            if ($type === self::TYPE_POST_ID) {
                if (!array_key_exists('value', $selector) || !is_int($selector['value'])) {
                    continue;
                }

                $postId = absint($selector['value']);
                if ($postId <= 0) {
                    continue;
                }

                $hasSelectors = true;
                $postIds[] = $postId;
                continue;
            }

            if ($type === self::TYPE_POST_TYPE) {
                if (!array_key_exists('value', $selector) || !is_string($selector['value'])) {
                    continue;
                }

                $postType = sanitize_key($selector['value']);
                if ($postType === '') {
                    continue;
                }

                $hasSelectors = true;
                $postTypes[] = $postType;
            }
        }

        $postIds = array_values(array_unique(array_filter(array_map('absint', $postIds), static fn(int $id): bool => $id > 0)));
        sort($postIds, SORT_NUMERIC);

        $postTypes = array_values(array_unique(array_filter(array_map(
            static fn($postType): string => sanitize_key((string) $postType),
            $postTypes
        ))));
        sort($postTypes, SORT_STRING);

        return [
            'intent' => $intent,
            'post_ids' => $postIds,
            'post_types' => $postTypes,
            'has_selectors' => $hasSelectors,
        ];
    }
}
