<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Selectors;

use Ekesto\CacheInvalidator\Resolvers\PageTargetResolver;
use Ekesto\CacheInvalidator\Support\Debug;

/**
 * Resolves post-trigger target mappings from extension filters.
 */
final class PostTargetMappingResolver
{
    /**
     * Resolve mapped targets for one post-trigger invalidation.
     *
     * @param array<string,mixed> $context Filter context payload.
     * @return array{
     *     mode:string,
     *     target_ids:int[],
     *     wildcard_requested:bool,
     *     matched:bool,
     *     has_selectors:bool,
     *     intent:string,
     *     targeted_empty:bool
     * }
     */
    public static function resolve(array $context): array
    {
        /** @var array<string,mixed>|array<int,mixed> $selectors */
        $selectors = apply_filters('ekesto_ci_post_selectors', [], $context);
        if (!is_array($selectors)) {
            $selectors = [];
        }

        $selectorResult = SelectorResolver::resolve(array_values($selectors));
        if (!empty($selectorResult['has_selectors'])) {
            $intent = (string) ($selectorResult['intent'] ?? SelectorResolver::INTENT_TARGETED);
            if ($intent === SelectorResolver::INTENT_GLOBAL) {
                Debug::log('post selector resolve: has_selectors=yes intent=GLOBAL post_ids=0 post_types=0 targets=0');
                return [
                    'mode' => 'replace',
                    'target_ids' => [],
                    'wildcard_requested' => false,
                    'matched' => true,
                    'has_selectors' => true,
                    'intent' => SelectorResolver::INTENT_GLOBAL,
                    'targeted_empty' => false,
                ];
            }

            $selectorPostIds = is_array($selectorResult['post_ids'] ?? null) ? $selectorResult['post_ids'] : [];
            $selectorPostTypes = is_array($selectorResult['post_types'] ?? null) ? $selectorResult['post_types'] : [];
            $resolvedFromTypes = PageTargetResolver::getPublishedPostIdsByPostTypes($selectorPostTypes);
            $targetIds = array_values(array_unique(array_filter(array_map(
                'absint',
                array_merge($selectorPostIds, $resolvedFromTypes)
            ), static fn(int $id): bool => $id > 0)));

            Debug::log(sprintf(
                'post selector resolve: has_selectors=yes intent=TARGETED post_ids=%d post_types=%d targets=%d',
                count($selectorPostIds),
                count($selectorPostTypes),
                count($targetIds)
            ));

            return [
                'mode' => 'replace',
                'target_ids' => $targetIds,
                'wildcard_requested' => false,
                'matched' => !empty($targetIds),
                'has_selectors' => true,
                'intent' => SelectorResolver::INTENT_TARGETED,
                'targeted_empty' => empty($targetIds),
            ];
        }

        return [
            'mode' => 'replace',
            'target_ids' => [],
            'wildcard_requested' => false,
            'matched' => false,
            'has_selectors' => false,
            'intent' => SelectorResolver::INTENT_TARGETED,
            'targeted_empty' => false,
        ];
    }
}
