<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Services;

use ImovelZapAi\AiGateway\Application\Data\AiCompletionRequest;
use ImovelZapAi\AiGateway\Application\Data\AiMessageData;
use ImovelZapAi\AiGateway\Application\Services\AiGateway;
use ImovelZapAi\AiGateway\Domain\Enums\AiTaskType;
use ImovelZapAi\AiGateway\Infrastructure\Providers\OpenAiProvider;
use ImovelZapAi\Conversations\Application\Data\ReturningClientHistoryData;
use ImovelZapAi\Conversations\Domain\Enums\ReturningClientChoice;
use Throwable;

final class ReturningClientChoiceResolver
{
    public function __construct(
        private readonly AiGateway $aiGateway,
        private readonly OpenAiProvider $openAiProvider,
    ) {}

    public function resolve(string $tenantId, string $inboundBody, ReturningClientHistoryData $history): ReturningClientChoice
    {
        $normalized = $this->normalize($inboundBody);

        if ($this->matchesContinue($normalized)) {
            return ReturningClientChoice::ContinuePrior;
        }

        if ($this->matchesStartNew($normalized)) {
            return ReturningClientChoice::StartNew;
        }

        $aiChoice = $this->resolveWithAi($tenantId, $inboundBody, $history);

        return $aiChoice ?? ReturningClientChoice::Unclear;
    }

    private function matchesContinue(string $normalized): bool
    {
        return (bool) preg_match(
            '/\b(continuar|continue|assunto antigo|mesmo assunto|mesma conversa|aquele im[oó]vel|mesmo im[oó]vel|retomar|voltar ao assunto|1)\b/u',
            $normalized,
        );
    }

    private function matchesStartNew(string $normalized): bool
    {
        return (bool) preg_match(
            '/\b(novo|nova busca|outra busca|outro assunto|come[cç]ar de novo|comecar de novo|do zero|outra coisa|2)\b/u',
            $normalized,
        );
    }

    private function resolveWithAi(string $tenantId, string $inboundBody, ReturningClientHistoryData $history): ?ReturningClientChoice
    {
        if (! (bool) config('conversations.ai_auto_reply', true)
            || ! $this->aiGateway->isEnabled()
            || ! $this->openAiProvider->isConfigured()) {
            return null;
        }

        try {
            $response = $this->aiGateway->complete(new AiCompletionRequest(
                tenantId: $tenantId,
                taskType: AiTaskType::WhatsAppAutoReply,
                messages: [
                    new AiMessageData('system', <<<'PROMPT'
Classifique a resposta do cliente sobre retomar atendimento imobiliário.
Responda APENAS com uma palavra: continuar | novo | indefinido
- continuar = quer retomar o assunto/imóvel anterior
- novo = quer começar outra busca/assunto
- indefinido = não ficou claro
PROMPT),
                    new AiMessageData('user', json_encode([
                        'historico' => $history->topicLabel(),
                        'mensagem' => $inboundBody,
                    ], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)),
                ],
                metadata: [
                    'purpose' => 'returning_client_choice',
                    'prior_conversation_id' => $history->priorConversationId,
                ],
                temperature: 0.0,
                maxTokens: 10,
            ));

            $text = $this->normalize($response->text);

            if (str_contains($text, 'continuar')) {
                return ReturningClientChoice::ContinuePrior;
            }

            if (str_contains($text, 'novo')) {
                return ReturningClientChoice::StartNew;
            }

            return ReturningClientChoice::Unclear;
        } catch (Throwable) {
            return null;
        }
    }

    private function normalize(string $body): string
    {
        $text = mb_strtolower(trim($body));

        return preg_replace('/\s+/u', ' ', $text) ?? $text;
    }
}
