<?php

use App\Models;
use App\Models\User;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use Tymon\JWTAuth\Facades\JWTAuth;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Log;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

if (!function_exists('jsonResponseWithSuccessMessageApi')) {
    function jsonResponseWithSuccessMessageApi($message, $data = [], $statusCode = 200)
    {
        // Set the HTTP status code
        http_response_code($statusCode);

        // Prepare the response array
        $response = [
            'status' => 'success',
            'status_code' => $statusCode,
            'message' => $message,
            'data' => $data,
        ];
        return response()->json($response, $statusCode);

        // Stop further execution (optional)
        exit();
    }
}


if (!function_exists('jsonResponseWithErrorMessageApi')) {
    function jsonResponseWithErrorMessageApi($errorMessage, $statusCode = 500)
    {
        // Set the HTTP status code
        http_response_code($statusCode);

        // Prepare the response array
        $response = [
            'status' => 'error',
            'status_code' => $statusCode,
            'message' => $errorMessage,
        ];
        return response()->json($response, $statusCode);

        // Stop further execution (optional)
        exit();
    }
}


if (!function_exists('jsonResponseWithDataErrorMessageApi')) {
    function jsonResponseWithDataErrorMessageApi($errorMessage, $data = [], $statusCode = 406)
    {
        // Set the HTTP status code
        http_response_code($statusCode);

        // Prepare the response array
        $response = [
            'status' => 'error',
            'status_code' => $statusCode,
            'message' => $errorMessage,
            'data' => $data,

        ];
        return response()->json($response, $statusCode);

        // Stop further execution (optional)
        exit();
    }
}


if (!function_exists('jsonResponseWithErrorMessage')) {
    function jsonResponseWithErrorMessage($errorMessage, $statusCode)
    {
        $response = [
            'status' => 'error',
            'message' => $errorMessage,
            'status_code' => $statusCode,

        ];
        return response()->json($response);

        // Stop further execution (optional)
        exit();
    }
}


if (!function_exists('jsonResponseWithSuccessMessage')) {
    function jsonResponseWithSuccessMessage($message, $data = [],$type = null)
    {
        $statusCode = 200;
        // Prepare the response array
        $response = [
            'type' => $type,
            'status' => 'success',
            'status_code' => $statusCode,
            'message' => $message,
            'data' => $data,
        ];
        return response()->json($response, $statusCode);

        // Stop further execution (optional)
        exit();
    }
}


if (!function_exists('fullSearchQuery')) {
    function fullSearchQuery($query, $word, $columns)
    {
        $orwords = explode('|', $columns);
        $query = $query->where(function ($query) use ($word, $orwords) {
            foreach ($orwords as $key) {
                $query->orWhere($key, 'like', '%' . $word . '%');
            }
        });
        return $query;
    }
}


if (!function_exists('readHeaderToken')) {
    function readHeaderToken()
    {
        $tokenData = Session::get('vendorToken');
 $token = JWTAuth::setToken($tokenData)->getPayload();

   // dd([
 //     'tokenData' => $tokenData,
 //     'sub' => $token['sub'], // This should be your UUID
  //     'sub_type' => gettype($token['sub']),
  //     'sub_length' => strlen($token['sub']),
 //     'iat' => date('Y-m-d H:i:s', $token['iat']),
 // ]);
        //convert iat to readable format
        $iat = date('Y-m-d H:i:s', $token['iat']);

        // check token issued time for single device login
        // ['last_login_datetime',  $iat]

        $check_iat = User::find((string) $token['sub']);
        // dd($check_iat);
        if ($check_iat) {
            return $token;
        } else {
            return false;
        }
    }
}


if (!function_exists('readRestHeaderToken')) {
    function readRestHeaderToken()
    {
        $tokenData = Session::get('RestToken');
        $token = JWTAuth::setToken($tokenData)->getPayload();

        //convert iat to readable format
        $iat = date('Y-m-d H:i:s', $token['iat']);

        // check token issued time for single device login
        $check_iat = User::where([['id', $token['sub']], ['is_active', '1']])->first();
        if ($check_iat) {
            return $token;
        } else {
            return false;
        }
    }

    if (!function_exists('generateOTP')) {

        function generateOTP()
        {
            // Define the length of the OTP
            $otpLength = 4;

            // Generate a random OTP with $otpLength digits
            $otp = '';
            for ($i = 0; $i < $otpLength; $i++) {
                $otp .= rand(0, 9);
            }
            return $otp;
        }
    }
}

/**
 * Created by : Hritik RD
 * Created at : 12 July 2024
 * Use : To Get Opening hours of Restaurant By NAME based on Google Maps using Google Places APIs
 */

if (!function_exists('getOpeningHoursOfRestaurant')) {
    function getOpeningHoursOfRestaurant($restaurantName)
    {

        $googlePlaceApiKey = config('constants.googlePlaces.api_key'); // Your webhook secret key
        // dd($googlePlaceApiKey);

        $client = new Client();
        $url = 'https://maps.googleapis.com/maps/api/place/findplacefromtext/json';

        $response = $client->get($url, [
            'query' => [
                'fields' => 'place_id',
                'input' => $restaurantName,
                'inputtype' => 'textquery',
                'key' => $googlePlaceApiKey
            ]
        ]);
        $placeData = json_decode($response->getBody(), true);

        if (isset($placeData['candidates'][0]['place_id'])) {
            $placeId = $placeData['candidates'][0]['place_id'];
            // return  $placeId;
        } else {
            $placeId = "N/A";
            // return response()->json($placeId);
            return $placeId;
        }


        // $placeId = 'ChIJT3dpYcy35zsRLxY5KTTMqhU'; // You can also pass this as a parameter if needed
        $client = new Client();
        $url = 'https://maps.googleapis.com/maps/api/place/details/json';

        $response = $client->get($url, [
            'query' => [
                'fields' => 'name,rating,formatted_phone_number,opening_hours',
                'place_id' => $placeId,
                'key' => $googlePlaceApiKey
            ]
        ]);

        $data = json_decode($response->getBody(), true);
        if (isset($data['result']['opening_hours']['weekday_text'])) {
            $hours = $data['result']['opening_hours']['weekday_text'];
            // return response()->json(['place_id' => $placeId]);
        } else {
            $hours = "N/A";
        }
        return  $hours;
        // dd($data);
        // return response()->json($data);

    }

    if (!function_exists('getOperatingHours')) {

        function getOperatingHours($placeName, $address)
        {
            $client = new Client();
            $googlePlaceApiKey = config('constants.googlePlaces.api_key');

            $cacheKey = 'restaurant_hours_' . $placeName;
            $cacheKeyIsRestaurantOpen = 'is_restaurant_open_now_' . $placeName;

            if (Cache::has($cacheKey)) {
                return [
                    'operating_hours' => Cache::get($cacheKey),
                    'is_open_now' => Cache::get($cacheKeyIsRestaurantOpen),
                ];
            }

            try {
                // Get place_id
                $placeResponse = $client->get('https://maps.googleapis.com/maps/api/place/findplacefromtext/json', [
                    'query' => [
                        'fields' => 'place_id',
                        'input' => $placeName . ' ' . $address,
                        'inputtype' => 'textquery',
                        'key' => $googlePlaceApiKey
                    ]
                ]);
                $placeData = json_decode($placeResponse->getBody(), true);

                if (isset($placeData['candidates'][0]['place_id'])) {
                    $placeId = $placeData['candidates'][0]['place_id'];

                    // Get operating hours
                    $detailResponse = $client->get('https://maps.googleapis.com/maps/api/place/details/json', [
                        'query' => [
                            'fields' => 'opening_hours',
                            'place_id' => $placeId,
                            'key' => $googlePlaceApiKey
                        ]
                    ]);
                    $detailData = json_decode($detailResponse->getBody(), true);

                    if (isset($detailData['result']['opening_hours']['weekday_text'])) {
                        $hours = $detailData['result']['opening_hours']['weekday_text'];
                        $isOpenNow = $detailData['result']['opening_hours']['open_now'];

                        Cache::put($cacheKey, $hours, now()->addHours(2));
                        Cache::put($cacheKeyIsRestaurantOpen, $isOpenNow, now()->addHours(2));

                        return [
                            'operating_hours' => $hours,
                            'is_open_now' => $isOpenNow,
                        ];
                    }
                }
            } catch (\Exception $e) {
                Log::error('Restaurant Get service failed : ' . $e->getMessage());
            }

            return [
                'operating_hours' => "N/A",
                'is_open_now' => false,
            ];
        }
    }
}

if (!function_exists('getThingsboardToken')) {
function getThingsboardToken()
{
    if (Cache::has('thingsboard_token')) {
        return Cache::get('thingsboard_token');
    }

    // Get a new token if not available
    $response = Http::post('http://thingsboard-url/api/auth/login', [
        'username' => 'your_username',
        'password' => 'your_password',
    ]);

    if ($response->successful()) {
        $token = $response->json('token');
        Cache::put('thingsboard_token', $token, now()->addMinutes(15));
        return $token;
    } else {
        throw new Exception('Unable to authenticate with ThingsBoard');
    }
}

if (!function_exists('getTokenFromHeader')) {
    /**
     * Function to get the token from the header and validate it.
     *
     * @param  \Illuminate\Http\Request $request
     * @return mixed
     */
    function getTokenFromHeader($request)
    {
        // Extract the token from the Authorization header
        $token = $request->bearerToken();

        if (!$token) {
            return response()->json(['error' => 'Invalid or missing token'], 401);
        }

        // Try to parse the token and return the payload (user information)
        try {
            $payload = JWTAuth::parseToken()->getPayload();  // Get the payload of the token
            return $payload; // Return the payload (you can use this in controllers)
        } catch (TokenExpiredException $e) {
            return response()->json(['error' => 'Token expired'], 401);
        } catch (TokenInvalidException $e) {
            return response()->json(['error' => 'Token invalid'], 401);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to authenticate token'], 401);
        }
    }
}
}

if (!function_exists('parameters')) {
function parameters()
{

    $keys = [
         // 1. Gas Engine
        "4e989080-04ad-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'PowerLoss_value,ChannelSpeed',
            "keyNameList2" => 'MechanicalHealth_valueInHealth,ChannelSpeed',
        ],
        // 2. 2 Stroke Engine
        "88986090-16b3-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'PowerLoss_value,ChannelSpeed',
            "keyNameList2" => 'MechanicalHealth_valueInHealth,ChannelSpeed',
        ],
        // 3. Engine
        "a7802800-f34d-11ef-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'PowerLoss_value,ChannelSpeed',
            "keyNameList2" => 'MechanicalHealth_valueInHealth,ChannelSpeed',
        ],
        // 4. Bearing
        "b82d42a0-f34d-11ef-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'GlobalLevel_value,ChannelSpeed',
            "keyNameList2" => 'BearingGlobal_valueInPercent,GlobalKurto_valueInPercent,ChannelSpeed',
        ],
        // 5. Gearbox
        "b60d08f0-16b3-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'GlobalLevel_value,ChannelSpeed',
            "keyNameList2" => 'BearingGlobal_valueInPercent,GlobalKurto_valueInPercent,ChannelSpeed',
        ],
        // 6. Turbine
        "b13497a0-f34d-11ef-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'RegularityDeviation_valueInPercent,BladeStatus_valueInPercent,ChannelSpeed',
            "keyNameList2" => 'BearingStatus_valueInPercent,TurbineCoupling_valueInPercent,ChannelSpeed',
        ],
        // 7. Gas Turbine
        "72907b10-04ad-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'RegularityDeviation_valueInPercent,BladeStatus_valueInPercent,ChannelSpeed',
            "keyNameList2" => 'BearingStatus_valueInPercent,TurbineCoupling_valueInPercent,ChannelSpeed',
        ],
        // 8. Torque
        "bfbd2490-f34d-11ef-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'StaticTorque_value,ChannelSpeed',
            "keyNameList2" => 'StaticPower_value,ChannelSpeed',
        ],
        // 9. Oil
        "bfd52480-15eb-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'OT',
            "keyNameList2" => 'TDN',
        ],
        // 10. Propeller
        "6543c980-04ad-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'PropellerEfficiency_value,ChannelSpeed',
            "keyNameList2" => 'PropellerBearing_valueInPercent,PropellerUnbalance_valueInPercent,ChannelSpeed',
        ],
        // 11. Motor
        "6c686680-04ad-11f0-a9dc-45dd276e4cd5" => [
            "keyNameList1" => 'MElectromag_valueInPercent,ChannelSpeed',
            "keyNameList2" => 'MStressStability_valueInPercent,MBearing_valueInPercent,ChannelSpeed',
        ]
    ];

    return $keys;

}
}
