<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ScheduleRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        $rules = [
            'client_id'                => 'sometimes|required|exists:clients,id',
            'provider_id'              => 'sometimes|required|exists:providers,id',
            'address_id'               => 'sometimes|required|exists:addresses,id',
            'date'                     => 'nullable|date|after_or_equal:today',
            'dates'                    => 'nullable|array',
            'dates.*'                  => 'date|after_or_equal:today',
            'schedules'                => 'nullable|array',
            'schedules.*.date'         => 'required|date|after_or_equal:today',
            'schedules.*.period_type'  => 'required|in:2,4,6,8',
            'schedules.*.start_time'   => 'required|date_format:H:i',
            'schedules.*.end_time'     => 'required|date_format:H:i|after:schedules.*.start_time',
            'schedules.*.total_amount' => 'required|numeric|min:0',
            'schedules.*.offers_meal'  => 'nullable|boolean',
            'offers_meal'              => 'sometimes|nullable|boolean',
            'period_type'              => 'sometimes|required|in:2,4,6,8',
            'schedule_type'            => 'sometimes|in:default,custom',
            'start_time'               => 'sometimes|required|date_format:H:i',
            'end_time'                 => 'sometimes|required|date_format:H:i|after:start_time',
            'status'                   => 'sometimes|in:pending,accepted,rejected,paid,cancelled,started,finished',
            'code_verified'            => 'sometimes|boolean',
        ];

        if ($this->isMethod('POST')) {
            $rules['client_id']                = 'required|exists:clients,id';
            $rules['provider_id']              = 'required|exists:providers,id';
            $rules['address_id']               = 'required|exists:addresses,id';
            $rules['date']                     = 'required_without_all:dates,schedules|nullable|date|after_or_equal:today';
            $rules['dates']                    = 'nullable|array';
            $rules['dates.*']                  = 'date|after_or_equal:today';
            $rules['schedules']                = 'nullable|array|min:1';
            $rules['schedules.*.date']         = 'required|date|after_or_equal:today';
            $rules['schedules.*.period_type']  = 'required|in:2,4,6,8';
            $rules['schedules.*.start_time']   = 'required|date_format:H:i';
            $rules['schedules.*.end_time']     = 'required|date_format:H:i|after:schedules.*.start_time';
            $rules['schedules.*.total_amount'] = 'required|numeric|min:0';
            $rules['period_type']              = 'required_without:schedules|in:2,4,6,8';
            $rules['start_time']               = 'required_without:schedules|date_format:H:i';
            $rules['end_time']                 = 'required_without:schedules|date_format:H:i|after:start_time';
            $rules['status']                   = 'in:pending';
        }

        return $rules;
    }

    public function messages(): array
    {
        return [
            'client_id.required'                 => 'O cliente é obrigatório.',
            'client_id.exists'                   => 'Cliente não encontrado.',
            'provider_id.required'               => 'O prestador é obrigatório.',
            'provider_id.exists'                 => 'Prestador não encontrado.',
            'address_id.required'                => 'O endereço é obrigatório.',
            'address_id.exists'                  => 'Endereço não encontrado.',
            'date.required_without_all'          => 'A data é obrigatória quando não há múltiplas datas ou agendamentos.',
            'date.date'                          => 'Data inválida.',
            'date.after_or_equal'                => 'A data deve ser hoje ou futura.',
            'dates.array'                        => 'Datas devem ser um array.',
            'dates.*.date'                       => 'Uma das datas é inválida.',
            'dates.*.after_or_equal'             => 'Todas as datas devem ser hoje ou futuras.',
            'schedules.array'                    => 'Agendamentos devem ser um array.',
            'schedules.min'                      => 'É necessário pelo menos um agendamento.',
            'schedules.*.date.required'          => 'A data do agendamento é obrigatória.',
            'schedules.*.date.date'              => 'Data do agendamento inválida.',
            'schedules.*.date.after_or_equal'    => 'A data do agendamento deve ser hoje ou futura.',
            'schedules.*.period_type.required'   => 'O período do agendamento é obrigatório.',
            'schedules.*.period_type.in'         => 'Período do agendamento inválido.',
            'schedules.*.start_time.required'    => 'O horário de início do agendamento é obrigatório.',
            'schedules.*.start_time.date_format' => 'Formato de horário de início inválido.',
            'schedules.*.end_time.required'      => 'O horário de término do agendamento é obrigatório.',
            'schedules.*.end_time.date_format'   => 'Formato de horário de término inválido.',
            'schedules.*.end_time.after'         => 'O horário de término deve ser após o horário de início.',
            'schedules.*.total_amount.required'  => 'O valor total do agendamento é obrigatório.',
            'schedules.*.total_amount.numeric'   => 'O valor total deve ser numérico.',
            'schedules.*.total_amount.min'       => 'O valor total deve ser maior ou igual a zero.',
            'period_type.required'               => 'O período é obrigatório.',
            'period_type.required_without'       => 'O período é obrigatório quando não há agendamentos múltiplos.',
            'period_type.in'                     => 'Período inválido.',
            'start_time.required'                => 'O horário de início é obrigatório.',
            'start_time.required_without'        => 'O horário de início é obrigatório quando não há agendamentos múltiplos.',
            'start_time.date_format'             => 'Formato de horário inválido.',
            'end_time.required'                  => 'O horário de término é obrigatório.',
            'end_time.required_without'          => 'O horário de término é obrigatório quando não há agendamentos múltiplos.',
            'end_time.date_format'               => 'Formato de horário inválido.',
            'end_time.after'                     => 'O horário de término deve ser após o horário de início.',
            'status.in'                          => 'Status inválido.',
        ];
    }
}
