*/ private const array CHANNEL_MAP = [ 'email' => 'mail', 'push' => OneSignalChannel::class, 'whatsapp' => VonageWhatsAppChannel::class, 'sms' => VonageSmsChannel::class, ]; /** @param string[] $channels Pre-filtered channel keys ('email', 'push', 'whatsapp', 'sms') */ public function __construct( public readonly string $triggerType, public readonly string $fuelType, public readonly ?float $price, public readonly array $channels, ) { $this->onQueue('notifications'); } /** @return array */ public function via(mixed $notifiable): array { return array_values(array_map( fn (string $key) => self::CHANNEL_MAP[$key] ?? $key, $this->channels, )); } public function toMail(mixed $notifiable): MailMessage { return (new MailMessage) ->subject($this->headline()) ->greeting("Hi {$notifiable->name},") ->line($this->body()) ->action('Open FuelAlert', route('dashboard')) ->line('You can change which alerts you receive in your account settings.'); } /** @return array{heading: string, message: string} */ public function toOneSignal(mixed $notifiable): array { return [ 'heading' => $this->headline(), 'message' => $this->body(), ]; } public function toVonageWhatsApp(mixed $notifiable): string { return $this->shortBody(); } public function toVonageSms(mixed $notifiable): string { return $this->shortBody(); } private function headline(): string { return match ($this->triggerType) { 'price_threshold' => 'Price hit your threshold', 'score_change' => 'Fill-up signal changed', 'scheduled_morning' => 'Morning fuel update', 'scheduled_evening' => 'Evening fuel update', default => 'Fuel alert', }; } private function body(): string { $fuel = strtoupper($this->fuelType); $price = $this->price !== null ? number_format($this->price, 1).'p' : null; return match ($this->triggerType) { 'price_threshold' => $price !== null ? "{$fuel} dropped to {$price} near you." : "{$fuel} hit your alert threshold.", 'score_change' => "The {$fuel} fill-up score has changed near you.", 'scheduled_morning', 'scheduled_evening' => "Latest {$fuel} update is ready in your dashboard.", default => "There's a new {$fuel} alert for you.", }; } /** SMS/WhatsApp must stay short — single line, ~160 chars max. */ private function shortBody(): string { return $this->headline().': '.$this->body(); } }