<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Services;

use ImovelZapAi\Conversations\Application\Services\ConversationAutomationState;
use ImovelZapAi\Conversations\Domain\Enums\ConversationAutomationPhase;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ConversationModel;
use ImovelZapAi\Properties\Application\Data\PropertySearchFilters;

final class ConversationSearchMemory
{
    public function __construct(
        private readonly ConversationAutomationState $automationState,
    ) {}

    public function pendingFilters(ConversationModel $conversation): PropertySearchFilters
    {
        $raw = $conversation->context['search']['pending_filters'] ?? null;

        if (! is_array($raw) || $raw === []) {
            return new PropertySearchFilters;
        }

        return PropertySearchFilters::fromQueryArray($raw);
    }

    public function awaitingField(ConversationModel $conversation): ?string
    {
        $field = $conversation->context['search']['awaiting_field'] ?? null;

        return is_string($field) && $field !== '' ? $field : null;
    }

    public function merge(ConversationModel $conversation, PropertySearchFilters $incoming): PropertySearchFilters
    {
        return $this->pendingFilters($conversation)->mergeWith($incoming);
    }

    public function savePending(
        ConversationModel $conversation,
        PropertySearchFilters $filters,
        ?string $awaitingField,
    ): void {
        $context = $conversation->context ?? [];
        $context['search'] = [
            'pending_filters' => $filters->toQueryArray(),
            'awaiting_field' => $awaitingField,
        ];

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

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

    public function clear(ConversationModel $conversation): void
    {
        $context = $conversation->context ?? [];

        unset($context['search']);

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

            return;
        }

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