<?php

namespace Modules\ClinicCore\Entities\Services;

use Modules\ClinicCore\Entities\ClcAppointment;
use Modules\ClinicCore\Entities\ClcDoctor;
use Carbon\Carbon;

class AppointmentService
{
    public function generateRefNo(): string
    {
        return 'APT-' . strtoupper(substr(uniqid(), -8));
    }

    /**
     * Check if a doctor has a conflicting appointment in the given time window.
     */
    public function isDoctorAvailable(int $doctorId, string $date, string $time, int $durationMinutes, ?int $excludeAppointmentId = null): bool
    {
        $start = Carbon::parse("$date $time");
        $end   = $start->copy()->addMinutes($durationMinutes);

        $query = ClcAppointment::where('doctor_id', $doctorId)
            ->whereDate('appointment_date', $date)
            ->whereNotIn('status', ['cancelled', 'no_show']);

        if ($excludeAppointmentId) {
            $query->where('id', '!=', $excludeAppointmentId);
        }

        $conflicts = $query->get();

        foreach ($conflicts as $apt) {
            $aptStart = Carbon::parse($apt->appointment_date->format('Y-m-d') . ' ' . $apt->appointment_time);
            $aptEnd   = $aptStart->copy()->addMinutes($apt->duration_minutes ?? 30);

            if ($start->lt($aptEnd) && $end->gt($aptStart)) {
                return false;
            }
        }

        return true;
    }

    public function getTodayAppointments(int $businessId): \Illuminate\Database\Eloquent\Collection
    {
        return ClcAppointment::with(['pet', 'owner', 'doctor'])
            ->where('business_id', $businessId)
            ->whereDate('appointment_date', Carbon::today())
            ->whereNotIn('status', ['cancelled', 'no_show'])
            ->orderBy('appointment_time')
            ->get();
    }
}
