<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Input;

class FCMNotification{

    private $request;
    private $requestData;
    private $key = 'AIzaSyCgCL9NFhR7dZvFC9nZt_QoIvTjiAs5nd0';
    private $webNotification = 'AAAAx5S2u4Y:APA91bGxmHbI6fJe6lGtp6l9Iy46GcfRWebN2vtC1ytMBj-oGwbnOXqAdJabteuT08rBJC4JFLgv6tNN2On6ovajbiKYZXhE2oLRzPYgaHh6S-G3-tjF0x2_WwXXvz7X4kMvd907cs5R';
    private $consumer_key = 'AAAAHbKp3rM:APA91bGfT16YyNNrdd-Z9O4JE-j7yzp1U5DQBZrQtwnENgefppNVeSaI6_2_CLWXWvu66PtVqOfnsGUuCXKQNRPxaoOHDG7GtrgfR30sWkBw5oFQENDlpm3-m2QTjEz1PYA6ZCRpQJBS';
    private $endPoint = 'https://fcm.googleapis.com/fcm/send';
    private $tokens = [];

    public function __construct(Request $request){
        $this->request = $request;
        $this->sendNotification();
    }

    public function sendNotification(){
        $this->requestData = [
            'registration_ids' => $this->getNotification(),
	        'data' => array(
                'title' => $this->request->get('title'),
		        'body' => $this->request->get('body'),
		        'deep_link' => $this->request->get('deeplink'),
                'date' => date('d M Y g:i A', Carbon::now()->timestamp),
                'image' => $this->request->get('image'),
                'payload' => $this->request->has('fcm_payload') ? $this->request->get('fcm_payload') : []
            )
	    ];
        if($this->tokens) {
            $response = $this->send();
            $this->updateTokens($response);
            $this->setResponse($response);
        }
    }

    public function send(){
        $data = json_encode($this->requestData);

        if($this->request->has('customer-app') && $this->request->get('customer-app') || $this->request->get('type') == 'user'){
            $this->key = $this->consumer_key;
        }else if($this->request->get('type') == 'admin_user'){
            $this->key = $this->webNotification;
        }

        $headers = array(
            'Content-Type:application/json',
            'Authorization:key='.$this->key
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->endPoint);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $result = curl_exec($ch);
        if ($result === FALSE) {
            $response = curl_error($ch);
        }else{
            $response = $result;
        }
        curl_close($ch);
        return json_decode($response, true);
    }

    public function getNotification(){
        $tokens = [];
        if($this->request->get('type') == 'merchant'){
            $merchants = Merchant::with('users.tokens')->where('id',$this->request->get('id'))->get();
            if(isset($merchants[0]->users)) {
                foreach ($merchants as $static) {
                    if(isset($static->users)) {
                        foreach ($static->users as $user){
                            if ($user->tokens) {
                                foreach ($user->tokens as $token) {
                                    if (isset($token->fcm_id) && !in_array($token->fcm_id, $tokens)) {
                                        $tokens[] = $token->fcm_id;
                                    }
                                }
                            }
                        }
                    }
            }
            }
        }else if($this->request->get('type') == 'admin_user' || $this->request->get('type') == 'user' || $this->request->get('type') == 'merchant_user'){
            if($this->request->has('device_id')){
                User::setDeviceId($this->request->get('device_id'));
            }
            $user = User::with('tokens')->where('id',$this->request->get('id'))->first();
            if ($user && isset($user->tokens)) {
                foreach ($user->tokens as $token) {
                    if (isset($token->fcm_id) && !in_array($token->fcm_id, $tokens)) {
                        $tokens[] = $token->fcm_id;
                    }
                }
            }
        }
        $this->tokens = $tokens;
        return $tokens;
    }

    public function updateTokens($data){
        $tokenUpdate = [];
        if(isset($data['results'])){
            foreach ($data['results'] as $key=>$result){
                if(!isset($result['message_id']) && isset($this->tokens[$key])){
                    $tokenUpdate[] = $this->tokens[$key];
                }
            }
        }

        if($tokenUpdate){
            GCMRegistraion::whereIn('fcm_id', $tokenUpdate)->update(['status'=>'Inactive']);
        }
    }

    public function setResponse($response){
        $request = $this->request->all();
        $request['tokens'] = $this->tokens;
        $data = array(
            'request' => json_encode($request),
            '_id' => $this->request->has('application_id') && $this->request->get('application_id') ? $this->request->get('application_id') : $this->request->get('id'),
            'notification_type' => $this->request->get('notification_type'),
            'id_type' => $this->request->has('application_id') ? 'application_id' : (($this->request->has('type') && in_array($this->request->get('type'), ['user', 'admin_user'])) ? 'user_id' : 'merchant_id'),
            'response' => json_encode($response),
            'multicast_id' => (isset($response['multicast_id'])) ? $response['multicast_id'] : '',
            'canonical_ids' => (isset($response['canonical_ids'])) ? $response['canonical_ids'] : '',
            'success' => (isset($response['success'])) ? $response['success'] : 0,
            'failure' => (isset($response['failure'])) ? $response['failure'] : 0,
            'created_at' => Carbon::now()->toDateTimeString(),
            'created_by' => (Auth::user()) ? Auth::user()->id : (Input::has('auth_user_id') ? Input::get('auth_user_id') : 107)
        );

        FCMResponse::insert($data);
    }
}
