<?php

declare(strict_types=1);

namespace App\Notifications;

use App\Models\Subscription;
use Filament\Notifications\Notification as FilamentNotification;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;

/**
 * Aviso in-app (campana del panel, canal `database`) de que la prueba o la
 * suscripción de una empresa está por vencer. Lo dispara el comando
 * `subscriptions:notify-expiring` a T-3 y T-1 días (#166).
 *
 * No usa email: prod no tiene SMTP configurado, así que va por `database` como
 * `SubscriptionRequestNotification`. Es informativo — el cobro es manual/offline.
 */
class SubscriptionExpiringNotification extends Notification implements ShouldQueue
{
    use Queueable;

    public const CONTEXT_TRIAL = 'trial';

    public const CONTEXT_RENEWAL = 'renewal';

    public const CONTEXT_GRACE = 'grace';

    public function __construct(
        public Subscription $subscription,
        public int $daysLeft,
        public string $context
    ) {}

    /**
     * @return array<int, string>
     */
    public function via(object $notifiable): array
    {
        return ['database'];
    }

    /**
     * @return array<string, mixed>
     */
    public function toDatabase(object $notifiable): array
    {
        return FilamentNotification::make()
            ->title($this->getTitle())
            ->body($this->getBody())
            ->icon($this->getIcon())
            ->iconColor($this->getIconColor())
            ->getDatabaseMessage();
    }

    private function dias(): string
    {
        return $this->daysLeft === 1 ? '1 día' : "{$this->daysLeft} días";
    }

    protected function getTitle(): string
    {
        return match ($this->context) {
            self::CONTEXT_TRIAL => 'Tu prueba está por terminar',
            self::CONTEXT_GRACE => 'Período de gracia por vencer',
            default => 'Tu suscripción está por vencer',
        };
    }

    protected function getBody(): string
    {
        $dias = $this->dias();

        return match ($this->context) {
            self::CONTEXT_TRIAL => "Tu prueba de Credify GO! termina en {$dias}. Activa tu suscripción para no perder el acceso ni tus datos.",
            self::CONTEXT_GRACE => "Tu acceso termina en {$dias}. Regulariza tu suscripción para no quedar bloqueado.",
            default => "Tu suscripción vence en {$dias}. Coordina tu pago para renovar sin interrupciones.",
        };
    }

    protected function getIcon(): string
    {
        return $this->context === self::CONTEXT_GRACE
            ? 'heroicon-o-exclamation-triangle'
            : 'heroicon-o-clock';
    }

    protected function getIconColor(): string
    {
        return $this->context === self::CONTEXT_GRACE ? 'danger' : 'warning';
    }
}
