<?php

namespace App\Jobs;

use App\User;
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Pusher\Pusher;
use App\Components\Functions;
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;

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

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

    public function onConnection($connection)
    {
        $this->connection = 'redis';
        return $this;
    }

    public function onQueue($connection)
    {
        $this->queue = 'low';
        return $this;
    }

    public function pushNotificationBrowser( $accountId, $content, $notificationId = null ) {
        $account = User::find( $accountId );
        if ( $account ) {
            if ( ! empty( $account->webpush_token ) ) {
                $tokens = json_decode( $account->webpush_token, true );
                if ( is_array( $tokens ) ) {
                    $endpoint = $tokens['endpoint'];
                    $key      = $tokens['key'];
                    $token    = $tokens['token'];

                    $data         = [
                        'title' => 'Thông báo từ itro.vn',
                        'body'  => $content,
                        'icon'  => 'https://itro.vn/frontend3/assets/img/logo.png'
                    ];
                    $notification =
                        [
                            'subscription' => Subscription::create( [
                                'endpoint'        => $endpoint,
                                'publicKey'       => $key, // base 64 encoded, should be 88 chars
                                'authToken'       => $token, // base 64 encoded, should be 24 chars
                                'contentEncoding' => 'aesgcm'
                            ] ),
                            'payload'      => json_encode( $data ),
                        ];

                    $auth = array(
                        'VAPID' => array(
                            'subject'    => 'https://itro.vn',
                            'publicKey'  => config( 'constants.VAPID_PUBLIC_KEY' ),
                            'privateKey' => config( 'constants.VAPID_SECRET_KEY' ),
                            // in the real world, this would be in a secret file
                        ),
                    );

                    $webPush = new WebPush( $auth );


                    $webPush->sendNotification(
                        $notification['subscription'],
                        $notification['payload'], // optional (defaults null)
                        true
                    );

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

    public function pushNotification( $accountId, $title, $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 );
        }


        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 ) ) {

            $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;

    }

    public function __construct( $userId, $message ) {
        //
        $this->userId  = $userId;
        $this->message = $message;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle() {
        //

        $pusher = \PusherService::getClient();
        $channelName   = 'presence-online-status';
        $usersChannel  = $pusher->get( '/channels/' . $channelName . '/users' );

        $userOnlineArr = [];
        if ( isset( $usersChannel['result'] ) ) {
            if ( isset( $usersChannel['result']['users'] ) ) {
                foreach ( $usersChannel['result']['users'] as $item ) {
                    $userIdOnline    = $item['id'];
                    $userOnlineArr[] = $userIdOnline;
                }
            }
        }


	    $message = $this->message;

	    $channelConversationName   = 'presence-read-conversation-'.$message['conversation_id'];
	    $usersChannelConversation  = $pusher->get( '/channels/' . $channelConversationName . '/users' );
	    $userOnlineConversationArr = [];
	    if ( isset( $usersChannelConversation['result'] ) ) {
		    if ( isset( $usersChannelConversation['result']['users'] ) ) {
			    foreach ( $usersChannelConversation['result']['users'] as $item2 ) {
				    $userIdOnlineConversation    = $item2['id'];
				    $userOnlineConversationArr[] = $userIdOnlineConversation;
			    }
		    }
	    }



        $userId = $this->userId;

        if ( ! in_array( $userId, $userOnlineArr ) ) {

        	if(!in_array($userId, $userOnlineConversationArr)) {

		        $user = User::find( $userId );

		        $title   = 'Bạn có tin nhắn mới';
		        $content = strip_tags($message['content']);
		        $payload = json_encode( [
			        'id'   => $message['conversation_id'],
			        'type' => config( 'constants.MESSAGE' )
		        ] );

		        if ( ! empty( $user->android_token ) ) {
			        $this->pushNotification( $userId, $title, $user->android_token, $content, 'yes', $payload );
		        }

		        if ( ! empty( $user->ios_token ) ) {
			        $this->pushNotification( $userId, $title, $user->ios_token, $content, 'no', $payload );
		        }

		        $this->pushNotificationBrowser( $userId, $content );
	        }
        }

    }
}