<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\DoctorSchedule;
use App\Models\User;
use App\Models\Appointments;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Throwable;
use App\Exceptions\GlobalException;
use App\Models\UserProfile;

class DoctorApiController extends Controller
{
    /**
     * Obtener los horarios disponibles de un doctor
     */
    public function getAvailableSchedules($doctorId)
    {
        try {
            // Verificar que el usuario existe y es un doctor
            $doctor = User::findOrFail($doctorId);
            
            // Obtener los horarios del doctor
            $schedules = DoctorSchedule::where('doctor_id', $doctorId)
                ->where('active', true)
                ->get();
                
            // Preparar los datos para el calendario
            $availableDays = [];
            
            foreach ($schedules as $schedule) {
                $availableDays[] = [
                    'dayOfWeek' => $schedule->day_of_week,
                    'dayName' => $schedule->getDayNameAttribute(),
                    'startTime' => $schedule->start_time,
                    'endTime' => $schedule->end_time
                ];
            }
            
            // Obtener citas existentes para el doctor en los próximos 30 días
            $startDate = Carbon::now();
            $endDate = Carbon::now()->addDays(30);
            
            $existingAppointments = Appointments::where('users_id', $doctorId)
                ->whereBetween('date', [$startDate, $endDate])
                ->get(['date']);
                
            $bookedSlots = [];
            
            foreach ($existingAppointments as $appointment) {
                $appointmentDate = Carbon::parse($appointment->date);
                $bookedSlots[] = [
                    'date' => $appointmentDate->format('Y-m-d'),
                    'time' => $appointmentDate->format('H:i:s')
                ];
            }
            
            return response()->json([
                'availableDays' => $availableDays,
                'bookedSlots' => $bookedSlots
            ]);
        } catch (Throwable $th) {
            return response()->json([
                'error' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Obtener las horas disponibles para una fecha específica
     */
    public function getAvailableHours(Request $request, $doctorId)
    {
        try {
            \Illuminate\Support\Facades\Log::info("en getAvailableHours 0 ");
            \Illuminate\Support\Facades\Log::info("en getAvailableHours 1 " . $request->all()['date']);
            // Validar datos de entrada
            $validated = $request->validate([
                'date' => 'required|date_format:Y-m-d',
            ]);
            
            $date = Carbon::parse($validated['date']);
            $dayOfWeek = $date->dayOfWeek;
            
            // Obtener el horario del doctor para ese día
            $schedule = DoctorSchedule::where('doctor_id', $doctorId)
                ->where('day_of_week', $dayOfWeek)
                ->where('active', true)
                ->first();
                
            if (!$schedule) {
                \Illuminate\Support\Facades\Log::info("en getAvailableHours 2 ");
                return response()->json([
                    'available' => false,
                    'message' => 'El doctor no tiene horario disponible para este día',
                    'hours' => []
                ]);
            }
            
            // Calcular bloques de horas disponibles (asumiendo citas de 30 minutos)
            $startTime = Carbon::parse($schedule->start_time);
            $endTime = Carbon::parse($schedule->end_time);
            
            $availableHours = [];
            $currentTime = $startTime->copy();
            
            while ($currentTime < $endTime) {
                $timeSlot = $currentTime->format('H:i');
                $appointmentDateTime = $date->copy()->setTimeFromTimeString($timeSlot);
                
                // Solo incluir slots futuros si es para hoy
                if ($date->isToday() && $currentTime->lt(Carbon::now())) {
                    $currentTime->addMinutes(30);
                    continue;
                }
                
                // Verificar si ya existe una cita para esta hora
                $existingAppointment = Appointments::where('users_id', $doctorId)
                    ->whereDate('date', $date->format('Y-m-d'))
                    ->whereTime('date', $timeSlot)
                    ->first();
                
                if (!$existingAppointment) {
                    $availableHours[] = [
                        'time' => $timeSlot,
                        'formatted' => $currentTime->format('g:i A')
                    ];
                }
                
                $currentTime->addMinutes(30);
            }

            \Illuminate\Support\Facades\Log::info("en getAvailableHours 3 " . count($availableHours));
            
            return response()->json([
                'available' => count($availableHours) > 0,
                'schedule' => [
                    'start' => $startTime->format('H:i'),
                    'end' => $endTime->format('H:i'),
                ],
                'hours' => $availableHours
            ]);
            
        } catch (Throwable $th) {
            \Illuminate\Support\Facades\Log::info("en getAvailableHours 4 " . $th->getMessage());
            return response()->json([
                'error' => $th->getMessage()
            ], 500);
        }
    }
    
    /**
     * Obtener los doctores por especialidad
     * 
     * @param int $specialityId
     * @return \Illuminate\Http\JsonResponse
     */
    public function getDoctorsBySpeciality($specialityId)
    {
        try {
            // Buscar perfiles de usuario que tengan la especialidad indicada
            $doctorProfiles = UserProfile::whereHas('especialities', function($query) use ($specialityId) {
                $query->where('especiality_id', $specialityId);
            })
            ->with('user')
            ->get();
            
            // Formatear la respuesta
            $doctors = [];
            foreach ($doctorProfiles as $profile) {
                // Verificar que el usuario existe y es un doctor
                if ($profile->user && User::isADoctor($profile->user)) {
                    $doctors[] = [
                        'id' => $profile->user->id,
                        'name' => $profile->firstname . ' ' . $profile->lastname
                    ];
                }
            }
            
            return response()->json([
                'doctors' => $doctors
            ]);
        } catch (Throwable $th) {
            return response()->json([
                'error' => $th->getMessage()
            ], 500);
        }
    }
} 