<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class JobAlertEmailLog extends Model
{
    public const STATUS_SENT = 'sent';

    public const STATUS_FAILED = 'failed';

    public const STATUS_SKIPPED = 'skipped';

    protected $fillable = [
        'user_id',
        'email_delivery_log_id',
        'status',
        'provider_message_id',
        'brevo_message_id',
        'job_count',
        'imported_job_ids',
        'sent_at',
        'delivered_at',
        'opened_at',
        'clicked_at',
        'unsubscribed_at',
        'bounced_at',
        'event_counts',
        'last_event_at',
        'failure_reason',
    ];

    /**
     * @return BelongsTo<User, $this>
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * @return BelongsTo<EmailDeliveryLog, $this>
     */
    public function emailDeliveryLog(): BelongsTo
    {
        return $this->belongsTo(EmailDeliveryLog::class);
    }

    public function markEvent(string $event, ?string $occurredAt = null): void
    {
        $timestamp = $occurredAt ? rescue(fn () => \Illuminate\Support\Carbon::parse($occurredAt), now(), report: false) : now();
        $counts = $this->event_counts ?: [];
        $counts[$event] = ((int) ($counts[$event] ?? 0)) + 1;

        $updates = [
            'event_counts' => $counts,
            'last_event_at' => $timestamp,
        ];

        match ($event) {
            'delivered' => $updates += ['delivered_at' => $this->delivered_at ?: $timestamp],
            'opened' => $updates += ['opened_at' => $this->opened_at ?: $timestamp],
            'clicked' => $updates += ['clicked_at' => $this->clicked_at ?: $timestamp],
            'unsubscribed' => $updates += ['unsubscribed_at' => $this->unsubscribed_at ?: $timestamp],
            'bounced' => $updates += ['bounced_at' => $this->bounced_at ?: $timestamp],
            default => null,
        };

        $this->forceFill($updates)->save();
    }

    /**
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'job_count' => 'integer',
            'imported_job_ids' => 'array',
            'sent_at' => 'datetime',
            'delivered_at' => 'datetime',
            'opened_at' => 'datetime',
            'clicked_at' => 'datetime',
            'unsubscribed_at' => 'datetime',
            'bounced_at' => 'datetime',
            'event_counts' => 'array',
            'last_event_at' => 'datetime',
        ];
    }
}
