<?php

declare(strict_types=1);

namespace App\Config;

/**
 * YAML-backed deterministic sales-intent configuration.
 *
 * This class intentionally has no PHP fallback values. Missing or invalid
 * configuration must be fixed in config/retriex/intent.yaml.
 */
final class SalesIntentConfig
{
    /**
     * @param array<string, mixed> $config
     */
    public function __construct(private readonly array $config)
    {
    }

    public function getDominanceDelta(): int
    {
        return $this->requiredNonNegativeInt('dominance_delta');
    }

    public function getMinScoreThreshold(): int
    {
        return $this->requiredNonNegativeInt('min_score_threshold');
    }

    /** @return string[] */
    public function getSalesSignals(): array
    {
        return $this->requiredStringList('sales_signals');
    }

    /** @return string[] */
    public function getComparisonSignals(): array
    {
        return $this->requiredStringList('comparison_signals');
    }

    /** @return string[] */
    public function getObjectionSignals(): array
    {
        return $this->requiredStringList('objection_signals');
    }

    /** @return string[] */
    public function getImplementationSignals(): array
    {
        return $this->requiredStringList('implementation_signals');
    }

    /** @return string[] */
    public function getRoiSignals(): array
    {
        return $this->requiredStringList('roi_signals');
    }

    private function requiredNonNegativeInt(string $key): int
    {
        if (!array_key_exists($key, $this->config)) {
            throw new \InvalidArgumentException(sprintf('Missing required RetrieX sales intent config key "%s".', $key));
        }

        $value = $this->config[$key];

        if (is_int($value)) {
            $intValue = $value;
        } elseif (is_string($value) && preg_match('/^-?\d+$/', trim($value)) === 1) {
            $intValue = (int) trim($value);
        } else {
            throw new \InvalidArgumentException(sprintf('RetrieX sales intent config key "%s" must be an integer.', $key));
        }

        if ($intValue < 0) {
            throw new \InvalidArgumentException(sprintf('RetrieX sales intent config key "%s" must be greater than or equal to 0.', $key));
        }

        return $intValue;
    }

    /** @return string[] */
    private function requiredStringList(string $key): array
    {
        if (!array_key_exists($key, $this->config)) {
            throw new \InvalidArgumentException(sprintf('Missing required RetrieX sales intent config key "%s".', $key));
        }

        $value = $this->config[$key];

        if (!is_array($value)) {
            throw new \InvalidArgumentException(sprintf('RetrieX sales intent config key "%s" must be a list.', $key));
        }

        $out = [];
        foreach ($value as $item) {
            if (!is_scalar($item)) {
                continue;
            }

            $item = trim((string) $item);
            if ($item === '') {
                continue;
            }

            if (!in_array($item, $out, true)) {
                $out[] = $item;
            }
        }

        if ($out === []) {
            throw new \InvalidArgumentException(sprintf('RetrieX sales intent config key "%s" must not be empty.', $key));
        }

        return $out;
    }
}
