<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use App\Models\Equipment;
use App\Models\TimeSlot;
use App\Models\EquipmentReservation;
use Carbon\Carbon;

class EquipmentReservationSlotRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules(): array
    {
        return [
            'equipment_id' => 'required|exists:equipment,id',
            'time_slot_ids' => 'required|array|min:1',
            'time_slot_ids.*' => 'required|exists:time_slots,id',
            'notes' => 'nullable|string|max:1000',
        ];
    }

    /**
     * Get custom messages for validator errors.
     */
    public function messages(): array
    {
        return [
            'equipment_id.required' => 'Please select an equipment.',
            'equipment_id.exists' => 'The selected equipment does not exist.',
            'time_slot_ids.required' => 'Please select at least one time slot.',
            'time_slot_ids.array' => 'Time slots must be selected as a list.',
            'time_slot_ids.min' => 'Please select at least one time slot.',
            'time_slot_ids.*.required' => 'Each time slot selection is required.',
            'time_slot_ids.*.exists' => 'One or more selected time slots do not exist.',
            'notes.max' => 'Notes cannot exceed 1000 characters.',
        ];
    }

    /**
     * Configure the validator instance.
     */
    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            $this->validateTimeSlotAvailability($validator);
            $this->validateTimeSlotOwnership($validator);
            $this->validateTimeSlotNotInPast($validator);
        });
    }

    /**
     * Validate that the time slot is available and belongs to the selected equipment.
     */
    protected function validateTimeSlotAvailability($validator)
    {
        $equipmentId = $this->input('equipment_id');
        $timeSlotIds = $this->input('time_slot_ids');

        if (!$equipmentId || !$timeSlotIds) {
            return;
        }
        
        foreach ($timeSlotIds as $timeSlotId) {
            $timeSlot = TimeSlot::find($timeSlotId);
            if (!$timeSlot) {
                $validator->errors()->add('time_slot_ids', 'The selected time slot does not exist.');
                return;
            }

            // Check if the time slot belongs to the selected equipment
            if ($timeSlot->equipment_id != $equipmentId) {
                $validator->errors()->add('time_slot_ids', 'The selected time slot does not belong to the selected equipment.');
                return;
            }

            // Check if the time slot is available
            if (!$timeSlot->isAvailable()) {
                $validator->errors()->add('time_slot_ids', 'The selected time slot is not available.');
                return;
            }

            // Check if the time slot is in the future
            if (!$timeSlot->isFuture()) {
                $validator->errors()->add('time_slot_ids', 'Cannot reserve a time slot in the past.');
                return;
            }
        }
    }

    /**
     * Validate that the user doesn't already have a reservation for this time slot.
     */
    protected function validateTimeSlotOwnership($validator)
    {
        $timeSlotIds = $this->input('time_slot_ids');
        $userId = auth()->id();

        if (!$timeSlotIds || !$userId) {
            return;
        }

        // Check if user already has a reservation for any of the selected time slots
        $existingReservations = EquipmentReservation::where('user_id', $userId)
            ->whereIn('time_slot_id', $timeSlotIds)
            ->where('status', 'confirmed')
            ->get();

        if ($existingReservations->isNotEmpty()) {
            $existingSlotIds = $existingReservations->pluck('time_slot_id')->toArray();
            $validator->errors()->add('time_slot_ids', 'You already have a reservation for one or more of the selected time slots.');
            $validator->errors()->add('time_slot_ids', 'Existing reservations: ' . implode(', ', $existingSlotIds));
            return;
        }
    }

    /**
     * Validate that the time slot is not in the past.
     */
    protected function validateTimeSlotNotInPast($validator)
    {
        $timeSlotIds = $this->input('time_slot_ids');

        if (!$timeSlotIds) {
            return;
        }

        foreach ($timeSlotIds as $timeSlotId) {
            $timeSlot = TimeSlot::find($timeSlotId);
            if (!$timeSlot) {
                continue;
            }

            if ($timeSlot->isPast()) {
                $validator->errors()->add('time_slot_ids', 'Cannot reserve a time slot in the past.');
            }
        }
    }
} 