<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use App\Models\User;
use Illuminate\Support\Facades\Log;

class ResetAppUserPassword extends Notification
{
    use Queueable;

    /**
     * The password reset token.
     *
     * @var string
     */
    public $token;

    /**
     * The password reset url for the app.
     *
     * @var string
     */
    private $resetUrl;

    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;

    /**
     * Create a notification instance.
     *
     * @param  string  $token
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Build the mail representation of the notification.
     *
     * @param  User  $notifiable
     * @return MailMessage
     */
    public function toMail(User $notifiable)
    {


        $this->locale($notifiable->language_id);

        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }

        if (!$this->resetUrl) {
            //unable to generate the firebase dynamic link
            Log::critical('Unable to generate the firebase dynamic link for user password recovery. Please make sure thar all required parameters are set.');
        }


        $subject = trans('emails.app-user-reset-password.subject', [], $notifiable->language_id);
        $title = trans('emails.app-user-reset-password.title', [], $notifiable->language_id);
        $intro   = trans('emails.app-user-reset-password.intro', [
            'name' => $notifiable->name
        ], $notifiable->language_id);
        $action  = trans('emails.app-user-reset-password.cta', [], $notifiable->language_id);
        $expire  = trans('emails.app-user-reset-password.expires', [
            'count' => '60'
        ], $notifiable->language_id);
        $ignore  = trans('emails.app-user-reset-password.ignore', [], $notifiable->language_id);
        $context = trans('emails.app-user-reset-password.context', [], $notifiable->language_id);
        $regards = trans('emails.app-user-reset-password.regards', [], $notifiable->language_id);
        $team = trans('emails.app-user-reset-password.team', [], $notifiable->language_id);

        return (new MailMessage)
            ->subject($subject)
            ->greeting($title)
            ->line($intro)
            ->line($context)
            ->action($action, $this->resetUrl)
            ->line($expire)
            ->line($ignore)
            ->line($regards)
            ->line($team);
    }

    /**
     * Set a callback that should be used when building the notification mail message.
     *
     * @param  \Closure  $callback
     * @return void
     */
    public static function toMailUsing($callback)
    {
        static::$toMailCallback = $callback;
    }


    /**
     * Generades a firebase link based on the config vales and a predetermined template
     * 
     * @return ?string
     */
    private function generateFirebaseDynamicLink(User $user): ?string
    {

        $configs = config('firebase-links');
        foreach ($configs as $idx => $config) {
            if ($config === false) {
                return null;
            }
        }

        $template = 'https://:subdomain.page.link/?link=:deepLink&apn=:apn&amv=:amv0&imv=:imv&isi=:isi&ius=:ius&ipbi=:ipbi&ibi=:ibi&ofl=:ofl';
        $deepLink = urlencode(config('firebase-links.recover_password_link')) . $this->token;
        $deepLink .= urlencode('&email=' . $user->email);
        $url      = strtr(
            $template,
            [
                ':subdomain' => config('firebase-links.app_subdomain'),
                ':deepLink'  => $deepLink,
                ':apn'       => urlencode(config('firebase-links.apn')),
                ':amv'       => urlencode(config('firebase-links.amv')),
                ':imv'       => urlencode(config('firebase-links.imv')),
                ':isi'       => urlencode(config('firebase-links.isi')),
                ':ius'       => urlencode(config('firebase-links.ius')),
                ':ipbi'      => urlencode(config('firebase-links.ipbi')),
                ':ibi'       => urlencode(config('firebase-links.ibi')),
                ':ofl'       => urlencode(config('firebase-links.ofl'))
            ],
        );

        return $url;
    }


    /**
     * Determines if the message can be sent
     * https://github.com/laravel/framework/pull/37930#issue-684438049
     * @param User $notifiable
     * @param string $channel
     * 
     * @return bool
     */
    public function shouldSend(User $notifiable, string $channel): bool
    {

        $this->resetUrl  = $this->generateFirebaseDynamicLink($notifiable);
        if (!$this->resetUrl) {
            //unable to generate the firebase dynamic link
            Log::critical('Unable to generate the firebase dynamic link for user (' . $notifiable->email . ') password recovery. Please make sure thar all required parameters are set.');
        }
        return $this->resetUrl ? true : false;
    }
}
