<?php

namespace App\Modules\Integrations\Platform\Services;

use App\Modules\Integrations\Platform\Jobs\DeliverWebhookJob;
use App\Modules\Integrations\Platform\Models\IntegrationEvent;
use App\Modules\Integrations\Platform\Models\IntegrationWebhookDelivery;
use App\Modules\Integrations\Platform\Repositories\IntegrationWebhookRepository;
use Illuminate\Support\Facades\DB;

final class WebhookDispatchService
{
    public function __construct(private readonly IntegrationWebhookRepository $webhooks) {}

    public function dispatchForEvent(IntegrationEvent $event, bool $isReplay = false): int
    {
        $topic = $event->name.'.v'.$event->version;
        $targets = $this->webhooks->activeForTenantAndTopic((int) $event->tenant_id, $topic);
        $deliveryIds = [];

        foreach ($targets as $wh) {
            $delivery = IntegrationWebhookDelivery::query()->create([
                'tenant_id' => (int) $event->tenant_id,
                'webhook_id' => (int) $wh->id,
                'event_id' => (string) $event->id,
                'attempt' => 0,
                'attempt_count' => 0,
                'status' => 'pending',
            ]);
            $deliveryIds[] = (int) $delivery->id;
        }

        if (! $isReplay) {
            $event->forceFill(['dispatched_at' => now()])->save();
        }

        DB::afterCommit(function () use ($deliveryIds): void {
            foreach ($deliveryIds as $deliveryId) {
                DeliverWebhookJob::dispatch($deliveryId);
            }
        });

        return count($deliveryIds);
    }
}
