<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Google\Auth\Credentials\ServiceAccountCredentials;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Promise\PromiseInterface;

class Sendpush extends Model
{
    use HasFactory;

    function getAccessToken()
    {
        // $credentialsPath = ('public/assets/json/service-account-file.json');
        $credentialsPath = base_path('public/assets/json/api-project-2-94007-firebase-adminsdk-w5lhz-25d5ac9a4e.json');
        $credentials = new ServiceAccountCredentials(
            'https://www.googleapis.com/auth/firebase.messaging',
            $credentialsPath
        );
        $token = $credentials->fetchAuthToken();
        return $token['access_token'];
    }

    function sendPushAndroid($user_id, $device_token, $message)
    {
    
        // Single
        $SERVER_API_KEY = $this->getAccessToken();
        $path_to_firebase_cm = 'https://fcm.googleapis.com/v1/projects/api-project-2-94007/messages:send';
        $jsonMessage = json_encode($message);
        $push_message = $message['message'];
        $fields = array(
            'message' => array(
                'token' => $device_token,
                'notification' => array(
                    'title' => $message['title'],
                    'body' => $push_message,
                ),
                'data' => array('message' => $jsonMessage),
            ),
            'validate_only' => false,
        );
        $headers = array(
            'Authorization: Bearer ' . $SERVER_API_KEY,
            'Content-Type:application/json'
        );
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $path_to_firebase_cm);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        //	curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

        $result = curl_exec($ch);

        curl_close($ch);

        return $result;
    }

    function sendAndriodNotification($tokens, $message)
    {
        $client = new Client();
        $deviceTokens = $tokens;
        $messages = [];

        foreach ($deviceTokens as $token) {
            $messages[] = [
                'token' => $token,
                'notification' => [
                    'title' => $message['title'],
                    'body' => $message['message'],

                ],
            ];
        }

        $promises = function () use ($client, $messages) {
            foreach ($messages as $message) {
                $SERVER_API_KEY = $this->getAccessToken();
                yield $client->requestAsync('POST', 'https://fcm.googleapis.com/v1/projects/api-project-2-94007/messages:send', [
                    'json' => ['message' => $message],
                    'headers' => [
                        'Authorization' => 'Bearer ' . $SERVER_API_KEY,
                        'Content-Type' => 'application/json',
                    ],
                ]);
            }
        };

        $handleResponses = function (array $responses) {
            $results = [];

            foreach ($responses as $response) {
                if ($response['state'] === PromiseInterface::FULFILLED) {
                    $body = $response['value']->getBody()->getContents();
                    $statusCode = $response['value']->getStatusCode();

                    $results[] = [
                        'status_code' => $statusCode,
                        'body' => $body,
                    ];
                } elseif ($response['state'] === PromiseInterface::REJECTED) {
                    $results[] = [
                        'error_message' => $response['reason']->getMessage(),
                    ];
                }
            }
        };

        Promise\Utils::settle($promises())
            ->then($handleResponses)
            ->wait();

        return true;
    }


    //send push for ios
    function sendPushIOS($device_token, $message, $title)
    {
        // Single
        $SERVER_API_KEY = $this->getAccessToken();
        $path_to_firebase_cm = 'https://fcm.googleapis.com/v1/projects/api-project-2-94007/messages:send';
        $jsonMessage = json_encode($message);
        $push_message = $message['message'];

        $fields = array(
            'message' => array(
                'token' => $device_token,
                'notification' => array(
                    'title' => $title,
                    'body' => $push_message
                ),
                'data' => array('message' => $jsonMessage),
                'apns' => array(
                    'payload' => array(
                        'aps' => array(
                            'alert' => array(
                                'title' => $title,
                                'body' => $push_message
                            ),
                            'sound' => 'default'
                        )
                    )
                ),
            ),
            'validate_only' => false,
        );


        $headers = array(
            'Authorization: Bearer ' . $SERVER_API_KEY,
            'Content-Type:application/json'
        );
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $path_to_firebase_cm);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        //	curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

        $result = curl_exec($ch);

        curl_close($ch);

        return $result;
    }

    function sendIOSNotification($deviceTokens, $message, $title)
    {
        $client = new Client();
        $SERVER_API_KEY = $this->getAccessToken();
        $path_to_firebase_cm = 'https://fcm.googleapis.com/v1/projects/api-project-2-94007/messages:send';

        // Prepare the message payload
        $prepareMessage = function ($device_token, $message, $title) {
            return [
                'token' => $device_token,
                'notification' => [
                    'title' => $title,
                    'body' => $message['message'],
                ],
                'data' => [
                    'message' => json_encode($message),
                ],
                'apns' => [
                    'payload' => [
                        'aps' => [
                            'alert' => [
                                'title' => $message['title'],
                                'body' => $message['message'],
                            ],
                            'sound' => 'default', // Specify sound here for iOS
                        ],
                    ],
                ],
            ];
        };

        // Create request promises
        $promises = array_map(function ($deviceToken) use ($client, $path_to_firebase_cm, $SERVER_API_KEY, $prepareMessage, $message, $title) {
            return $client->requestAsync('POST', $path_to_firebase_cm, [
                'json' => [
                    'message' => $prepareMessage($deviceToken, $message, $title),
                ],
                'headers' => [
                    'Authorization' => 'Bearer ' . $SERVER_API_KEY,
                    'Content-Type' => 'application/json',
                ],
            ]);
        }, $deviceTokens);

        // Handle responses
        $handleResponses = function (array $responses) {
            foreach ($responses as $response) {
                if ($response['state'] === PromiseInterface::FULFILLED) {
                    $body = $response['value']->getBody()->getContents();
                    $statusCode = $response['value']->getStatusCode();
                } elseif ($response['state'] === PromiseInterface::REJECTED) {                   
                }
            }
        };

        // Execute the promises
        Promise\Utils::settle($promises)
            ->then($handleResponses)
            ->wait();
        return true;
    }
}
