<?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\Infrastructure\Persistence\Eloquent\ContactModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ConversationModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\MessageModel;
use Throwable;

/**
 * Resposta automática no WhatsApp via AI Gateway (modelo barato: gpt-4.1-nano).
 * Usado quando as regras não cobrem o intent (Other) e a IA está habilitada.
 */
final class ConversationWhatsAppAiResponder
{
    public function __construct(
        private readonly AiGateway $aiGateway,
        private readonly OpenAiProvider $openAiProvider,
    ) {}

    public function canRespond(): bool
    {
        return (bool) config('conversations.ai_auto_reply', true)
            && $this->aiGateway->isEnabled()
            && $this->openAiProvider->isConfigured();
    }

    public function respond(
        string $tenantId,
        ContactModel $contact,
        ConversationModel $conversation,
        string $inboundBody,
    ): ?string {
        if (! $this->canRespond() || trim($inboundBody) === '') {
            return null;
        }

        try {
            $recent = MessageModel::query()
                ->where('conversation_id', $conversation->id)
                ->orderByDesc('created_at')
                ->limit(8)
                ->get()
                ->reverse()
                ->map(fn (MessageModel $message): array => [
                    'direction' => $message->direction?->value ?? (string) $message->direction,
                    'body' => (string) $message->body,
                ])
                ->values()
                ->all();

            $response = $this->aiGateway->complete(new AiCompletionRequest(
                tenantId: $tenantId,
                taskType: AiTaskType::WhatsAppAutoReply,
                messages: [
                    new AiMessageData('system', $this->systemPrompt($conversation)),
                    new AiMessageData('user', json_encode([
                        'contact_name' => $contact->display_name ?? $contact->wa_id,
                        'inbound_message' => $inboundBody,
                        'conversation_status' => $conversation->status?->value,
                        'returning_context' => $conversation->context['returning'] ?? null,
                        'catalog_filters' => $conversation->context['catalog']['filters'] ?? null,
                        'recent_messages' => $recent,
                    ], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)),
                ],
                metadata: [
                    'conversation_id' => (string) $conversation->id,
                    'channel' => 'whatsapp',
                ],
                temperature: 0.5,
                maxTokens: 350,
            ));

            $text = trim($response->text);

            if ($text === '' || str_starts_with($text, '[IA desabilitada]')) {
                return null;
            }

            return $text;
        } catch (Throwable) {
            return null;
        }
    }

    private function systemPrompt(ConversationModel $conversation): string
    {
        $returningHint = '';
        $returning = $conversation->context['returning'] ?? null;
        if (is_array($returning) && (($returning['resolved'] ?? false) === true)) {
            $choice = (string) ($returning['choice'] ?? '');
            $label = (string) ($returning['property_label'] ?? $returning['location_label'] ?? '');
            $returningHint = "\nContexto de retorno: o cliente escolheu \"{$choice}\" em relação ao histórico ({$label}). Respeite essa escolha.";
        }

        return <<<PROMPT
Você é o corretor digital do ImóvelZapAi no WhatsApp (Brasil).

Objetivo: conduzir a pessoa com perguntas curtas para qualificar busca de imóvel (bairro/cidade, tipo, orçamento, compra ou aluguel).
{$returningHint}

Regras:
- Português do Brasil, tom humano, acolhedor e profissional.
- Respostas curtas (2 a 4 frases). Sem markdown, sem listas longas.
- Não invente imóveis, preços, disponibilidade ou horários de visita.
- Se a pessoa já pediu busca concreta (ex.: "casa no Bessa até 500 mil"), confirme o entendimento e diga que vai buscar opções.
- Se faltar dado, faça UMA pergunta objetiva.
- Nunca diga que é IA, CRM ou bot — fale como assistente da imobiliária.
- Responda APENAS com o texto da mensagem WhatsApp.
PROMPT;
    }
}
