<?php

declare(strict_types=1);

namespace ImovelZapAi\Visits\Application\Queries;

use ImovelZapAi\Visits\Domain\Enums\VisitStatus;
use ImovelZapAi\Visits\Infrastructure\Persistence\Eloquent\VisitModel;

final class GetVisitDashboardQuery
{
    /**
     * @return array<string, mixed>
     */
    public function execute(string $tenantId): array
    {
        $base = VisitModel::query()->where('tenant_id', $tenantId);

        $scheduled = (clone $base)->whereIn('status', [
            VisitStatus::Scheduled,
            VisitStatus::Confirmed,
            VisitStatus::Requested,
        ])->count();

        $completed = (clone $base)->where('status', VisitStatus::Completed)->count();
        $cancelled = (clone $base)->where('status', VisitStatus::Cancelled)->count();
        $noShow = (clone $base)->where('status', VisitStatus::NoShow)->count();
        $inProgress = (clone $base)->where('status', VisitStatus::InProgress)->count();

        $attendanceDenom = $completed + $noShow;
        $attendanceRate = $attendanceDenom > 0
            ? round(($completed / $attendanceDenom) * 100, 1)
            : null;

        $byBroker = VisitModel::query()
            ->where('tenant_id', $tenantId)
            ->whereNotNull('responsible_user_id')
            ->selectRaw('responsible_user_id, count(*) as total')
            ->groupBy('responsible_user_id')
            ->orderByDesc('total')
            ->limit(10)
            ->get()
            ->map(static fn ($row) => [
                'responsible_user_id' => $row->responsible_user_id,
                'total' => (int) $row->total,
            ])
            ->all();

        $byProperty = VisitModel::query()
            ->where('tenant_id', $tenantId)
            ->whereNotNull('property_id')
            ->selectRaw('property_id, count(*) as total')
            ->groupBy('property_id')
            ->orderByDesc('total')
            ->limit(10)
            ->get()
            ->map(static fn ($row) => [
                'property_id' => $row->property_id,
                'total' => (int) $row->total,
            ])
            ->all();

        return [
            'scheduled' => $scheduled,
            'completed' => $completed,
            'cancelled' => $cancelled,
            'no_show' => $noShow,
            'in_progress' => $inProgress,
            'attendance_rate' => $attendanceRate,
            'by_broker' => $byBroker,
            'by_property' => $byProperty,
        ];
    }
}
