<?php

namespace App\Services\Communications;

use App\Enum\Contact\MessageEventType;
use App\Enum\Contact\MessageStatus;

/**
 * Maps raw provider event strings into our canonical MessageEventType and
 * MessageStatus pair, plus the ContactMessage timestamp column that should be
 * stamped (if any).
 */
class ProviderEventMapper
{
    /**
     * @return array{event: MessageEventType, status: ?MessageStatus, timestamp_column: ?string}
     */
    public function mapSendGrid(string $eventName): array
    {
        return match (strtolower($eventName)) {
            'processed' => ['event' => MessageEventType::PROCESSED, 'status' => MessageStatus::SENDING, 'timestamp_column' => null],
            'delivered' => ['event' => MessageEventType::DELIVERED, 'status' => MessageStatus::DELIVERED, 'timestamp_column' => 'delivered_at'],
            'open' => ['event' => MessageEventType::OPEN, 'status' => MessageStatus::OPENED, 'timestamp_column' => 'opened_at'],
            'click' => ['event' => MessageEventType::CLICK, 'status' => MessageStatus::CLICKED, 'timestamp_column' => null],
            'bounce' => ['event' => MessageEventType::BOUNCE, 'status' => MessageStatus::BOUNCED, 'timestamp_column' => 'failed_at'],
            'dropped' => ['event' => MessageEventType::DROPPED, 'status' => MessageStatus::DROPPED, 'timestamp_column' => 'failed_at'],
            'spamreport' => ['event' => MessageEventType::SPAM_REPORT, 'status' => MessageStatus::SPAM_REPORT, 'timestamp_column' => 'failed_at'],
            'deferred' => ['event' => MessageEventType::DEFERRED, 'status' => MessageStatus::DEFERRED, 'timestamp_column' => null],
            'unsubscribe', 'group_unsubscribe' => ['event' => MessageEventType::OPT_OUT, 'status' => null, 'timestamp_column' => null],
            default => ['event' => MessageEventType::UNKNOWN, 'status' => null, 'timestamp_column' => null],
        };
    }

    /**
     * @return array{event: MessageEventType, status: ?MessageStatus, timestamp_column: ?string}
     */
    public function mapTwilio(string $messageStatus): array
    {
        return match (strtolower($messageStatus)) {
            'queued', 'accepted' => ['event' => MessageEventType::QUEUED, 'status' => MessageStatus::QUEUED, 'timestamp_column' => null],
            'sending' => ['event' => MessageEventType::SENDING, 'status' => MessageStatus::SENDING, 'timestamp_column' => null],
            'sent' => ['event' => MessageEventType::SENT, 'status' => MessageStatus::SENT, 'timestamp_column' => 'sent_at'],
            'delivered' => ['event' => MessageEventType::DELIVERED, 'status' => MessageStatus::DELIVERED, 'timestamp_column' => 'delivered_at'],
            'failed' => ['event' => MessageEventType::FAILED, 'status' => MessageStatus::FAILED, 'timestamp_column' => 'failed_at'],
            'undelivered' => ['event' => MessageEventType::UNDELIVERED, 'status' => MessageStatus::UNDELIVERED, 'timestamp_column' => 'failed_at'],
            default => ['event' => MessageEventType::UNKNOWN, 'status' => null, 'timestamp_column' => null],
        };
    }
}
