<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Account;
use App\Components\Functions;
use App\Notification;
use App\User;
use Dompdf\Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use LaravelFCM\Message\OptionsBuilder;
use LaravelFCM\Message\PayloadDataBuilder;
use LaravelFCM\Message\PayloadNotificationBuilder;
use FCM;
use Minishlink\WebPush\Subscription;
use Minishlink\WebPush\WebPush;
use Mockery\Matcher\Not;

class PushNotification implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    protected $notificationId;

    public function __construct($notificationId)
    {
        //
        $this->notificationId = $notificationId;
    }

    public function pushNotification($accountId, $title, $notificationId, $token, $content, $isAndroid, $payload)
    {

        $optionBuiler = new OptionsBuilder();
        $optionBuiler->setTimeToLive(60 * 20);

        $notificationBuilder = new PayloadNotificationBuilder($title);

        $badge = Functions::countBadge($accountId);

        $notificationBuilder->setBody($content)
            ->setBadge($badge)
            ->setSound('default');

        $dataBuilder = new PayloadDataBuilder();

        if (!empty($payload)) {
            $payloadArr = json_decode($payload, true);
        }

        $payloadArr['notification_id'] = $notificationId;

        if (!empty($payloadArr)) {
            if ($isAndroid == 'yes') {
                $payloadArr['title'] = $title;
                $payloadArr['badge'] = $badge;
                $payloadArr['body'] = $content;
            }

            $dataBuilder->addData($payloadArr);
        } else {

            if ($isAndroid == 'yes') {

                $payloadArr['title'] = null;
                $payloadArr['badge'] = null;
                $payloadArr['body'] = null;

            }

            $dataBuilder->addData([
                'type' => null,
                'id' => null
            ]);
        }

        $option = $optionBuiler->build();
        $notification = $notificationBuilder->build();

        $data = $dataBuilder->build();

        if ($isAndroid == 'yes') {

            $downstreamResponse = FCM::sendTo($token, $option, $notification, $data);

        } else {
            $downstreamResponse = FCM::sendTo($token, $option, $notification, $data);
        }

        if (!empty($downstreamResponse)) {
            \App\Models\Notification::find($notificationId)->forceFill([
                'status' => \App\Models\Notification::PUSHED
            ])->save();

            $downstreamResponse->numberSuccess();
            $downstreamResponse->numberFailure();
            $downstreamResponse->numberModification();

//return Array - you must remove all this tokens in your database
            $deleteTokens = $downstreamResponse->tokensToDelete();

            if (is_array($deleteTokens)) {

                foreach ($deleteTokens as $deleteToken) {
                    User::where('android_token', $deleteToken)->update([
                        'android_token' => null
                    ]);

                    User::where('ios_token', $deleteToken)->update([
                        'ios_token' => null
                    ]);
                }
            }

            $modifyTokens = $downstreamResponse->tokensToModify();

            if (is_array($modifyTokens)) {

                foreach ($modifyTokens as $oldToken => $modifyToken) {
                    User::where('android_token', $oldToken)->update([
                        'android_token' => $modifyToken
                    ]);

                    User::where('ios_token', $oldToken)->update([
                        'ios_token' => $modifyToken
                    ]);
                }
            }
        }

        return;

    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
        $notificationId = $this->notificationId;
        $notification = \App\Models\Notification::find($notificationId);
        if(!$notification)
        {
            return;
        }
        $user = User::find($notification->to_user);
        if(!$user)
        {
            return;
        }
        if (!empty($user->ios_token)) {
            $this->pushNotification($notification->to_user, $notification->title, $notification->id,
                $user->ios_token, $notification->content, $isAndroid = 'no', $notification->payload);
        }

        if (!empty($user->android_token)) {

            $this->pushNotification($notification->to_user, $notification->title, $notification->id,
                $user->android_token, $notification->content, $isAndroid = 'yes', $notification->payload);
        }
    }
}
