<?php

namespace App\Console\Commands;

use App\Models\Subscription;
// Importamos la clase Carbon para la manipulación de fechas
use Carbon\Carbon;
// Importamos el modelo de Eloquent para trabajar directamente con la tabla
use Illuminate\Console\Command;

class UpdateSubscriptionsStatus extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'subscriptions:update-status';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Avanza la máquina de estados de suscripciones: trial/active vencidas → grace; grace lapsada → expired.';

    /**
     * Execute the console command.
     *
     * Recorre la máquina de estados real (trial/active → grace → expired) usando
     * los métodos del modelo (startGracePeriod/expire), que disparan los eventos
     * Eloquent e invalidan la caché de estado por company (ver Subscription::booted).
     * El antiguo `update(['is_active'=>false])` solo movía is_active, nunca el
     * `status`, así que `grace`/`expired` jamás se alcanzaban (issue #89).
     */
    public function handle(): int
    {
        $this->info('Avanzando estados de suscripciones...');

        $now = Carbon::now();

        try {
            // 1) trial/active vencidas → período de gracia (grace_period_ends_at
            //    se fija desde ends_at dentro de startGracePeriod()).
            $toGrace = Subscription::whereIn('status', [
                Subscription::STATUS_ACTIVE,
                Subscription::STATUS_TRIAL,
            ])
                ->where('ends_at', '<', $now)
                ->get();

            foreach ($toGrace as $subscription) {
                $subscription->startGracePeriod();
            }

            // 2) grace cuya ventana ya lapsó → expirada. Se consulta DESPUÉS del
            //    paso 1 para capturar también las que acaban de entrar a grace con
            //    la ventana ya vencida (suscripciones vencidas hace > GRACE_PERIOD_DAYS).
            $toExpire = Subscription::where('status', Subscription::STATUS_GRACE)
                ->where('grace_period_ends_at', '<', $now)
                ->get();

            foreach ($toExpire as $subscription) {
                $subscription->expire();
            }

            $this->info("Finalizado. {$toGrace->count()} → gracia, {$toExpire->count()} → expiradas.");

            return self::SUCCESS;
        } catch (\Throwable $e) {
            $this->error('Error al actualizar suscripciones: '.$e->getMessage());

            return self::FAILURE;
        }
    }
}
