<?php

namespace App\Rules\SAT;

use Carbon\Carbon;
use Illuminate\Contracts\Validation\Rule;

class ValidInvoiceDate implements Rule
{
    /**
     * Horas máximas hacia atrás permitidas (SAT: 72h).
     */
    protected int $hours;

    /**
     * Instancia de "ahora" (útil para pruebas unitarias).
     */
    protected Carbon $now;

    public function __construct(int $hours = 72, ?Carbon $now = null)
    {
        $this->hours = $hours;
        $this->now   = $now ?? now();
    }

    /**
     * Valida que la fecha esté dentro del rango permitido:
     * - No más antigua que "now - 72h" (redondeado al minuto)
     * - No en el futuro (también al minuto)
     */
    public function passes($attribute, $value): bool
    {
        if (empty($value)) return true;

        try {
            // El formato ya se valida en el FormRequest, pero repetimos por seguridad
            $invoiceDate = Carbon::parse($value, config('app.timezone'));
        } catch (\Exception $e) {
            return false;
        }

        // Normalizamos todo al inicio del minuto (ignoramos segundos)
        $invoiceDate = $invoiceDate->startOfMinute();
        $now         = $this->now->copy()->startOfMinute();

        $minDate = $now->copy()->subHours($this->hours); // límite inferior
        $maxDate = $now;                                 // límite superior (no futuro)

        return $invoiceDate->betweenIncluded($minDate, $maxDate);
    }

    public function message(): string
    {
        return "La fecha de la factura debe estar dentro de las últimas {$this->hours} horas y no puede ser futura.";
    }
}
