<?php

namespace App\Modules\Admin\Tenancy\Services;

use App\Models\User;
use App\Modules\Admin\Tenancy\Models\Subscription;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\Admin\Tenancy\Notifications\TrialExpiringSoonNotification;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Notification;

class TrialExpiryNotifier
{
    public function notifyExpiringTrials(int $withinDays = 3): void
    {
        $end = now()->addDays($withinDays);

        Subscription::query()
            ->where('status', Subscription::STATUS_TRIAL)
            ->whereNotNull('trial_ends_at')
            ->where('trial_ends_at', '>', now())
            ->where('trial_ends_at', '<=', $end)
            ->with('tenant')
            ->each(function (Subscription $subscription): void {
                $cacheKey = 'trial_ntf:'.$subscription->id.':'.now()->format('Y-m-d');
                if (! Cache::add($cacheKey, 1, now()->addDay())) {
                    return;
                }
                $tenant = $subscription->tenant;
                if ($tenant === null) {
                    return;
                }
                $hoursLeft = now()->diffInHours($subscription->trial_ends_at);
                $daysLeft = max(1, (int) ceil($hoursLeft / 24));
                $recipients = $this->tenantRecipients($tenant);
                if ($recipients->isEmpty()) {
                    return;
                }
                Notification::send(
                    $recipients,
                    new TrialExpiringSoonNotification($daysLeft, $subscription->trial_ends_at),
                );
            });
    }

    /**
     * @return Collection<int, User>
     */
    private function tenantRecipients(Tenant $tenant): Collection
    {
        $admins = User::query()
            ->where('tenant_id', $tenant->id)
            ->where('is_admin', true)
            ->get();
        if ($admins->isNotEmpty()) {
            return $admins;
        }

        return User::query()->where('tenant_id', $tenant->id)->get();
    }
}
