<?php
namespace EasyChat\Library\Ai;








class ChannelPolicyResolver {
    public const INTENT_ITEM_FACTS = 'item_facts';
    public const INTENT_STORE_POLICY = 'store_policy';
    public const INTENT_ALTERNATIVES = 'alternatives';
    public const INTENT_GENERAL_CATALOG = 'general_catalog';
    public const INTENT_UNKNOWN = 'unknown';

    public function resolve(array $context, array $settings): array {
        $channel_context = (string)($context['channel_context'] ?? '');
        $last_message = (string)($context['last_message'] ?? '');

        $policy = [
            'provider' => '',
            'context_kind' => 'none',
            'intent' => self::INTENT_UNKNOWN,
            'rag_allowed' => true,
            'rag_reason' => 'default',
            'allowed_tools' => ['search_products', 'search_pages'],
            'tools_reason' => 'default',
            'alternatives_mode' => 'on_request',
        ];

        $has_avito_item = strpos($channel_context, '[AVITO_ITEM_CONTEXT]') !== false;
        $has_avito_general = strpos($channel_context, '[AVITO_GENERAL_CONTEXT]') !== false;
        $has_youla_item = strpos($channel_context, '[YOULA_ITEM_CONTEXT]') !== false;
        if (!$has_avito_item && !$has_avito_general && !$has_youla_item) {
            return $policy;
        }

        $provider = $has_youla_item ? 'youla' : 'avito';
        $context_kind = ($has_avito_item || $has_youla_item) ? 'item' : 'general';
        $intent = $this->classifyIntent($last_message, $context_kind);
        $rag_mode = $this->normalizeRagMode($settings['chat_ai_avito_rag_mode'] ?? 'auto');
        $tools_mode = $this->normalizeToolsMode($settings['chat_ai_avito_tools_mode'] ?? 'auto');
        $alternatives_mode = $this->normalizeAlternativesMode($settings['chat_ai_avito_alternatives_mode'] ?? 'on_request');

        $policy['provider'] = $provider;
        $policy['context_kind'] = $context_kind;
        $policy['intent'] = $intent;
        $policy['alternatives_mode'] = $alternatives_mode;

        [$policy['rag_allowed'], $policy['rag_reason']] = $this->resolveAvitoRag(
            $context_kind,
            $intent,
            $rag_mode
        );
        [$policy['allowed_tools'], $policy['tools_reason']] = $this->resolveAvitoTools(
            $context_kind,
            $intent,
            $tools_mode,
            $alternatives_mode
        );

        return $policy;
    }

    private function resolveAvitoRag(string $context_kind, string $intent, string $rag_mode): array {
        if ($rag_mode === 'off') {
            return [false, 'avito_rag_mode_off'];
        }

        if ($context_kind === 'general') {
            return [true, 'avito_general_context'];
        }

        if ($rag_mode === 'always') {
            return [true, 'avito_rag_mode_always'];
        }

        if ($rag_mode === 'general_chats') {
            return [false, 'avito_item_general_chats_only'];
        }

        if ($intent === self::INTENT_STORE_POLICY) {
            return [true, 'avito_item_store_policy'];
        }

        return [false, 'avito_item_product_facts'];
    }

    private function resolveAvitoTools(
        string $context_kind,
        string $intent,
        string $tools_mode,
        string $alternatives_mode
    ): array {
        if ($tools_mode === 'off') {
            return [[], 'avito_tools_mode_off'];
        }

        $tools = [];
        if ($tools_mode === 'pages_only') {
            if ($intent === self::INTENT_STORE_POLICY || $context_kind === 'general') {
                $tools[] = 'search_pages';
            }
            return [$tools, 'avito_tools_pages_only'];
        }

        if ($context_kind === 'item') {
            if ($intent === self::INTENT_STORE_POLICY) {
                $tools[] = 'search_pages';
            }
            if ($intent === self::INTENT_ALTERNATIVES && $alternatives_mode !== 'off') {
                $tools[] = 'search_products';
            } elseif ($alternatives_mode === 'soft' && in_array($intent, [self::INTENT_ITEM_FACTS, self::INTENT_UNKNOWN], true)) {
                $tools[] = 'search_products';
            }
            return [$tools, 'avito_item_intent_' . $intent];
        }

        if ($intent === self::INTENT_STORE_POLICY) {
            $tools[] = 'search_pages';
        }
        if (in_array($intent, [self::INTENT_ALTERNATIVES, self::INTENT_GENERAL_CATALOG], true)
            && $alternatives_mode !== 'off') {
            $tools[] = 'search_products';
        }
        if ($tools_mode === 'products_pages' && $intent === self::INTENT_UNKNOWN) {
            $tools = ['search_pages'];
        }

        return [$tools, 'avito_general_intent_' . $intent];
    }

    private function classifyIntent(string $message, string $context_kind): string {
        $text = $this->lower($message);
        if ($text === '') {
            return self::INTENT_UNKNOWN;
        }

        if ($this->matches($text, [
            'похож', 'аналог', 'альтернатив', 'вариант', 'дешев', 'дороже',
            'другой', 'другая', 'другое', 'ещё', 'еще', 'подобрать', 'подберите',
            'что есть', 'какие есть', 'есть ли еще', 'есть ли ещё',
        ])) {
            return self::INTENT_ALTERNATIVES;
        }

        if ($this->matches($text, [
            'достав', 'оплат', 'гарант', 'возврат', 'обмен', 'самовывоз',
            'встреч', 'график', 'режим', 'адрес', 'чек', 'касс', 'рассроч',
            'кредит', 'бронь', 'забрать', 'отправ',
        ])) {
            return self::INTENT_STORE_POLICY;
        }

        if ($this->matches($text, [
            'цена', 'сколько стоит', 'стоимость', 'оператив', 'озу', 'накоп',
            'память', 'ssd', 'hdd', 'процессор', 'видеокарт', 'характерист',
            'комплект', 'модель', 'экран', 'диагонал', 'налич', 'в наличии',
            'торг', 'скидк', 'состояни', 'аккумулятор',
        ])) {
            return self::INTENT_ITEM_FACTS;
        }

        if ($context_kind === 'general' && $this->matches($text, [
            'ноутбук', 'телефон', 'смартфон', 'компьютер', 'товар', 'ассортимент',
            'купить', 'ищу', 'нужен', 'нужна', 'нужно',
        ])) {
            return self::INTENT_GENERAL_CATALOG;
        }

        return self::INTENT_UNKNOWN;
    }

    private function matches(string $text, array $needles): bool {
        foreach ($needles as $needle) {
            if ($needle !== '' && strpos($text, $needle) !== false) {
                return true;
            }
        }
        return false;
    }

    private function lower(string $value): string {
        $value = trim(strip_tags($value));
        return function_exists('mb_strtolower') ? mb_strtolower($value, 'UTF-8') : strtolower($value);
    }

    private function normalizeRagMode($value): string {
        $value = (string)$value;
        return in_array($value, ['auto', 'general_chats', 'always', 'off'], true) ? $value : 'auto';
    }

    private function normalizeToolsMode($value): string {
        $value = (string)$value;
        return in_array($value, ['auto', 'pages_only', 'products_pages', 'off'], true) ? $value : 'auto';
    }

    private function normalizeAlternativesMode($value): string {
        $value = (string)$value;
        return in_array($value, ['on_request', 'soft', 'off'], true) ? $value : 'on_request';
    }
}
