<?php

namespace App\Traits;

use App\Models\BusinessSetting;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

trait NotificationTrait
{
    public static function sendPushNotificationToTopic($data, $topic, $type,$web_push_link = null): bool|string
    {
        if(isset($data['module_id'])){
            $module_id = $data['module_id'];
        }else{
            $module_id = '';
        }
        if(isset($data['order_type'])){
            $order_type = $data['order_type'];
        }else{
            $order_type = '';
        }
        if(isset($data['zone_id'])){
            $zone_id = $data['zone_id'];
        }else{
            $zone_id = '';
        }

//        $click_action = "";
//        if($web_push_link){
//            $click_action = ',
//            "click_action": "'.$web_push_link.'"';
//        }

        if (isset($data['order_id'])) {
            $postData = [
                'message' => [
                    "topic" => $topic,
                    "data" => [
                        "title" => (string)$data['title'],
                        "body" => (string)$data['description'],
                        "order_id" => (string)$data['order_id'],
                        "order_type" => (string)$order_type,
                        "type" => (string)$type,
                        "image" => (string)$data['image'],
                        "module_id" => (string)$module_id,
                        "zone_id" => (string)$zone_id,
                        "title_loc_key" => (string)$data['order_id'],
                        "body_loc_key" => (string)$type,
                        "click_action" => $web_push_link?(string)$web_push_link:'',
                        "sound" => "notification.wav",
                    ],
                    "notification" => [
                        "title" => (string)$data['title'],
                        "body" => (string)$data['description'],
                        "image" => (string)$data['image'],
                    ],
                    "android" => [
                        "notification" => [
                            "channelId" => '6ammart',
                        ]
                    ],
                    "apns" => [
                        "payload" => [
                            "aps" => [
                                "sound" => "notification.wav"
                            ]
                        ]
                    ],
                ]
            ];
        } else {
            $postData = [
                'message' => [
                    "topic" => $topic,
                    "data" => [
                        "title" => (string)$data['title'],
                        "body" => (string)$data['description'],
                        "type" => (string)$type,
                        "image" => (string)$data['image'],
                        "body_loc_key" => (string)$type,
                        "click_action" => $web_push_link?(string)$web_push_link:'',
                        "sound" => "notification.wav",
                    ],
                    "notification" => [
                        "title" => (string)$data['title'],
                        "body" => (string)$data['description'],
                        "image" => (string)$data['image'],
                    ],
                    "android" => [
                        "notification" => [
                            "channelId" => '6ammart',
                        ]
                    ],
                    "apns" => [
                        "payload" => [
                            "aps" => [
                                "sound" => "notification.wav"
                            ]
                        ]
                    ],
                ]
            ];
        }
        return self::sendNotificationToHttp($postData);
    }

    public static function sendPushNotificationToDevice($fcm_token, $data, $web_push_link = null): bool|string
    {
        //        if(isset($data['message'])){
//            $message = $data['message'];
//        }else{
//            $message = '';
//        }
        if(isset($data['conversation_id'])){
            $conversation_id = $data['conversation_id'];
        }else{
            $conversation_id = '';
        }
        if(isset($data['sender_type'])){
            $sender_type = $data['sender_type'];
        }else{
            $sender_type = '';
        }
        if(isset($data['module_id'])){
            $module_id = $data['module_id'];
        }else{
            $module_id = '';
        }
        if(isset($data['order_type'])){
            $order_type = $data['order_type'];
        }else{
            $order_type = '';
        }

//        $click_action = "";
//        if($web_push_link){
//            $click_action = ',
//            "click_action": "'.$web_push_link.'"';
//        }
        $postData = [
            'message' => [
                "token" => $fcm_token,
                "data" => [
                    "title" => (string)$data['title'],
                    "body" => (string)$data['description'],
                    "image" => (string)$data['image'],
                    "order_id" => (string)$data['order_id'],
                    "type" => (string)$data['type'],
                    "conversation_id" => (string)$conversation_id,
                    "module_id" => (string)$module_id,
                    "sender_type" => (string)$sender_type,
                    "order_type" => (string)$order_type,
                    "click_action" => $web_push_link?(string)$web_push_link:'',
                    "sound" => "notification.wav",
                ],
                "notification" => [
                    'title' => (string)$data['title'],
                    'body' => (string)$data['description'],
                    "image" => (string)$data['image'],
                ],
                "android" => [
                    "notification" => [
                        "channelId" => '6ammart',
                    ]
                ],
                "apns" => [
                    "payload" => [
                        "aps" => [
                            "sound" => "notification.wav"
                        ]
                    ]
                ]
            ]
        ];

        return self::sendNotificationToHttp($postData);
    }

    public static function sendNotificationToHttp(array|null $data)
    {
        if (empty($data)) {
            return false;
        }

        $config = self::get_business_settings('push_notification_service_file_content');
        $key = is_array($config) ? $config : [];

        foreach (['project_id', 'client_email', 'private_key', 'token_uri'] as $requiredKey) {
            if (empty($key[$requiredKey])) {
                return false;
            }
        }

        $accessToken = self::getAccessToken($key);
        if (!$accessToken) {
            return false;
        }

        $url = 'https://fcm.googleapis.com/v1/projects/'.$key['project_id'].'/messages:send';

        try {
            $response = Http::withToken($accessToken)
                ->acceptJson()
                ->post($url, $data);

            if ($response->successful()) {
                return true;
            }

            Log::warning('FCM notification send failed', [
                'status' => $response->status(),
                'body' => $response->body(),
            ]);

            return $response->body() ?: false;
        } catch (\Exception $exception) {
            Log::warning('FCM notification send exception: ' . $exception->getMessage());
            return false;
        }
    }

    public static function getAccessToken($key)
    {
        foreach (['client_email', 'private_key', 'token_uri'] as $requiredKey) {
            if (empty($key[$requiredKey])) {
                return false;
            }
        }

        $jwtToken = [
            'iss' => $key['client_email'],
            'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
            'aud' => 'https://oauth2.googleapis.com/token',
            'exp' => time() + 3600,
            'iat' => time(),
        ];
        $jwtHeader = self::base64UrlEncode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
        $jwtPayload = self::base64UrlEncode(json_encode($jwtToken));
        $unsignedJwt = $jwtHeader . '.' . $jwtPayload;
        $privateKey = str_replace('\\n', "\n", $key['private_key']);

        if (!openssl_sign($unsignedJwt, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
            return false;
        }

        $jwt = $unsignedJwt . '.' . self::base64UrlEncode($signature);

        try {
            $response = Http::asForm()->post($key['token_uri'], [
                'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                'assertion' => $jwt,
            ]);
        } catch (\Exception $exception) {
            Log::warning('FCM access token request exception: ' . $exception->getMessage());
            return false;
        }

        if (!$response->successful()) {
            Log::warning('FCM access token request failed', [
                'status' => $response->status(),
                'body' => $response->body(),
            ]);

            return false;
        }

        return $response->json('access_token') ?: false;
    }

    private static function base64UrlEncode($data): string
    {
        return rtrim(strtr(base64_encode((string)$data), '+/', '-_'), '=');
    }

    public static function get_business_settings($name)
    {
        $config = null;

        $paymentmethod = BusinessSetting::where('key', $name)->first();

        if ($paymentmethod) {
            $config = json_decode($paymentmethod->value, true);
        }

        return $config;
    }
}
