<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Queries;

use Illuminate\Support\Collection;
use ImovelZapAi\Conversations\Domain\Enums\ConversationStatus;
use ImovelZapAi\Conversations\Domain\Enums\HandoffStatus;
use ImovelZapAi\Conversations\Domain\Enums\PeopleFunnelStage;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ConversationModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\HumanHandoffModel;
use ImovelZapAi\Properties\Domain\Enums\PropertyInterestStatus;
use ImovelZapAi\Properties\Infrastructure\Persistence\Eloquent\PropertyInterestModel;

final class PeopleFunnelQuery
{
    /**
     * @return array<string, int>
     */
    public function counts(): array
    {
        $counts = [];

        foreach (PeopleFunnelStage::ordered() as $stage) {
            $counts[$stage->value] = $this->countFor($stage);
        }

        return $counts;
    }

    public function countFor(PeopleFunnelStage $stage): int
    {
        return match ($stage) {
            PeopleFunnelStage::ActiveConversations => $this->activeConversationsQuery()->count(),
            PeopleFunnelStage::Interested => $this->interestedQuery()->count(),
            PeopleFunnelStage::Ready => $this->readyHandoffsQuery()->count(),
            PeopleFunnelStage::Negotiating => $this->negotiatingQuery()->count(),
            PeopleFunnelStage::Closed => $this->closedQuery()->count(),
        };
    }

    public function defaultStage(): PeopleFunnelStage
    {
        if ($this->countFor(PeopleFunnelStage::Ready) > 0) {
            return PeopleFunnelStage::Ready;
        }

        if ($this->countFor(PeopleFunnelStage::Negotiating) > 0) {
            return PeopleFunnelStage::Negotiating;
        }

        return PeopleFunnelStage::ActiveConversations;
    }

    /**
     * @return Collection<int, ConversationModel|PropertyInterestModel|HumanHandoffModel>
     */
    public function items(PeopleFunnelStage $stage, int $limit = 50): Collection
    {
        return match ($stage) {
            PeopleFunnelStage::ActiveConversations => $this->activeConversationsQuery()
                ->with('contact')
                ->orderByDesc('last_message_at')
                ->limit($limit)
                ->get(),
            PeopleFunnelStage::Interested => $this->interestedQuery()
                ->with(['contact', 'property', 'conversation'])
                ->orderByDesc('updated_at')
                ->limit($limit)
                ->get(),
            PeopleFunnelStage::Ready => $this->readyHandoffsQuery()
                ->with(['contact', 'summary', 'leadScore', 'conversation'])
                ->orderByDesc('priority_score')
                ->orderBy('queued_at')
                ->limit($limit)
                ->get(),
            PeopleFunnelStage::Negotiating => $this->negotiatingQuery()
                ->with(['contact', 'property', 'conversation', 'assignedUser'])
                ->orderByDesc('updated_at')
                ->limit($limit)
                ->get(),
            PeopleFunnelStage::Closed => $this->closedQuery()
                ->with(['contact', 'property'])
                ->orderByDesc('updated_at')
                ->limit($limit)
                ->get(),
        };
    }

    public function interestedPeopleCount(): int
    {
        return $this->countFor(PeopleFunnelStage::Interested);
    }

    public function readyForAttendanceCount(): int
    {
        return $this->countFor(PeopleFunnelStage::Ready);
    }

    public function negotiatingCount(): int
    {
        return $this->countFor(PeopleFunnelStage::Negotiating);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder<ConversationModel>
     */
    private function activeConversationsQuery()
    {
        return ConversationModel::query()->whereIn('status', [
            ConversationStatus::New,
            ConversationStatus::Automated,
        ]);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder<PropertyInterestModel>
     */
    private function interestedQuery()
    {
        return PropertyInterestModel::query()->whereIn('status', [
            PropertyInterestStatus::New,
            PropertyInterestStatus::Qualifying,
        ]);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder<HumanHandoffModel>
     */
    private function readyHandoffsQuery()
    {
        return HumanHandoffModel::query()->where('status', HandoffStatus::Waiting);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder<PropertyInterestModel>
     */
    private function negotiatingQuery()
    {
        return PropertyInterestModel::query()->whereIn('status', [
            PropertyInterestStatus::InProgress,
            PropertyInterestStatus::VisitScheduled,
            PropertyInterestStatus::Negotiating,
        ]);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder<PropertyInterestModel>
     */
    private function closedQuery()
    {
        return PropertyInterestModel::query()->whereIn('status', [
            PropertyInterestStatus::ClosedWon,
            PropertyInterestStatus::ClosedRental,
            PropertyInterestStatus::Lost,
        ]);
    }
}
