<?php

declare(strict_types=1);

namespace App\Notifications;

use App\Models\WinbackCampaign;
use App\Models\WinbackRecipient;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\URL;

class WinbackEmailNotification extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * @param  array{delay_days: int, subject: string, body: string}  $emailConfig
     */
    public function __construct(
        public WinbackCampaign $campaign,
        public WinbackRecipient $recipient,
        public array $emailConfig,
    ) {}

    /** @return array<int, string> */
    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        $unsubscribeUrl = URL::signedRoute('winback.unsubscribe', [
            'recipient' => $this->recipient->id,
        ]);

        $pricingUrl = 'https://'.config('app.domains.marketing').'/pricing';

        $mail = (new MailMessage)
            ->subject($this->emailConfig['subject'])
            ->greeting("Hello {$notifiable->name},")
            ->line($this->emailConfig['body']);

        if ($this->campaign->offer_type !== 'none' && $this->campaign->offer_value) {
            $offerDescription = $this->buildOfferDescription();
            $mail->line('');
            $mail->line("**Special Offer:** {$offerDescription}");

            if ($this->campaign->coupon_code) {
                $mail->line("Use coupon code: **{$this->campaign->coupon_code}**");
            }

            if ($this->campaign->offer_duration_days) {
                $mail->line("This offer is valid for {$this->campaign->offer_duration_days} days.");
            }
        }

        $mail->action('View Plans', $pricingUrl);
        $mail->line('');
        $mail->line("[Unsubscribe from these emails]({$unsubscribeUrl})");

        return $mail;
    }

    private function buildOfferDescription(): string
    {
        return match ($this->campaign->offer_type) {
            'discount' => number_format((float) $this->campaign->offer_value, 0).'% off your next subscription',
            'credit' => '$'.number_format((float) $this->campaign->offer_value, 2).' account credit',
            'free_upgrade' => 'Free upgrade for '.((int) $this->campaign->offer_duration_days).' days',
            default => '',
        };
    }
}
