<?php

declare(strict_types=1);

namespace App\Intent;

use App\Config\CommerceIntentConfig;

final class CommerceIntentLite
{
    public const NONE = 'none';
    public const PRODUCT_SEARCH = 'product_search';
    public const ADVISORY_PRODUCT_SEARCH = 'advisory_product_search';

    public function __construct(
        private readonly CommerceIntentConfig $config
    ) {
    }

    /**
     * @return array{intent:string, score:int, signals:string[]}
     */
    public function detect(string $originalPrompt): array
    {
        $p = mb_strtolower(trim($originalPrompt));

        if ($p === '') {
            return [
                'intent' => self::NONE,
                'score' => 0,
                'signals' => [],
            ];
        }

        // Block support / diagnostic questions from entering the commerce flow
        // unless the prompt also contains very explicit purchase / shop intent.
        if ($this->isSupportOrDiagnosticQuery($p) && !$this->hasExplicitCommerceIntent($p)) {
            return [
                'intent' => self::NONE,
                'score' => 0,
                'signals' => ['support_or_diagnostic'],
            ];
        }

        $score = 0;
        $signals = [];

        $strongSignals = $this->config->getStrongSignalsList();

        foreach ($strongSignals as $signal) {
            if (str_contains($p, mb_strtolower($signal))) {
                $score += 3;
                $signals[] = $signal;
            }
        }

        // Treat long numeric identifiers as stronger product-number-like signals.
        // This avoids over-triggering commerce purely because a model name contains
        // a short number such as "808" in support questions.
        if (preg_match('/\b\d{4,10}\b/u', $p) === 1) {
            $score += 2;
            $signals[] = 'sku';
        }

        $pricePattern = $this->config->getPricePattern();
        if (preg_match('/\b\d+(?:[.,]\d+)?\s*(' . $pricePattern . ')\b/u', $p) === 1) {
            $score += 2;
            $signals[] = 'price';
        }

        $sizePattern = $this->config->getSizePattern();
        if (preg_match('/\b(' . $sizePattern . ')\s*[a-z0-9.-]+\b/u', $p) === 1) {
            $score += 2;
            $signals[] = 'size';
        }

        $sizeTokenPattern = $this->config->getSizeTokenPattern();
        if (preg_match('/\b(' . $sizeTokenPattern . ')\b/u', $p) === 1) {
            $score += 1;
            $signals[] = 'size_token';
        }

        $colorPattern = $this->config->getColorPattern();
        if (preg_match('/\b(' . $colorPattern . ')\b/u', $p) === 1) {
            $score += 1;
            $signals[] = 'color';
        }

        $advisorySignals = $this->config->getAdvisorySignals();

        foreach ($advisorySignals as $signal) {
            if (str_contains($p, mb_strtolower($signal))) {
                $score += 1;
                $signals[] = 'advisory:' . $signal;
            }
        }

        $signals = array_values(array_unique($signals));

        if ($score >= 3) {
            return [
                'intent' => self::PRODUCT_SEARCH,
                'score' => $score,
                'signals' => $signals,
            ];
        }

        if ($score >= 2) {
            return [
                'intent' => self::ADVISORY_PRODUCT_SEARCH,
                'score' => $score,
                'signals' => $signals,
            ];
        }

        return [
            'intent' => self::NONE,
            'score' => $score,
            'signals' => $signals,
        ];
    }

    private function isSupportOrDiagnosticQuery(string $prompt): bool
    {
        $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',
        ];

        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $prompt) === 1) {
                return true;
            }
        }

        return false;
    }

    private function hasExplicitCommerceIntent(string $prompt): bool
    {
        $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',
        ];

        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $prompt) === 1) {
                return true;
            }
        }

        return false;
    }
}