<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Actions;

use ImovelZapAi\Conversations\Application\Services\ConversationAutomationState;
use ImovelZapAi\Conversations\Application\Services\QualificationQuestionCatalog;
use ImovelZapAi\Conversations\Application\Services\QualificationSkipPolicy;
use ImovelZapAi\Conversations\Domain\Enums\ConversationAutomationPhase;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ContactModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ConversationModel;
use ImovelZapAi\Properties\Application\Actions\RegisterPropertyInterestAction;
use ImovelZapAi\Properties\Domain\Enums\PropertyInterestSource;
use ImovelZapAi\Properties\Domain\Enums\PropertyInterestStatus;
use ImovelZapAi\Properties\Infrastructure\Persistence\Eloquent\PropertyInterestModel;
use ImovelZapAi\Properties\Infrastructure\Persistence\Eloquent\PropertyModel;
use ImovelZapAi\Tenancy\Support\TenantContext;

final class StartPropertyQualificationAction
{
    public function __construct(
        private readonly RegisterPropertyInterestAction $registerInterest,
        private readonly QualificationQuestionCatalog $catalog,
        private readonly QualificationSkipPolicy $skipPolicy,
        private readonly GenerateConversationSummaryAction $generateSummary,
        private readonly SendOutboundMessageAction $sendText,
        private readonly ConversationAutomationState $automationState,
    ) {}

    public function execute(
        string $tenantId,
        ContactModel $contact,
        ConversationModel $conversation,
        string $propertyId,
        PropertyInterestSource $source,
        bool $explicitVisitRequest = false,
    ): void {
        TenantContext::set($tenantId);

        $property = PropertyModel::query()
            ->where('tenant_id', $tenantId)
            ->whereKey($propertyId)
            ->first();

        if ($property === null) {
            $this->sendText->execute(
                $tenantId,
                $contact,
                'Não encontrei esse imóvel. Escolha uma opção da lista ou faça uma nova busca.',
                $conversation,
            );

            return;
        }

        $interest = $this->registerInterest->execute(
            tenantId: $tenantId,
            contactId: (string) $contact->id,
            propertyId: (string) $property->id,
            source: $source,
            conversationId: (string) $conversation->id,
        );

        if ($interest->status === PropertyInterestStatus::ReadyForHandoff
            || $interest->status === PropertyInterestStatus::InProgress) {
            $this->sendText->execute(
                $tenantId,
                $contact,
                'Suas informações já foram enviadas para um corretor. Em breve entraremos em contato.',
                $conversation,
            );

            return;
        }

        if ($this->skipPolicy->shouldHandoffDirectly($property, $conversation, $explicitVisitRequest)) {
            $this->generateSummary->execute(
                $tenantId,
                $contact,
                $conversation,
                $interest,
                requestedVisit: true,
            );

            return;
        }

        $interest->transitionTo(PropertyInterestStatus::Qualifying);

        $answers = is_array($interest->qualification) ? $interest->qualification : [];
        $nextField = $this->catalog->nextField(null, $answers);

        if ($nextField === null) {
            $this->generateSummary->execute(
                $tenantId,
                $contact,
                $conversation,
                $interest,
                requestedVisit: true,
            );

            return;
        }

        $context = $conversation->context ?? [];
        $context['qualification'] = [
            'property_interest_id' => (string) $interest->id,
            'property_id' => (string) $property->id,
            'awaiting_field' => $nextField,
            'answers' => $answers,
            'requested_visit' => true,
        ];
        unset($context['awaiting_human_response']);

        $conversation->update([
            'context' => $context,
        ]);

        $this->automationState->setPhase($conversation, ConversationAutomationPhase::Qualifying);

        $this->sendText->execute(
            $tenantId,
            $contact,
            $this->catalog->questionFor($nextField),
            $conversation,
        );
    }
}
