<?php

namespace App\Repositories\Eloquent;

use App\Models\Booking;

class BookingManagementRepository
{
    public function paginate(array $filters = [])
    {
        return Booking::with(['client.profile', 'professional.user.profile', 'professional.profession'])
            ->when($filters['q'] ?? null, fn ($query, $term) => $query->where(fn ($search) => $search
                ->where('uuid', 'like', "%{$term}%")
                ->orWhereHas('client.profile', fn ($profile) => $profile->where('full_name', 'like', "%{$term}%"))
                ->orWhereHas('professional.user.profile', fn ($profile) => $profile->where('full_name', 'like', "%{$term}%"))))
            ->when($filters['status'] ?? null, fn ($query, $status) => match ($status) {
                'completed' => $query->whereNotNull('consultation_closed_at'),
                'in_progress' => $query->whereNotNull('consultation_started_at')->whereNull('consultation_closed_at'),
                default => $query->where('status', $status)->whereNull('consultation_closed_at'),
            })
            ->when($filters['payment_status'] ?? null, fn ($query, $status) => $query->where('payment_status', $status))
            ->when($filters['type'] ?? null, fn ($query, $type) => $query->where('type', $type))
            ->when($filters['date_from'] ?? null, fn ($query, $date) => $query->whereDate('date', '>=', $date))
            ->when($filters['date_to'] ?? null, fn ($query, $date) => $query->whereDate('date', '<=', $date))
            ->latest()->paginate(12)->withQueryString();
    }

    public function stats(): array
    {
        return [
            'total' => Booking::count(),
            'upcoming' => Booking::where('status', 'accepted')->where('payment_status', 'paid')->whereNull('consultation_closed_at')->whereDate('date', '>=', today())->count(),
            'in_progress' => Booking::whereNotNull('consultation_started_at')->whereNull('consultation_closed_at')->count(),
            'completed' => Booking::whereNotNull('consultation_closed_at')->count(),
            'paid_value' => (float) Booking::where('payment_status', 'paid')->sum('amount'),
        ];
    }

    public function find(int $id): Booking
    {
        return Booking::with([
            'client.profile', 'professional.user.profile', 'professional.profession', 'profession',
            'payments:id,booking_id,status,amount,reference_id,created_at,updated_at',
            'payout', 'ratings.rateBy.profile', 'attachments',
        ])->findOrFail($id);
    }
}
