<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Integrations\Builders;

use Ekesto\CacheInvalidator\Support\Debug;

/**
 * Chooses a single primary builder scan profile for a post.
 */
final class BuilderDetector
{
    private BuildersRegistry $registry;

    /**
     * Build detector with registry dependency.
     *
     * @param BuildersRegistry|null $registry Registry dependency.
     */
    public function __construct(?BuildersRegistry $registry = null)
    {
        $this->registry = $registry ?? new BuildersRegistry();
    }

    /**
     * Detect and return the post scan profile.
     *
     * @param \WP_Post $post Post object.
     * @return BuildersScanProfile
     */
    public function detectForPost(\WP_Post $post): BuildersScanProfile
    {
        if (Debug::verboseEnabled()) {
            Debug::log(sprintf(
                'builder detector: start post_id=%d post_type=%s',
                (int) $post->ID,
                (string) $post->post_type
            ));
        }

        foreach ($this->registry->all() as $builder) {
            $detection = $builder->detect($post);
            $detected = (bool) ($detection['detected'] ?? false);
            if (!$detected) {
                continue;
            }

            $confidence = (string) ($detection['confidence'] ?? 'unknown');
            $signals = is_array($detection['signals'] ?? null) ? $detection['signals'] : [];
            $fields = ['post_content'];

            if ($confidence !== 'unknown') {
                $fields = array_merge($fields, $builder->additionalFieldsToScan());
            }

            $profile = new BuildersScanProfile($builder->key(), $confidence, $fields, $signals);
            if (Debug::verboseEnabled()) {
                Debug::log(sprintf(
                    'builder detector: selected post_id=%d builder=%s confidence=%s fields=%d',
                    (int) $post->ID,
                    $profile->builderKey(),
                    $profile->confidence(),
                    count($profile->fieldsToScan())
                ), [
                    'signals' => $profile->detectionSignals(),
                    'fields' => $profile->fieldsToScan(),
                ]);
            }

            return $profile;
        }

        $fallback = $this->registry->fallback();
        $detected = $fallback->detect($post);
        $profile = new BuildersScanProfile(
            $fallback->key(),
            (string) ($detected['confidence'] ?? 'unknown'),
            ['post_content'],
            is_array($detected['signals'] ?? null) ? $detected['signals'] : []
        );

        if (Debug::verboseEnabled()) {
            Debug::log(sprintf(
                'builder detector: fallback post_id=%d builder=%s confidence=%s',
                (int) $post->ID,
                $profile->builderKey(),
                $profile->confidence()
            ), [
                'signals' => $profile->detectionSignals(),
                'fields' => $profile->fieldsToScan(),
            ]);
        }

        return $profile;
    }
}
