<?php

declare(strict_types=1);

namespace App\Framework\Webhook\Events;

use App\Framework\Events\DomainEvent;
use DateTimeImmutable;

/**
 * Domain event fired when a webhook is successfully sent
 * Tracks outgoing webhook delivery for monitoring and debugging
 */
final readonly class WebhookSent implements DomainEvent
{
    public function __construct(
        public string $url,
        public array $payload,
        public int $responseCode,
        public DateTimeImmutable $sentAt,
        public ?string $provider = null,
        public ?string $webhookId = null,
        public ?float $duration = null
    ) {
    }

    public static function create(
        string $url,
        array $payload,
        int $responseCode,
        ?string $provider = null,
        ?float $duration = null
    ): self {
        return new self(
            url: $url,
            payload: $payload,
            responseCode: $responseCode,
            sentAt: new DateTimeImmutable(),
            provider: $provider,
            webhookId: $payload['webhook_id'] ?? null,
            duration: $duration
        );
    }

    public function getEventName(): string
    {
        return 'webhook.sent';
    }

    public function getAggregateId(): string
    {
        return $this->webhookId ?? md5($this->url);
    }

    public function wasSuccessful(): bool
    {
        return $this->responseCode >= 200 && $this->responseCode < 300;
    }

    public function toArray(): array
    {
        return [
            'url' => $this->url,
            'provider' => $this->provider,
            'response_code' => $this->responseCode,
            'webhook_id' => $this->webhookId,
            'sent_at' => $this->sentAt->format('c'),
            'duration_ms' => $this->duration ? round($this->duration * 1000, 2) : null,
            'payload_size' => strlen(json_encode($this->payload)),
            'successful' => $this->wasSuccessful(),
        ];
    }
}
