<?php

namespace App\Modules\Integrations\Platform\Support;

use App\Modules\Integrations\Platform\Models\IntegrationEvent;
use Illuminate\Support\Str;

final class IntegrationEventFactory
{
    /**
     * Immutable, tenant-scoped, retry-safe event recording (outbox).
     *
     * @param  array<string, mixed>  $payload
     */
    public function record(int $tenantId, string $name, int $version, array $payload, ?\DateTimeInterface $occurredAt = null): IntegrationEvent
    {
        $occurredAt = $occurredAt ?? now();
        $hash = self::payloadHash($tenantId, $name, $version, $payload);

        $existing = IntegrationEvent::query()
            ->where('tenant_id', $tenantId)
            ->where('payload_hash', $hash)
            ->first();
        if ($existing instanceof IntegrationEvent) {
            return $existing;
        }

        return IntegrationEvent::query()->create([
            'id' => (string) Str::uuid(),
            'tenant_id' => $tenantId,
            'name' => $name,
            'version' => $version,
            'payload' => $payload,
            'payload_hash' => $hash,
            'occurred_at' => $occurredAt,
        ]);
    }

    /**
     * @param  array<string, mixed>  $payload
     */
    public static function payloadHash(int $tenantId, string $name, int $version, array $payload): string
    {
        $json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

        return hash('sha256', $tenantId.'|'.$name.'|'.$version.'|'.$json);
    }
}

