<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Actions;

use ImovelZapAi\Conversations\Domain\Enums\ConversationStatus;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ContactModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ConversationModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\MessageModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ReplySuggestionModel;
use ImovelZapAi\Conversations\Application\Services\CopilotMetricsRecorder;
use ImovelZapAi\Users\Infrastructure\Persistence\Eloquent\UserModel;
use ImovelZapAi\Tenancy\Support\TenantContext;
use InvalidArgumentException;

final class SendBrokerReplyAction
{
    public function __construct(
        private readonly SendOutboundMessageAction $sendText,
        private readonly CopilotMetricsRecorder $metrics,
    ) {}

    public function execute(
        string $tenantId,
        ConversationModel $conversation,
        UserModel $user,
        string $body,
        ?string $suggestionId = null,
    ): MessageModel {
        TenantContext::set($tenantId);

        $body = trim($body);

        if ($body === '') {
            throw new InvalidArgumentException('A mensagem não pode estar vazia.');
        }

        if (! in_array($conversation->status, [
            ConversationStatus::AwaitingBroker,
            ConversationStatus::Negotiating,
        ], true)) {
            throw new InvalidArgumentException('Esta conversa não aceita respostas pelo painel no momento.');
        }

        /** @var ContactModel $contact */
        $contact = $conversation->contact()->firstOrFail();

        $message = $this->sendText->execute($tenantId, $contact, $body, $conversation);

        $message->update([
            'raw_payload' => [
                'sent_by' => 'broker',
                'user_id' => (string) $user->id,
                'user_name' => $user->name,
                'suggestion_id' => $suggestionId,
            ],
        ]);

        if ($suggestionId !== null) {
            $suggestion = ReplySuggestionModel::query()
                ->where('tenant_id', $tenantId)
                ->where('conversation_id', $conversation->id)
                ->whereKey($suggestionId)
                ->first();

            if ($suggestion !== null) {
                $this->metrics->resolveSuggestionOutcome($tenantId, $suggestion, $body);
            }
        }

        return $message->fresh() ?? $message;
    }

    public function canReply(ConversationModel $conversation): bool
    {
        return in_array($conversation->status, [
            ConversationStatus::AwaitingBroker,
            ConversationStatus::Negotiating,
        ], true);
    }
}
