<?php

namespace App\Http\Requests\Auth;

use App\Models\Admin;
use App\Rules\Turnstile;
use Carbon\Carbon;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

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

    public function rules(): array
    {
        return [
            'token' => 'required|string',
            'email' => 'required|email',
            'password' => 'required|string|confirmed|min:8|max:25',
            'turnstile_token' => ['required', 'string', new Turnstile()],
        ];
    }

    public function messages(): array
    {
        return [
            'email.required' => 'El correo es obligatorio.',
            'email.email' => 'El correo no es válido.',
            'password.required' => 'La contraseña es obligatoria.',
            'password.confirmed' => 'La confirmación de contraseña no coincide.',
            'password.min' => 'La contraseña debe tener al menos 8 caracteres.',
            'password.max' => 'La contraseña no debe superar los 25 caracteres.',
            'token.required' => 'El token es obligatorio.',
            'turnstile_token.required' => 'Completá la validación de seguridad.',
        ];
    }

    public function getAdminByToken(): Admin
    {
        $passwordReset = DB::table('password_resets')
            ->where('token', $this->string('token')->toString())
            ->first();

        $this->validateToken($passwordReset);

        $admin = Admin::query()
            ->where('email', $passwordReset->email)
            ->where('estado', true)
            ->first();

        if (! $admin) {
            throw ValidationException::withMessages([
                'email' => 'No existe un administrador activo para este token.',
            ]);
        }

        if ($admin->email !== $this->string('email')->toString()) {
            throw ValidationException::withMessages([
                'email' => 'El correo no coincide con el token recibido.',
            ]);
        }

        return $admin;
    }

    private function validateToken($passwordReset): void
    {
        if (! $passwordReset) {
            throw ValidationException::withMessages([
                'token' => 'El token es inválido.',
            ]);
        }

        if (Carbon::parse($passwordReset->created_at)->diffInMinutes(now()) >= 60) {
            throw ValidationException::withMessages([
                'token' => 'El token ha expirado.',
            ]);
        }
    }
}
