<?php

namespace App\Services;

use App\Models\CustomerNotification;
use App\Models\CustomerPushSubscription;
use Illuminate\Support\Facades\Log;
use Minishlink\WebPush\Subscription;
use Minishlink\WebPush\WebPush;

class WebPushService
{
    public function send(CustomerNotification $notification): int
    {
        $publicKey = config('services.webpush.vapid_public_key');
        $privateKey = config('services.webpush.vapid_private_key');
        $subject = config('services.webpush.vapid_subject');

        if (! $publicKey || ! $privateKey || ! $subject) {
            Log::info('customer.web_push.skipped_missing_vapid', ['notification_id' => $notification->id]);

            return 0;
        }

        $webPush = new WebPush([
            'VAPID' => [
                'subject' => $subject,
                'publicKey' => $publicKey,
                'privateKey' => $privateKey,
            ],
        ]);
        $payload = json_encode([
            'title' => $notification->title,
            'body' => $notification->body,
            'url' => $notification->url ?: route('portal.notifications'),
        ], JSON_THROW_ON_ERROR);
        $sent = 0;

        $subscriptions = $notification->customer?->pushSubscriptions()->get() ?? collect();

        foreach ($subscriptions as $subscription) {
            $webPush->queueNotification(Subscription::create([
                'endpoint' => $subscription->endpoint,
                'publicKey' => $subscription->public_key,
                'authToken' => $subscription->auth_token,
                'contentEncoding' => $subscription->content_encoding ?: 'aes128gcm',
            ]), $payload);
        }

        foreach ($webPush->flush() as $report) {
            if ($report->isSuccess()) {
                $sent++;
                continue;
            }

            Log::warning('customer.web_push.failed', [
                'notification_id' => $notification->id,
                'endpoint' => $report->getEndpoint(),
                'reason' => $report->getReason(),
            ]);

            if ($report->isSubscriptionExpired()) {
                CustomerPushSubscription::query()->where('endpoint', $report->getEndpoint())->delete();
            }
        }

        return $sent;
    }
}
