<?php

declare(strict_types=1);

namespace App\Config;

final class CommerceIntentConfig
{
    private const STRONG_SIGNALS = [
        'shop',
        'alle',
        'preis',
        'kunde',
        'online',
        'produkt',
        'artikel',
        'sku',
        'kaufen',
        'kostet',
        'suche',
        'such',
        'finde',
        'finden',
        'analysegerät',
        'analysegeraet',
        'messgerät',
        'messgeraet',
        'pockettester',
        'pocket tester',
        'handmessgerät',
        'handmessgeraet',
        'analysator',
        'analyzer',
        'puffer',
        'kalibrierpuffer',
        'kalibrierlösung',
        'kalibrierloesung',
        'kalibrierung',
        'chemie',
        'reagenz',
        'reagenzien',
        'verbrauchsmaterial',
        'zubehör',
        'zubehoer',
        'ersatzteil',
    ];

    private const ADVISORY_SIGNALS = [
        'passt',
        'eignet',
        'besser',
        'besten',
        'gut',
        'gut für',
        'gut fuer',
        'passend für',
        'passend fuer',
        'geeignet',
        'geeigent',
        'empfiehl',
        'empfehl',
    ];

    private const ADVISORY_PRODUCT_SELECTION_PATTERNS = [
        '/\bmit\s+welche(?:m|n|r|s)?\s+(?:testomat(?:en)?|pockettester|pocket\s+tester|analysegerät|analysegeraet|messgerät|messgeraet|analysator|analyzer)\b.*\b(?:messen|messung|überwach(?:en|ung)?|ueberwach(?:en|ung)?)\b/u',
        '/\bwelche(?:r|s|n|m)?\s+(?:testomat(?:en)?|pockettester|pocket\s+tester|analysegerät|analysegeraet|messgerät|messgeraet|analysator|analyzer)\b.*\b(?:kann|können|koennen|misst|messen|überwacht|ueberwacht|eignet|geeignet|passt|gut|empfehl)\b.*\b(?:messen|messung|überwach(?:en|ung)?|ueberwach(?:en|ung)?)\b/u',
        '/\b(?:testomat(?:en)?|pockettester|pocket\s+tester|analysegerät|analysegeraet|messgerät|messgeraet|analysator|analyzer)\b.*\b(?:für|fuer)\b.*\b(?:messung|messen|überwachung|ueberwachung)\b/u',
    ];

    private const PRICE_TERMS = [
        'euro',
        '€',
        'eur',
        'teuer',
        'preis',
        'kosten',
        'kostet',
    ];

    private const COLOR_TERMS = [
        'schwarz',
        'weiß',
        'weis',
        'blau',
        'grau',
        'beige',
        'rosa',
        'pink',
        'gruen',
        'orange',
        'braun',
    ];

    private const SIZE_TOKEN_TERMS = [
        'xs',
        's',
        'm',
        'l',
        'xl',
        'xxl',
        'xxxxl',
    ];

    private const SIZE_TERMS = [
        'größe',
        'groesse',
        'grösse',
    ];

    private const SUPPORT_DIAGNOSTIC_PATTERNS = [
        '/\bfehler\b/u',
        '/\bfehlercode\b/u',
        '/\berror\b/u',
        '/\bstörung\b/u',
        '/\bstoerung\b/u',
        '/\balarm\b/u',
        '/\bstörungsmeldung\b/u',
        '/\bstoerungsmeldung\b/u',
        '/\bmeldung\b/u',
        '/\bwarnung\b/u',
        '/\bwarncode\b/u',
        '/\bcode\b/u',
        '/\bwas bedeutet\b/u',
        '/\bwarum\b/u',
        '/\bblinkt\b/u',
        '/\bzeigt\b/u',
        '/\bzeigt an\b/u',
        '/\bursache\b/u',
        '/\bdiagnose\b/u',
        '/\bservicefall\b/u',
        '/\bproblem\b/u',
        '/\bstörung beheben\b/u',
        '/\bstoerung beheben\b/u',
        '/\be\d{1,3}\b/u',
    ];

    private const EXPLICIT_COMMERCE_INTENT_PATTERNS = [
        '/\bshop\b/u',
        '/\bpreis\b/u',
        '/\bkosten\b/u',
        '/\bkostet\b/u',
        '/\bkaufen\b/u',
        '/\bbestellen\b/u',
        '/\bprodukt\b/u',
        '/\bartikel\b/u',
        '/\bsku\b/u',
        '/\bonline\b/u',
        '/\bchemie\b/u',
        '/\breagenz(?:ien)?\b/u',
        '/\bverbrauchsmaterial(?:ien)?\b/u',
        '/\bzubehör\b/u',
        '/\bzubehoer\b/u',
        '/\bersatzteil(?:e)?\b/u',
    ];

    /**
     * @param array<string, mixed> $config
     */
    public function __construct(private readonly array $config = [])
    {
    }

    /** @return string[] */
    public function getStrongSignalsList(): array
    {
        return $this->stringList('strong_signals', self::STRONG_SIGNALS);
    }

    /** @return string[] */
    public function getAdvisorySignals(): array
    {
        return $this->stringList('advisory_signals', self::ADVISORY_SIGNALS);
    }

    /** @return string[] */
    public function getAdvisoryProductSelectionPatterns(): array
    {
        return $this->stringList('advisory_product_selection_patterns', self::ADVISORY_PRODUCT_SELECTION_PATTERNS);
    }

    /** @return string[] */
    public function getPriceTerms(): array
    {
        return $this->stringList('price_terms', self::PRICE_TERMS);
    }

    public function getPricePattern(): string
    {
        return implode('|', $this->getPriceTerms());
    }

    /** @return string[] */
    public function getColorTerms(): array
    {
        return $this->stringList('color_terms', self::COLOR_TERMS);
    }

    public function getColorPattern(): string
    {
        return implode('|', $this->getColorTerms());
    }

    /** @return string[] */
    public function getSizeTokenTerms(): array
    {
        return $this->stringList('size_token_terms', self::SIZE_TOKEN_TERMS);
    }

    public function getSizeTokenPattern(): string
    {
        return implode('|', $this->getSizeTokenTerms());
    }

    /** @return string[] */
    public function getSizeTerms(): array
    {
        return $this->stringList('size_terms', self::SIZE_TERMS);
    }

    public function getSizePattern(): string
    {
        return implode('|', $this->getSizeTerms());
    }

    public function getSizeExtractionPattern(): string
    {
        return '/\b(?:' . $this->getSizePattern() . ')\s*([a-z0-9.-]+)\b/u';
    }

    /** @return string[] */
    public function getSupportDiagnosticPatterns(): array
    {
        return $this->stringList('support_diagnostic_patterns', self::SUPPORT_DIAGNOSTIC_PATTERNS);
    }

    /** @return string[] */
    public function getExplicitCommerceIntentPatterns(): array
    {
        return $this->stringList('explicit_commerce_intent_patterns', self::EXPLICIT_COMMERCE_INTENT_PATTERNS);
    }

    public function getSkuLikePattern(): string
    {
        return '/\b\d{4,10}\b/u';
    }

    public function getPriceValuePattern(): string
    {
        return '/\b\d+(?:[.,]\d+)?\s*(?:' . $this->getPricePattern() . ')\b/u';
    }

    public function getSizeValuePattern(): string
    {
        return '/\b(?:' . $this->getSizePattern() . ')\s*[a-z0-9.-]+\b/u';
    }

    public function getSizeTokenValuePattern(): string
    {
        return '/\b(?:' . $this->getSizeTokenPattern() . ')\b/u';
    }

    public function getColorValuePattern(): string
    {
        return '/\b(?:' . $this->getColorPattern() . ')\b/u';
    }

    public function getSupportOrDiagnosticSignalLabel(): string
    {
        return 'support_or_diagnostic';
    }

    public function getSkuSignalLabel(): string
    {
        return 'sku';
    }

    public function getPriceSignalLabel(): string
    {
        return 'price';
    }

    public function getSizeSignalLabel(): string
    {
        return 'size';
    }

    public function getSizeTokenSignalLabel(): string
    {
        return 'size_token';
    }

    public function getColorSignalLabel(): string
    {
        return 'color';
    }

    public function getAdvisorySignalPrefix(): string
    {
        return 'advisory:';
    }

    public function getAdvisoryProductSelectionSignalLabel(): string
    {
        return 'advisory_product_selection';
    }

    public function getProductSearchMinScore(): int
    {
        return 3;
    }

    public function getAdvisoryProductSearchMinScore(): int
    {
        return 2;
    }

    public function getStrongSignalScore(): int
    {
        return 3;
    }

    public function getSkuSignalScore(): int
    {
        return 2;
    }

    public function getPriceSignalScore(): int
    {
        return 2;
    }

    public function getSizeSignalScore(): int
    {
        return 2;
    }

    public function getSizeTokenSignalScore(): int
    {
        return 1;
    }

    public function getColorSignalScore(): int
    {
        return 1;
    }

    public function getAdvisorySignalScore(): int
    {
        return 1;
    }

    public function getAdvisoryProductSelectionSignalScore(): int
    {
        return 3;
    }

    public function getModelLikeProductPattern(): string
    {
        return '/\b[a-zäöüß][a-zäöüß®\-]*(?:\s+[a-zäöüß][a-zäöüß®\-]*){0,2}\s+\d{2,5}[a-z0-9\-]*\b/u';
    }

    public function getModelLikeProductSignalLabel(): string
    {
        return 'model_like_product';
    }

    public function getModelLikeProductSignalScore(): int
    {
        return 3;
    }

    /** @return string[] */
    private function stringList(string $key, array $default): array
    {
        $value = $this->config[$key] ?? $default;
        if (!is_array($value)) {
            return $default;
        }

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

            $item = trim((string) $item);
            if ($item === '' || in_array($item, $out, true)) {
                continue;
            }

            $out[] = $item;
        }

        return $out !== [] ? $out : $default;
    }
}
