<?php

declare(strict_types=1);

namespace App\Notifications;

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\URL;

/**
 * Email verification, pointed at the SPA rather than the API.
 *
 * Laravel's default link resolves to a backend route that returns JSON. Users
 * clicking a link in their inbox must land in the application, so the signed
 * URL is generated here and handed to the frontend to submit.
 */
class VerifyEmailNotification extends VerifyEmail
{
    public function toMail(mixed $notifiable): MailMessage
    {
        $url = $this->verificationUrl($notifiable);

        return (new MailMessage)
            ->subject('Confirm your Domainsansar email address')
            ->greeting('Welcome to Domainsansar')
            ->line('Confirm your email address to start browsing, buying and listing domain names.')
            ->action('Confirm email address', $url)
            ->line(sprintf(
                'This link expires in %d minutes.',
                (int) config('auth.verification.expire', 60)
            ))
            ->line('If you did not create a Domainsansar account, you can safely ignore this email.')
            ->salutation('— The Domainsansar team');
    }

    /**
     * Build a signed URL that the SPA can relay back to the API.
     *
     * The signature still covers the API route, so the SPA cannot forge a
     * verification -- it only carries the signed parameters across.
     */
    protected function verificationUrl(mixed $notifiable): string
    {
        $signed = URL::temporarySignedRoute(
            'api.v1.auth.email.verify',
            now()->addMinutes((int) config('auth.verification.expire', 60)),
            [
                'id' => $notifiable->public_id,
                'hash' => sha1((string) $notifiable->getEmailForVerification()),
            ],
            absolute: false,
        );

        return rtrim((string) config('app.frontend_url'), '/')
            .'/verify-email?'.parse_url($signed, PHP_URL_QUERY)
            .'&path='.urlencode((string) parse_url($signed, PHP_URL_PATH));
    }
}
