<?php

namespace App\Http\Requests\Api\V1;

use App\Services\Api\ApiResponse;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;

class MoodleApiRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true; // La autorización se maneja en el middleware ProductToken
    }

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules(): array
    {
        $action = $this->input('action');

        $rules = [
            'action' => ['required', 'string', 'in:sync,licence,products,scss,scss-cdn,js,setup,features,tutorials,resources,data,plugins,stats'],
            'host' => ['required', 'string', 'url', 'max:500'],
            'projectid' => ['nullable', 'string', 'max:255'],
        ];

        // Para sync y stats, site/environment.version y release son opcionales; para el resto required_without
        if (in_array($action, ['sync', 'stats'])) {
            $rules['environment.version'] = ['nullable', 'string', 'max:100'];
            $rules['environment.release'] = ['nullable', 'string', 'max:100'];
            $rules['site.version'] = ['nullable', 'string', 'max:100'];
            $rules['site.release'] = ['nullable', 'string', 'max:100'];
        } else {
            $rules['environment.version'] = ['required_without:site.version', 'string', 'max:100'];
            $rules['environment.release'] = ['required_without:site.release', 'string', 'max:100'];
            $rules['site.version'] = ['required_without:environment.version', 'string', 'max:100'];
            $rules['site.release'] = ['required_without:environment.release', 'string', 'max:100'];
        }

        $rules['environment.lastversion'] = ['nullable', 'string', 'max:100'];
        $rules['environment.lastminor'] = ['nullable', 'string', 'max:100'];
        $rules['environment.token'] = ['nullable', 'string', 'max:500'];
        $rules['environment.type'] = ['nullable', 'string', 'in:moodle,workplace,goodle,wordpress,other'];
        $rules['environment.env'] = ['nullable', 'string', 'in:pro,pre,develop,local'];
        $rules['site.lastversion'] = ['nullable', 'string', 'max:100'];
        $rules['site.lastminor'] = ['nullable', 'string', 'max:100'];
        $rules['site.token'] = ['nullable', 'string', 'max:500'];
        $rules['site.type'] = ['nullable', 'string', 'in:moodle,workplace,goodle,wordpress,other'];
        $rules['site.env'] = ['nullable', 'string', 'in:pro,pre,develop,local'];

        // Para la acción 'products' y 'stats', plugin y version son opcionales
        if (in_array($action, ['products', 'stats'])) {
            $rules['plugin'] = ['nullable', 'string', 'max:255'];
            $rules['version'] = ['nullable', 'string', 'regex:/^\d{10}$/']; // YYYYMMDDXX
        } else {
            $rules['plugin'] = ['required', 'string', 'max:255'];
            $rules['version'] = ['required', 'string', 'regex:/^\d{10}$/']; // YYYYMMDDXX
        }

        // El campo data es obligatorio para data, plugins, sync y stats
        if (in_array($action, ['data', 'plugins', 'sync', 'stats'])) {
            $rules['data'] = ['required', 'array'];
            if ($action === 'sync') {
                $rules['data.plugins'] = ['required', 'array'];
            }
        } else {
            $rules['data'] = ['nullable', 'array'];
        }

        // Para stats, date es obligatorio (YYYY-MM-DD)
        if ($action === 'stats') {
            $rules['date'] = ['required', 'date', 'date_format:Y-m-d'];
        }

        return $rules;
    }

    /**
     * Get custom messages for validator errors.
     */
    public function messages(): array
    {
        return [
            'action.required' => 'El campo action es obligatorio.',
            'action.in' => 'El campo action debe ser uno de: sync, licence, products, scss, scss-cdn, js, setup, features, tutorials, resources, data, plugins, stats.',
            'plugin.required' => 'El campo plugin es obligatorio.',
            'host.required' => 'El campo host es obligatorio.',
            'host.url' => 'El campo host debe ser una URL válida.',
            'version.required' => 'El campo version es obligatorio.',
            'version.regex' => 'El campo version debe tener el formato YYYYMMDDXX (10 dígitos).',
            'environment.version.required_without' => 'El campo environment.version o site.version es obligatorio.',
            'environment.release.required_without' => 'El campo environment.release o site.release es obligatorio.',
            'site.version.required_without' => 'El campo site.version o environment.version es obligatorio.',
            'site.release.required_without' => 'El campo site.release o environment.release es obligatorio.',
            'environment.type.in' => 'El campo environment.type debe ser uno de: moodle, workplace, goodle, wordpress, other.',
            'environment.env.in' => 'El campo environment.env debe ser uno de: pro, pre, develop, local.',
            'site.type.in' => 'El campo site.type debe ser uno de: moodle, workplace, goodle, wordpress, other.',
            'site.env.in' => 'El campo site.env debe ser uno de: pro, pre, develop, local.',
            'data.required' => 'El campo data es obligatorio para la acción seleccionada.',
            'data.array' => 'El campo data debe ser un array.',
            'data.plugins.required' => 'El campo data.plugins es obligatorio para la acción sync.',
            'data.plugins.array' => 'El campo data.plugins debe ser un array.',
            'date.required' => 'El campo date es obligatorio para la acción stats.',
            'date.date_format' => 'El campo date debe tener el formato YYYY-MM-DD.',
        ];
    }

    /**
     * Maneja errores de validación devolviendo JSON en formato estándar de la API
     *
     * @param Validator $validator
     * @return void
     * @throws HttpResponseException
     */
    protected function failedValidation(Validator $validator): void
    {
        $errors = $validator->errors()->all();
        $firstError = $errors[0] ?? 'Error de validación';

        throw new HttpResponseException(
            ApiResponse::error(
                $this->input('action', 'unknown'),
                $firstError,
                400,
                ['errors' => $errors],
                422
            )
        );
    }
}

