<?php

use App\Models\CryptoTransaction;
use App\Models\DataPlan;
use App\Models\ReferBonus;
use App\Models\UsdtAddress;
use App\Models\User;
use App\Models\VirtualAccounts;
use App\Models\VirtualCard;
use Carbon\Carbon;
use App\Models\Charge;
use Illuminate\Support\Facades\DB;
use PrevailExcel\Nowpayments\Facades\Nowpayments;
//use Twilio\Rest\Client;
use App\Models\Currency;
use Illuminate\Support\Str;
use App\Models\EmailTemplate;
use App\Models\Generalsetting;
use App\Models\PaymentGateway;
use App\Models\SmsGateway;
use Illuminate\Support\Facades\Http;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use Illuminate\Support\Facades\Session;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

function getPhoto($filename)
{
    if($filename){
        if(file_exists('assets/images'.'/'.$filename)) return asset('assets/images/'.$filename);
        else return asset('assets/images/default.png');
    } else{
        return asset('assets/images/default.png');
    }
}
function getProductPicture($filename)
{
    if($filename){
        if(file_exists('assets/images'.'/products/'.$filename)) return asset('assets/images/products/'.$filename);
        else return asset('assets/images/default.png');
    } else{
        return asset('assets/images/default.png');
    }
}

function sysVersion()
{
    return '2.2';
}


function admin()
{
    return auth()->guard('admin')->user();
}
function merchant()
{
    return auth()->guard('merchant')->user();
}
function agent()
{
    return auth()->guard('agent')->user();
}

function user(){
    if(auth()->check()){
        $user = auth()->user();
        $type = 1;
    }

    if(auth()->guard('merchant')->check()){
        $user = auth()->guard('merchant')->user();
        $type = 2;
    }

    return json_decode(json_encode(['user'=>$user,'type'=>$type]));
}

function menu($route)
{
    if(is_array($route)) {
        foreach ($route as $value) {
            if (request()->routeIs($value)) {
                return 'active';
            }
        }
    } elseif (request()->routeIs($route)) {
        return 'active';
    }
}


function tagFormat($tag)
{
    $common_rep   = ["value", "{", "}", "[","]",":","\""];
    $tag = str_replace($common_rep, '', $tag);
    if (!empty($tag))  return $tag;
    else  return  null;
}

function numFormat($amount, $length = 0)
{
    if(0 < $length)return number_format( $amount + 0, $length);
    return $amount + 0;
}

function amount($amount,$type = 1,$length = 0){
    if($type == 2) return numFormat($amount,8);
    else return numFormat($amount,$length);
}

function charge($slug)
{
    $charge = Charge::where('slug',$slug)->first();
    return $charge->data;
}

function chargeCalc($charge,$amount,$rate = 1)
{
    return  ($charge->fixed_charge * $rate) + ($amount * ($charge->percent_charge/100));
}

function dateFormat($date,$format = 'd M Y -- h:i a'){
    return Carbon::parse($date)->format($format);
}

function randNum($digits = 6){
    return rand(pow(10, $digits-1), pow(10, $digits)-1);
}

function str_rand($length = 12,$up = false)
{
    if($up) return Str::random($length);
    else return strtoupper(Str::random($length));
}


function getCurrency(){
    if(Session::has('currency')){
        $currency = Currency::findOrFail(Session::get('currency'));
    }else{
        $currency = Currency::whereIsDefault(1)->first();
    }
    return json_encode($currency->toArray());
}


// Payment Gateway Keyword Calculation 0
function getCallback($id)
{
    return PaymentGateway::findOrFail($id)->keyword;
}



function email($data){
    $gs = Generalsetting::first();

    // if ($gs->email_notify) {
    if ($gs->mail_type == 'php_mail') {
        $headers = "From: $gs->sitename <$gs->email_from> \r\n";
        $headers .= "Reply-To: $gs->sitename <$gs->email_from> \r\n";
        $headers .= "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: text/html; charset=utf-8\r\n";
        @mail($data['email'], $data['subject'], $data['message'], $headers);
    }
    else {
        $mail = new PHPMailer(true);

        try {

            $gs = Generalsetting::first();

            // SMTP configuration
            $mail->isSMTP();
            $mail->Host       = env('MAIL_HOST');// 'smtp.hostinger.com';
            $mail->SMTPAuth   = true;
            $mail->Username   = env('MAIL_USERNAME');//'info@refer2trade.com';
            $mail->Password   = env('MAIL_PASSWORD');//'Pipopay_2019#';
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
            $mail->Port       = 465;

            // Email content
            $mail->CharSet = 'UTF-8';
            $mail->setFrom($gs->from_email, $gs->from_name);
            $mail->addAddress($data['email'], $data['name']);
            $mail->addReplyTo($gs->from_email, $gs->from_name);
            $mail->isHTML(true);

            $mail->isHTML(true); // Ensure the email is sent as HTML
            $mail->Subject = $data['subject'];

// Add the logo and email body content
            $mail->Body = '
    <div style="text-align: center; margin-bottom: 20px;">
        <img src="'.asset('assets/frontend/images/').'/logo.png" alt="Company Logo" style="max-width: 150px; height: auto;">
    </div>
    <hr style="border: 1px solid #ccc; margin: 20px 0;">
    <div style="font-family: Arial, sans-serif; font-size: 14px; color: #333;">
        ' . nl2br($data['message']) . '
    </div>
    <hr style="border: 1px solid #ccc; margin: 20px 0;">
';
           // $mail->Subject = $data['subject'];
           // $mail->Body    = $data['message'];
            $mail->send();
            // $mail->isSMTP();
            /* $mail->Host       = $gs->smtp_host;
             $mail->SMTPAuth   = true;
             $mail->Username   = $gs->smtp_user;
             $mail->Password   = $gs->smtp_pass;
             if ($gs->mail_encryption == 'ssl') {
                 $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
             } else {
                 $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
             }
             $mail->Port       = $gs->smtp_port;
             $mail->CharSet = 'UTF-8';
             $mail->setFrom($gs->from_email, $gs->from_name);
             $mail->addAddress($data['email'], $data['name']);
             $mail->addReplyTo($gs->from_email, $gs->from_name);
             $mail->isHTML(true);
             $mail->Subject = $data['subject'];
             $mail->Body    = $data['message'];
             $mail->send();
             */
        } catch (Exception $e) {
            throw new Exception($e);
        }
    }
    // }
}


function mailSend($key, array $data, $user)
{

    $gs = GeneralSetting::first();
    $template =  EmailTemplate::where('email_type', $key)->first();

    if($gs->email_notify){
        $message = str_replace('{name}', $user->name, $template->email_body);

        foreach ($data as $key => $value) {
            $message = str_replace("{" . $key . "}", $value, $message);
        }

        if ($gs->mail_type == 'php_mail') {
            $headers = "From: $gs->sitename <$gs->email_from> \r\n";
            $headers .= "Reply-To: $gs->sitename <$gs->email_from> \r\n";
            $headers .= "MIME-Version: 1.0\r\n";
            $headers .= "Content-Type: text/html; charset=utf-8\r\n";
            @mail($user->email, $template->email_subject, $message, $headers);
        } else {
            $mail = new PHPMailer(true);

            try {
                // $mail->isSMTP();
                $mail->Host       = $gs->smtp_host;
                $mail->SMTPAuth   = true;
                $mail->Username   = $gs->smtp_user;
                $mail->Password   = $gs->smtp_pass;
                if ($gs->mail_encryption == 'ssl') {
                    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
                } else {
                    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                }
                $mail->Port       = $gs->smtp_port;
                $mail->CharSet = 'UTF-8';
                $mail->setFrom($gs->from_email, $gs->from_name);
                $mail->addAddress($user->email, $user->name);
                $mail->addReplyTo($gs->from_email, $gs->from_name);
                $mail->isHTML(true);
                $mail->Subject = $template->email_subject;
                $mail->Body    = $message;
                $mail->send();
            } catch (Exception $e) {
                // throw new Exception($e);
            }
        }
    }

    if($gs->sms_notify){
        $message = str_replace('{name}', $user->name, $template->sms);
        foreach ($data as $key => $value) {
            $message = str_replace("{" . $key . "}", $value, $message);
        }
        sendSMS($user->phone,$message,$gs->contact_no);
    }

}

function sendSMS($recipient,$message,$from){
    $sg = SmsGateway::where('status',1)->first();
    try {
        if($sg->name == 'Nexmo')       nexmo($recipient,$message,$from,$sg->config);
        else if($sg->name == 'Twilio') twilio($recipient,$message,$sg->config);
    } catch (\Throwable $th) {

    }

}

function twilio($recipient,$message,$config){
    $sid = $config->sid;
    $token = $config->token;
    $from_number = $config->from_number;

    $client = new Client($sid, $token);
    $client->messages->create(
        '+'.$recipient,
        array(
            'from' => $from_number,
            'body' => $message
        )
    );
}

function nexmo(string $recipient,$message,$from,$config){
    $basic  = new \Vonage\Client\Credentials\Basic($config->api_key, $config->api_secret);
    $client = new \Vonage\Client($basic);
    $client->sms()->send(
        new \Vonage\SMS\Message\SMS($recipient, $from, $message)
    );

}


function access($permission){
    return admin()->can($permission);
}


//gateway helpers

function storePrice($amount){

    $curr = Session::has('currency') ? Session::get('currency') : Currency::whereDefault(1)->first();
    return $amount;
}

function setCurrencyPrice($amount){
    $curr = Session::has('currency') ? Currency::findOrFail(Session::get('currency')) : Currency::whereDefault(1)->first();
    return $curr->symbol . round($amount * $curr->rate , 2);
}

function getCurrencyCode(){
    $curr = Session::has('currency') ? Session::get('currency') : Currency::whereDefault(1)->first();
    return $curr->code;
}

function sessionCurrency(){
    $curr = Session::has('currency') ? Session::get('currency') : Currency::whereDefault(1)->first();
    return json_encode($curr);
}

function loginIp(){
    $info = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$_SERVER['REMOTE_ADDR']));
    return json_decode(json_encode($info));
}

function filter($key, $value)
{
    $queries = request()->query();
    if(count($queries) > 0) $delimeter = '&';
    else  $delimeter = '?';

    if(request()->has($key)){
        $url = request()->getRequestUri();
        $pattern = "\?$key";
        $match = preg_match("/$pattern/",$url);
        if($match != 0) return  preg_replace('~(\?|&)'.$key.'[^&]*~', "\?$key=$value", $url);
        $filteredURL = preg_replace('~(\?|&)'.$key.'[^&]*~', '', $url);
        return  $filteredURL.$delimeter."$key=$value";
    }
    return  request()->getRequestUri().$delimeter."$key=$value";


}

function generateQR($data)
{
    return "https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=$data&choe=UTF-8";
}

function diffTime($time)
{
    return Carbon::parse($time)->diffForHumans();
}

function amountConv($amount,$currency){
    if($currency->rate>0)
        return amount($amount/$currency->rate,$currency->type,2);
    return 0;
}

function defaultCurr(){
    return Currency::where('default',1)->first();
}


function getAlias($word){
    // Split the word into an array of words
    $words = explode(" ", $word);

// Initialize an empty array to store the first letters
    $firstLetters = [];

// Loop through each word and extract the first letter
    foreach ($words as $word) {
        $firstLetters[] = substr($word, 0, 1);
    }

// Convert the array of first letters to a string
    $result = implode("", $firstLetters);

    return $result;  // Output: HW
}


function activeMenu($route)
{
    if(is_array($route)){
        if(in_array(url()->current(),$route)){
            return 'active';
        }
    }
    if($route == url()->current()){
        return 'active';
    }
}

function toMoney($amount){
    return '₦'.number_format($amount, 2);
}

function getAllBank(){
    return DB::table('banks')->get();

}

function getBankName($bank){
    return DB::table('banks')->where('bank_code',$bank)->first('bank_name')->bank_name;
}


function getStateName($stateId){
    return DB::table('states')->where('id',$stateId)->first('name')->name;
}

function getBeneficiaryByUser($user_id, $bid){
    return DB::table('beneficiaries')->where('user_id',$user_id)->where('id',$bid)->first();

}

function getEstimated($amount, $coin){
    $client = new \GuzzleHttp\Client();

// Validate and sanitize user input before using it
    $coin = trim(strtoupper($coin)); // Assuming coin comes from a GET parameter

    $url = sprintf('https://api.binance.us/api/v3/ticker/price?symbol=%sUSDT', $coin);

    try {
        $response = $client->get($url);
        // print_r($response);
    } catch (Exception $e) {
        // Handle the error gracefully, e.g., log the error and provide a user-friendly message
        echo "An error occurred while fetching data: " . $e->getMessage();
        exit;
    }

// Assuming the response is successful, decode the JSON and check for errors
    $data = json_decode($response->getBody(), true);

    if (isset($data['error'])) {
        // Handle API error
        return ["type"=>'error','message'=>$data['error']['message']];
        exit;
    } else {
        // Process the price data from $data
        $rate = (1 / (floatval($data['price'])) * $amount);
        return  ['type'=>'success','price'=>$rate];
        //echo "The current price of " . $coin . " is " . $data['price'];
    }

// new \GuzzleHttp\Client->Http::get(https://api.binance.us/api/v3/ticker/price?symbol=);
    // $crypto_rate_usd = json_decode(bxc_curl('https://api.binance.us/api/v3/ticker/price?symbol=' . $coin . 'USD'), true)['price'];

    /*$data =
        "amount=" . $amount . "&" .
        "currency_from=" . "usd" . "&" .
        "currency_to=" . $coin;
    $rate = Nowpayments::getEstimatePrice($data);
    //$paymentDetails= NowPayments::getCurrencies();*/
//return  $rate;

}
function satToBtc($satoshi) {
    // Define the conversion factor (1 BTC = 100,000,000 satoshi)
    $conversionFactor = 100000000;

    // Perform division and return the result
    return $satoshi / $conversionFactor;
}


function confirmBtcTransaction($address){
    //  $address = "1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp"; // Replace with your actual Bitcoin address


    //mempool
    $url = 'https://mempool.space/api/address/'.$address.'/txs/chain';

// Initialize cURL
    $ch = curl_init($url);

// Set cURL options
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Capture response instead of printing it
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Skip SSL certificate verification (not recommended for production)
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Skip SSL hostname verification (not recommended for production)

// Execute the cURL request
    $response = curl_exec($ch);
//dd($response);
// Check for errors
    if (curl_errno($ch)) {
        echo 'Error: ' . curl_error($ch);
        exit;
    }

// Close the cURL resource
    curl_close($ch);

// Decode the JSON response
    $data = json_decode($response, true);


    $total_in = 0;
    $total_out = 0;
    //dd($data);
    if(!(isset($data[0]))){
        return  ['status'=>'error','confirmed'=>false];
    }
    $transaction= $data[0];
// Calculate total amount received (in)
    foreach ($transaction['vout'] as $output) {
        $total_in += $output['value'];
    }

// Calculate total amount sent (out)
    foreach ($transaction['vin'] as $input) {
        $total_out += $input['prevout']['value'];
    }

    return ['status'=>'success','confirmed'=>true, 'vin'=>satToBtc($total_in), 'vout'=>satToBtc($total_out),
        'fee'=>satToBtc($transaction['fee']), 'txid'=>$transaction['txid']];
    // echo "Total amount received (in): " . $total_in . " Satoshi\n";
    // echo "Total amount sent (out): " . $total_out . " Satoshi\n";
}

function btctoUsdBinance($amount){
    $client = new \GuzzleHttp\Client();

// Validate and sanitize user input before using it
    $coin = 'USDT'; // Assuming coin comes from a GET parameter

    $url = sprintf('https://api.binance.us/api/v3/ticker/price?symbol=%sBTC', $coin);

    try {
        $response = $client->get($url);
        // print_r($response);
    } catch (Exception $e) {
        // Handle the error gracefully, e.g., log the error and provide a user-friendly message
        echo "An error occurred while fetching data: " . $e->getMessage();
        exit;
    }

// Assuming the response is successful, decode the JSON and check for errors
    $data = json_decode($response->getBody(), true);

    if (isset($data['error'])) {
        // Handle API error
        return ["type"=>'error','message'=>$data['error']['message']];
        exit;
    } else {
        // Process the price data from $data
        $rate = (1 / (floatval($data['price'])) * $amount);
        return  ['type'=>'success','price'=>$rate];
        //echo "The current price of " . $coin . " is " . $data['price'];
    }



}

function confirmBalancebk($address){
    //  $address = "1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp"; // Replace with your actual Bitcoin address
    $apiKey = "hihv7pldoxmdsrTN84JESyrnCPe7k8SALKRqEc4o2Ho"; // Replace with your Blockonomics API key

    // $addresses ="1DyDvLSenrGC2ZfiLWknBMQA5xMare1ST1"; // Replace with your actual Bitcoin addresses (whitespace separated)
    // $apiKey = "YOUR_API_KEY_HERE"; // Replace with your Blockonomics API key

// Initialize a cURL handle
    $ch = curl_init("https://www.blockonomics.co/api/balance");

// Set cURL options
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Capture response instead of printing it
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Skip SSL certificate verification (not recommended for production)
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Skip SSL hostname verification (not recommended for production)

// Set request method to POST
    curl_setopt($ch, CURLOPT_POST, true);

// Prepare the request body
    $requestBody = json_encode(['addr' =>  $address]); // Implode to create the whitespace-separated list

// Set the request body with proper content type
    curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));

// Set the Authorization header
    $headers = array('Authorization: Bearer ' . $apiKey);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

// Execute the cURL request
    $response = curl_exec($ch);
//dd($response);
// Check for errors
    if (curl_errno($ch)) {
        echo 'Error: ' . curl_error($ch);
        exit;
    }

// Close the cURL handle
    curl_close($ch);

// Decode the JSON response
    $data = json_decode($response, true);
    //dd($data['response'][0]['confirmed']);
    $confirmAmt =$data['response'][0]['confirmed'];
// Process the response data (refer to Blockonomics API documentation)
    if ($confirmAmt>0) {
        //  dd($data[0]['confirmed']);
        return ['amount'=>satToBtc($confirmAmt)];
    } else {
        echo "Failed to retrieve balances.";
    }

}


function toPhoneNumber($phoneNumber)
{
    if (preg_match('/^(\\+?234|0)?[789]\\d{9}$/', $phoneNumber)) {
        // Remove any leading zeros from the phone number
        $phoneNumber = ltrim($phoneNumber, '0');

        // Check if the phone number already has the country code
        if (substr($phoneNumber, 0, 4) == '+234') {
            return $phoneNumber;
        } else {
            // Add the country code to the beginning of the phone number
            $phoneNumber = '+234' . $phoneNumber;

            return $phoneNumber;
        }
    } else {
        return null;
    }

}

function convertDataPhone($phoneNumber)
{
    // Remove any non-digit characters from the phone number
    $phoneNumber = preg_replace('/\D/', '', $phoneNumber);

    // Check if the phone number is valid
    if (preg_match('/^(\+?234|0)?[789]\d{9}$/', $phoneNumber)) {
        // Remove '234' or '+234' from the beginning of the phone number if present
        $phoneNumber = preg_replace('/^(?:\+?234|0)/', '', $phoneNumber);
        $phoneNumber = ltrim($phoneNumber, '0');

        // Check if the phone number already starts with '0'
        if (substr($phoneNumber, 0, 1) == '0') {
            return $phoneNumber;
        } else {
            // Add '0' as the starting point of the phone number
            $phoneNumber = '0' . $phoneNumber;

            return $phoneNumber;
        }
    } else {
        return null;
    }
}

function usdt(){

    $addr ="0x955cAc5aE0cF2e6F3b3086df36fC4C9aC7E8560f";

    if ($addr == '') {
        exit();
    }

    $url = "https://api.trongrid.io/v1/accounts/" . $addr;
    $apiKey = "YOUR_API_KEY"; // Replace with your actual API key
    $headers = array(
        'Content-Type: application/json',
        'TRON-PRO-API-KEY: ' . 'a39f9b03-dd30-4a6b-85b3-683ca59d24f7'
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($curl);

    if ($response === false) {
        echo 'Error accessing API';
        exit();
    }

    $data = json_decode($response, true);
    dd($data);
    $lastTx = $data['data'][0]; // Retrieve the first transaction (most recent)
    $lastReceivedDate = $lastTx['block_timestamp'];
    $lastReceivedAddress = $lastTx['to_address'];
    $transactionId = $lastTx['transaction_id'];

    $inputValue = 0;
    $outputValue = 0;

    foreach ($lastTx['internal_transactions'] as $transaction) {
        if ($transaction['from_address'] == $addr) {
            $inputValue += $transaction['value'];
        }
        if ($transaction['to_address'] == $addr) {
            $outputValue += $transaction['value'];
        }
    }

    $networkCharges = $inputValue - $outputValue;
    $sentAmount = $outputValue - $networkCharges;

    echo "Last Received Date: " . date('Y-m-d H:i:s', $lastReceivedDate) . "\n";
    echo "Last Received Address: " . $lastReceivedAddress . "\n";
    echo "Transaction ID: " . $transactionId . "\n";
    echo "Network Charges: " . $networkCharges . " USDT\n";
    echo "Sent Amount: " . $sentAmount . " USDT\n";

}





function confirmBtcPayment($address){
    //  $address = "1DyDvLSenrGC2ZfiLWknBMQA5xMare1ST1";


// Build the API endpoint URL
    $url = 'https://mempool.space/api/address/' . $address . '/txs/chain';

// Make the API request
    $response = file_get_contents($url);

    if ($response === false) {
        return ['amount'=>0, 'txid'=>'', 'confirmed'=>false];
        //  echo 'Error accessing mempool.space API';
        // exit();
    }

    $data = json_decode($response, true);

// Check if there are any transactions for the address
    if (empty($data)) {
        return ['amount'=>0, 'txid'=>'', 'confirmed'=>false];
        // echo 'No transactions found for the address.';
        //  exit();
    }

// Get the last received transaction
    $lastTransaction = $data[0]; // Assuming the transactions are sorted in descending order (most recent first)

    $totalReceivedAmount = 0;
    $totalConfirmations = 0;
    $receiveDate =  null;
    $transId= null;
    $confirm= null;


    foreach ($data as $transaction) {
        /*  if (isset($transaction['status']['confirmed'])) {
              $totalConfirmations += $transaction['status']['confirmed'];
              $receiveDate = $transaction['status']['block_time'];
          }*/
        foreach ($transaction['vout'] as $output) {
            if ($output['scriptpubkey_address'] === $address) {
                $totalReceivedAmount += $output['value'];
                // echo $output['scriptpubkey_address'];
                $transId =$transaction['txid'];
                $confirm =$transaction['status']['confirmed'];
            }
        }
    }

    $totalReceivedAmount = $totalReceivedAmount / 100000000; // Convert satoshis to BTC
    if($totalReceivedAmount>0){
        return ['amount'=>$totalReceivedAmount, 'txid'=>$transId, 'confirmed'=>$confirm];
    }else{
        return 0;
    }
    //  echo "Total Received Amount: " . $totalReceivedAmount . " BTC\n";
    // echo "Total Confirmations: " . $totalConfirmations . " confirmations\n";
    // echo "Recived Date: " . date('d-y-M h:i:s', $receiveDate);

}

function btctoUsd($symbol){
    $apiEndpoint = 'https://pro-api.coinmarketcap.com/v1/tools/price-conversion';
    $apiKey = 'f2e9c0b7-7edd-4889-b97c-83c2e19b7b9e'; // Replace with your actual API key

    $parameters = [
        'amount' => '1',
        'symbol' => $symbol,
        'convert' => 'USD'
    ];

    $url = $apiEndpoint . '?' . http_build_query($parameters);

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, [
        'X-CMC_PRO_API_KEY: ' . $apiKey
    ]);

    $response = curl_exec($curl);

    if ($response === false) {
        echo 'Error accessing CoinMarketCap API: ' . curl_error($curl);
        exit();
    }

    $data = json_decode($response, true);
    $usdPrice=0;
//dd($data);
    if (isset($data['data']['quote']['USD']['price'])) {
        $usdPrice = $data['data']['quote']['USD']['price'];
        // $convertedAmount = $parameters['amount'] * $usdPrice;

        // echo "0.00038 BTC is approximately $usdPrice USD\n";
    } else {
        echo 'Failed to convert BTC to USD using CoinMarketCap API.';
    }

    curl_close($curl);

    //$rate = (1 / (floatval($data['price'])) * $amount);
    // return  ['type'=>'success','price'=>$rate];
    return $usdPrice;

}

function newUSDTDepositAddress(){
// Retrieve records
    $fiveHoursAgo = Carbon::now()->subHours(1);

    $result = UsdtAddress::where(function ($query) use ($fiveHoursAgo) {
        $query->where('last_used', '<', $fiveHoursAgo)
            ->orWhereNull('last_used');
    })->where('status', '1')->firstOrFail();
    return $result->address;
}

function updateUsdtAddressUsed($address, $usedDate, $usedBy){
// Retrieve records
    // $fiveHoursAgo = Carbon::now()->subHours(5);

    $result = UsdtAddress::where('address',$address)->firstOrFail();
    $result->last_used = $usedDate;
    $result->last_used_by = $usedBy;
    $result->save();
    //return $result->address;
}

function getNetwork($dat){
    $data=['GLO' => 1,  'MTN' => 2, 'AIRTEL' => 3, '9MOBILE' => 4];
    return $data[$dat];
}

function getDataPlan($network){
    $plans = DataPlan::where('network', $network)
        ->select('datacode', 'price', 'pname')
        ->get()
        ->map(function ($plan) {
            return [
                'datacode' => $plan->datacode,
                'price' => $plan->price,
                'pname' => $plan->pname,
            ];
        });

    return json_encode($plans);

}

function getCryptoAccountNumber(){
    $total = User::count();
    $rand = randNum().($total+1);
    $check = User::where('crypto_account_number',$rand)->exists();
    while($check){
        $rand=randNum().($total+1);
        $check = User::where('crypto_account_number',$rand)->exists();
    }
    return $rand;
}

function generateAddress($asset, $xpub, $index){
    //$apiKeyTest = env('TTAPIKEYTEST');
    // $sdk = new \Tatum\Sdk('',$apiKeyTest);
//echo $apiKey; die();
    // $responseAdd->config()->setDebug(true);
    $sdk = initiateTatum();
    if($asset=='BTC'){
        /**
         * GET /v3/bitcoin/address/{xpub}/{index}
         *
         * @var \Tatum\Model\GeneratedAddressBtc $response
         */
        // $sdk = initiateTatum();
        $response = $sdk
            ->api()
            ->bitcoin()
            ->btcGenerateAddress($xpub, $index);

        $data = json_decode($response);
        return $data->address;
    }elseif($asset=='USDT_TRON'){
        /**
         * GET /v3/bitcoin/address/{xpub}/{index}
         *
         * @var \Tatum\Model\GeneratedAddressBtc $response
         */
        $response = $sdk
            ->api()
            ->tron()
            ->tronGenerateAddress($xpub, $index);

        $data = json_decode($response);
        return $data->address;
    }elseif($asset=='ETH'){
        /**
         * GET /v3/bitcoin/address/{xpub}/{index}
         *
         * @var \Tatum\Model\GeneratedAddressBtc $response
         */
        $response = $sdk
            ->api()
            ->ethereum()
            ->ethGenerateAddress($xpub, $index);

        $data = json_decode($response);
        return $data->address;
    }
}

function generateAddressByAccountId($accountId){
    //  $apiKeyTest = env('TTAPIKEYTEST');
    // $sdk = new \Tatum\Sdk('',$apiKeyTest);
//echo $apiKey; die();
    // $sdk->testnet()->config()->setDebug(true);
    $sdk = initiateTatum();
    $responseAdd= $sdk->api()->account()->generateAccountAddress($accountId);
    // $addressGenerated = json_decode($responseAdd);
    return $responseAdd;
}

function generatePrecalculateGasPumpAddress(){
    $masterAddress= masterGasAddress('USDT_TRON');
    $arg_create_gas_pump = (new \Tatum\Model\CreateGasPump())

        // The blockchain to work with
        ->setChain('USDT_TRON')

        // The blockchain address that will own the precalculated gas pump addresses and will be used to pay...
        ->setOwner($masterAddress->attarched_address)

        // The start index of the range of gas pump addresses to precalculate
        ->setFrom(0)

        // The end index of the range of gas pump addresses to precalculate; must be greater than or equal t...
        ->setTo(1000);

    try {

        /**
         * POST /v3/gas-pump
         *
         * @var string[] $response
         */
        $tSdk =initiateTatum();// new \Tatum\Sdk('',$apiKeyTest);
        $response = $tSdk// new \Tatum\Sdk('',$apiKeyTest);
        ->api()
            ->gasPump()
            ->precalculateGasPumpAddresses($arg_create_gas_pump);

        var_dump($response);

    } catch (\Tatum\Sdk\ApiException $apiExc) {
        echo sprintf(
            "API Exception when calling api()->gasPump()->precalculateGasPumpAddresses(): %s\n",
            var_export($apiExc->getResponseObject(), true)
        );
    } catch (\Exception $exc) {
        echo sprintf(
            "Exception when calling api()->gasPump()->precalculateGasPumpAddresses(): %s\n",
            $exc->getMessage()
        );
    }
}

function masterGasAddress($code){
    return  VirtualAccounts::where('user_id','1')->where('virtual_account_type','Gas')->where('blockchain_code',$code)->first();
}


function getAssetAccountBalance($vacc){
    $tenMinutesAgo = now()->subMinutes(5);
    $virtualAccountRecord = $vacc;//\App\Models\VirtualAccounts::where('virtual_account_id',$id)->first();
    if ($virtualAccountRecord && $virtualAccountRecord->last_check < $tenMinutesAgo) {


//echo $apiKey; die();
        // $sdk->testnet()->config()->setDebug(true);
        $sdk =  initiateTatum();
        $responseAdd=$sdk->api()->account()->getAccountBalance($vacc->virtual_account_id);
        // $addressGenerated = json_decode($responseAdd);
        // dd($responseAdd);
        $accountBalance = $responseAdd->getAccountBalance();
        $availableBalance = $responseAdd->getAvailableBalance();
//dd($availableBalance);
        if (!empty($responseAdd->getAvailableBalance()) || !empty($responseAdd->getAccountBalance())) {
            //update the virtual account balance to save tatum credit
            //check if last check is more than 10 minute
            $rate = getExchangeRate($virtualAccountRecord->blockchain_code,'USD');
            // dd($rate);
            $virtualAccountRecord->accountBalance=$accountBalance;
            $virtualAccountRecord->availableBalance = $availableBalance;
            $virtualAccountRecord->availableBalanceUSD = convertAssetToUSD($rate, $availableBalance);
            $virtualAccountRecord->accountBalanceUSD = convertAssetToUSD($rate,$accountBalance);
            $virtualAccountRecord->last_check_rate = $rate;

            $virtualAccountRecord->last_check = now()->toDateTimeString();
            $virtualAccountRecord->save();

            //   DB::table('virtual_accounts')->where('virtual_account_id', $id)->update(['accountBalance' => $accountBalance, 'availableBalance' => $availableBalance, 'last_check' => now()->toDateTimeString()]);

            //
        }
        return $responseAdd->getAvailableBalance();
    }else{
        return $virtualAccountRecord->availableBalance;
    }
}
function getAssetAccountBalanceReal($vacc){

    $virtualAccountRecord= $vacc;
//echo $apiKey; die();
    // $sdk->testnet()->config()->setDebug(true);
    $sdk =  initiateTatum();
    $responseAdd=$sdk->api()->account()->getAccountBalance($vacc->virtual_account_id);
    // $addressGenerated = json_decode($responseAdd);
    // dd($responseAdd);
    $accountBalance = $responseAdd->getAccountBalance();
    $availableBalance = $responseAdd->getAvailableBalance();

    if (!empty($responseAdd->getAvailableBalance()) || !empty($responseAdd->getAccountBalance())) {
        //update the virtual account balance to save tatum credit
        //check if last check is more than 10 minute
        $rate = getExchangeRate($virtualAccountRecord->blockchain_code,'USD');
        // dd($rate);
        $virtualAccountRecord->accountBalance=$accountBalance;
        $virtualAccountRecord->availableBalance = $availableBalance;
        $virtualAccountRecord->availableBalanceUSD = convertAssetToUSD($rate, $availableBalance);
        $virtualAccountRecord->accountBalanceUSD = convertAssetToUSD($rate,$accountBalance);

        $virtualAccountRecord->last_check = now()->toDateTimeString();
        $virtualAccountRecord->last_check_rate = $rate;
        $virtualAccountRecord->save();

        //   DB::table('virtual_accounts')->where('virtual_account_id', $id)->update(['accountBalance' => $accountBalance, 'availableBalance' => $availableBalance, 'last_check' => now()->toDateTimeString()]);

        //
    }
    return $virtualAccountRecord;

}
function getExchangeRate($arg_currency, $arg_base_pair){
    $exchange = \App\Models\ExchangePrice::where('asset_code',$arg_currency)->first();
    $tenMinutesAgo = now()->subMinutes(2);
    $sdk = initiateTatum();
    if ($exchange && $exchange->last_check < $tenMinutesAgo) {



        $responseAdd=$sdk->api()
            ->exchangeRate()
            ->getExchangeRate($arg_currency, $arg_base_pair);
        //  $exchange->asset_name = $arg_currency;
        // $exchange->asset_code = $arg_currency;
        $exchange->last_check = now()->toDateTimeString();
        $exchange->amount = $responseAdd->getValue();
        $exchange->save();
        return $responseAdd->getValue();
    }elseif(!$exchange){

        $exchange = new \App\Models\ExchangePrice();


        // $sdk->testnet()->config()->setDebug(true);
        $responseAdd = $sdk->api()
            ->exchangeRate()
            ->getExchangeRate($arg_currency, $arg_base_pair);
        $exchange->asset_name = $arg_currency;
        $exchange->asset_code = $arg_currency;
        $exchange->last_check = now()->toDateTimeString();
        $exchange->amount = $responseAdd->getValue();
        $exchange->save();
        //   dd($responseAdd->getValue());//
        return $responseAdd->getValue();
    }
    else{
        return $exchange->amount;
    }



}

function convertAssetToUSD($rate, $balance){
    //if($balance>=0)
    $value = (float)$rate * (float)$balance;
    return round($value, 2) ;

}

function convertAssetToUSDWithRate($asset, $balance){
    //if($balance>=0)
    $rate= getExchangeRate($asset,'USD');
    $value = (float)$rate * (float)$balance;
    return round($value, 2) ;

}


function sendTransaction($sender, $recipient, $amount, $reference, $payid,  $description){

// Set your API Keys 👇 here
    // $sdk = new \Tatum\Sdk();

// 🐛 Enable debugging on the MainNet
    // $sdk->mainnet()->config()->setDebug(true);

    $arg_create_transaction = (new \Tatum\Model\CreateTransaction())

        // Internal sender account ID within Tatum platform
        ->setSenderAccountId($sender)

        // Internal recipient account ID within Tatum platform
        ->setRecipientAccountId($recipient)

        // Amount to be sent.
        ->setAmount($amount)

        // (optional) Anonymous transaction does not show sender account to recipient, default is false
        ->setAnonymous(false)

        // (optional) Enable compliant checks. Transaction will not be processed, if compliant check fails.
        ->setCompliant(false)

        // (optional) For bookkeeping to distinct transaction purpose.
        ->setTransactionCode($reference)

        // (optional) Payment ID, External identifier of the payment, which can be used to pair transactions within Tat...
        ->setPaymentId($payid)

        // (optional) Note visible to both, sender and recipient
        ->setRecipientNote($description)

        // (optional) Exchange rate of the base pair. Only applicable for Tatum's Virtual currencies Ledger transaction...
        //  ->setBaseRate(1)

        // (optional) Note visible to sender
        ->setSenderNote($description);

    try {
        $sdk = initiateTatum();
        $response=$sdk
            ->api()
            ->transaction()
            ->sendTransaction($arg_create_transaction);

        var_dump($response);

    } catch (\Tatum\Sdk\ApiException $apiExc) {
        echo sprintf(
            "API Exception when calling api()->transaction()->sendTransaction(): %s\n",
            var_export($apiExc->getResponseObject(), true)
        );
    } catch (\Exception $exc) {
        echo sprintf(
            "Exception when calling api()->transaction()->sendTransaction(): %s\n",
            $exc->getMessage()
        );
    }
}

function convertUsdToAsset($currentRate, $amount){
    $rate = $currentRate;
    $value = round($amount / $rate, 8);
    $formattedValue = number_format($value, 8, '.', '');
    return $formattedValue;


}


function updateAccountBalance($vacc){
    $tenMinutesAgo = now()->subMinutes(10);
    $virtualAccountRecord = $vacc;//\App\Models\VirtualAccounts::where('virtual_account_id',$id)->first();
    if ($virtualAccountRecord && $virtualAccountRecord->last_check < $tenMinutesAgo) {

        $apiKeyTest = env('TTAPIKEYTEST');
        $sdk = new \Tatum\Sdk('', $apiKeyTest);
//echo $apiKey; die();
        // $sdk->testnet()->config()->setDebug(true);
        $responseAdd = $sdk->testnet()->api()->account()->getAccountBalance($vacc->virtual_account_id);
        // $addressGenerated = json_decode($responseAdd);
        // dd($responseAdd);
        $accountBalance = $responseAdd->getAccountBalance();
        $availableBalance = $responseAdd->getAvailableBalance();

        if (!empty($responseAdd->getAvailableBalance()) || !empty($responseAdd->getAccountBalance())) {
            //update the virtual account balance to save tatum credit
            //check if last check is more than 10 minute
            $rate = getExchangeRate($virtualAccountRecord->blockchain_code,'USD');
            // dd($rate);
            $virtualAccountRecord->accountBalance=$accountBalance;
            $virtualAccountRecord->availableBalance = $availableBalance;
            $virtualAccountRecord->availableBalanceUSD = convertAssetToUSD($rate, $availableBalance);
            $virtualAccountRecord->accountBalanceUSD = convertAssetToUSD($rate,$accountBalance);

            $virtualAccountRecord->last_check = now()->toDateTimeString();
            $virtualAccountRecord->save();

            //   DB::table('virtual_accounts')->where('virtual_account_id', $id)->update(['accountBalance' => $accountBalance, 'availableBalance' => $availableBalance, 'last_check' => now()->toDateTimeString()]);

            //
        }
        return $responseAdd->getAvailableBalance();
    }else{
        return $virtualAccountRecord->availableBalance;
    }
}

function totalAssetBalance($asset){
    $total = \App\Models\VirtualAccounts::where('blockchain_code',$asset)->sum('availableBalance');
    return  number_format($total,8,'.', '');

}

function getCableList($network){

    $resultData = session('cableSub');
    $resultNetwork = session('tv');
    if(!empty($resultData) && ($resultNetwork==$network)){
        return $resultData;
    }else {
        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://api.oneappgo.com/v1/listcabletv?tv='.$network,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPHEADER => array(
                'Authorization: Bearer '.env('BILL_PUBLIC')
            ),
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        $result = json_decode($response, true);
        // dd($result);
        if (isset($result)) {
            $resultData = $result['cablelist'];
            session(['cableSub' => $result['cablelist']]);
            session(['tv'=>$network]);
            return  $resultData;

        }
    }

}

function verifyICu($cable_type,$icu_no){


    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => "https://api.oneappgo.com/v1/verifycable?iuc=$icu_no&type=$cable_type",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'GET',
        CURLOPT_HTTPHEADER => array(
            'Authorization: Bearer '.env('BILL_PUBLIC')
        ),
    ));

    $response = curl_exec($curl);

    curl_close($curl);
    $result = json_decode($response, true);
    // dd($result);
    if (isset($result)) {
        $resultData = $result['details'];
        //session(['cableSub' => $result['cablelist']]);
        // session(['tv'=>$network]);
        $resultData['status']=$result['status'];
        //  dd($resultData);
        return  $resultData;

    }else{
        return null;
    }

    /*
        return response()->json([
            'data' => $result,
            'status' => 'success'
        ], 200);
    */
}

function createVirtualAccountDetails(){

    $user = User::where('id',Auth()->user()->id)->first();
    if(empty($user->crypto_account_number)){
        $cAccount = getCryptoAccountNumber();
        $user->crypto_account_number=$cAccount;
        $user->crypto_account_code='R2T'.$cAccount;
        $user->crypto_customer_id='R2TCUS'.$cAccount;
        $user->save();
    }



}


function getElectricityProvider(){

    $resultData = session('electricity');

    if(!empty($resultData)){
        return $resultData;
    }else {
        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://api.oneappgo.com/v1/elect-billers',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPHEADER => array(
                'Authorization: Bearer '.env('BILL_PUBLIC')
            ),
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        $result = json_decode($response, true);
        //dd($result);
        if (isset($result)) {
            $resultData = $result['lists'];
            session(['electricity' => $result['lists']]);
            return  $resultData;

        }
    }

}



function verifyMeterNo($provider,$meter_no ){


    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => "https://api.oneappgo.com/v1/verifyelect?meterno=$meter_no&provider=$provider",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'GET',
        CURLOPT_HTTPHEADER => array(
            'Authorization: Bearer '.env('BILL_PUBLIC')
        ),
    ));

    $response = curl_exec($curl);

    curl_close($curl);
    $result = json_decode($response, true);
    // dd($result);
    if (isset($result)) {
        if($result['status']==true) {
            $resultData = $result['details'];
            //session(['cableSub' => $result['cablelist']]);
            // session(['tv'=>$network]);
            $resultData['status'] = $result['status'];
            //  dd($resultData);
            return $resultData;
        }else{
            return null;
        }

    }else{
        return null;
    }

    /*
        return response()->json([
            'data' => $result,
            'status' => 'success'
        ], 200);
    */
}
function initiateTatum(){

// Set your API Keys 👇 here
    $sdk = new \Tatum\Sdk(env("TTAPIKEYLIVE"),env('TTAPIKEYTEST'));

// 🐛 Enable debugging on the MainNet
    $sdk->mainnet()->config()->setDebug(false);
    // return $sdk->mainnet();
    return $sdk->mainnet();
}

function transferForWithdraw($from, $to, $amount){
    $coin = VirtualAccounts::where('user_id',Auth()->user()->id)->where('virtual_account_id',$request->account)->firstOrFail();//Coins::where('code',$request->coin)->first();
    //check accout balance

    $transChanges=0;
    //do virtual account transfer to trading virtual account
    $tradingAcc = VirtualAccounts::where('blockchain_code',$coin->blockchain_code)->where('virtual_account_type','Gas')->firstOrFail();
    // $payoutRate = $coin->coinDetails->rate;
    //  $payoutAmount = $payoutRate * $finalAmount;
    $currentCoinRate = getExchangeRate($coin->blockchain_code, 'USD');
    $paymentId= uniqid().time() . Auth()->user()->id;
    $orderId = 'R2T-'.$paymentId;
    $description=  '$' . $request->amount . ' ' . $request->coin . ' Crypto Trading';
    $assetAmount = convertUsdToAsset($currentCoinRate, $amount);
//$payoutAmount = $finalAmount * $coi
//dd($assetAmount);
//save the transaction first

    // $payStatus = NowPayments::getPaymentStatus('4703776273');
    //\  dd($payStatus);
// Set your API Keys 👇 here
    // $sdk = new \Tatum\Sdk('',env('TTAPIKEYTEST'));
    $sdk = initiateTatum();
// 🐛 Enable debugging on the MainNet
    // $sdk->testnet()->config()->setDebug(true);

    $arg_create_transaction = (new \Tatum\Model\CreateTransaction())

        // Internal sender account ID within Tatum platform
        ->setSenderAccountId($coin->virtual_account_id)

        // Internal recipient account ID within Tatum platform
        ->setRecipientAccountId($tradingAcc->virtual_account_id)

        // Amount to be sent.
        ->setAmount($assetAmount)

        // (optional) Anonymous transaction does not show sender account to recipient, default is false
        ->setAnonymous(false)

        // (optional) Enable compliant checks. Transaction will not be processed, if compliant check fails.
        ->setCompliant(false)

        // (optional) For bookkeeping to distinct transaction purpose.
        ->setTransactionCode($orderId)

        // (optional) Payment ID, External identifier of the payment, which can be used to pair transactions within Tat...
        ->setPaymentId($paymentId)

        // (optional) Note visible to both, sender and recipient
        ->setRecipientNote($description)

        // (optional) Exchange rate of the base pair. Only applicable for Tatum's Virtual currencies Ledger transaction...
        //  ->setBaseRate(1)

        // (optional) Note visible to sender
        ->setSenderNote($description);

    try {

        /**
         * POST /v3/ledger/transaction
         *
         * @var \Tatum\Model\TransactionResult $response
         */
        $response = $sdk
            ->api()
            ->transaction()
            ->sendTransaction($arg_create_transaction);
        $transaction_reference = $response->getReference();
//dd($transaction_reference);
        if (!empty($transaction_reference)) {
            // dd($transaction_reference);

            //  $newTrans->save();

            //  return response()->json(['data' => $newTrans->order_id, 'message' => 'Payment Initiated Successfuly'], 200);

        }

    } catch (\Tatum\Sdk\ApiException $apiExc) {
        /*
        echo sprintf(
            "API Exception when calling api()->transaction()->sendTransaction(): %s\n",
            var_export($apiExc->getResponseObject(), true)
        );*/
        $errorCode = $apiExc->getResponseObject()['errorCode'];
        if ($errorCode == 'balance.insufficient') {
            return response()->json([
                'status' => 'error',
                'message' => 'Insufficient balance please deposit to your wallet and try again!!'
            ], 400);
        } else {
            return response()->json([
                'status' => 'error',
                'message' => var_export($apiExc->getResponseObject(), true)
            ], 400);
        }

    } catch (\Exception $exc) {
        echo sprintf(
            "Exception when calling api()->transaction()->sendTransaction(): %s\n",
            $exc->getMessage()
        );
    }

}


function getAssetGasEstimate($vcc, $address, $amount){

// Set your API Keys 👇 here
    if($vcc->blockchain_code=='BTC') {
// Set your API Keys 👇 here
        $sdk = initiateTatum();

        $arg_offchain_estimate_fee = (new \Tatum\Model\OffchainEstimateFee())

            // Sender account ID
            ->setSenderAccountId($vcc->virtual_account_id)

            // Blockchain address to send assets to. For BTC, LTC, and DOGE, it is possible to enter list of mul...
            ->setAddress($address)

            // Amount to be withdrawn to blockchain.
            ->setAmount($amount)


            // (optional) For BTC, LTC, and DOGE, it is possible to enter list of multiple recipient blockchain amounts. Li...
            ->setMultipleAmounts(null)

            // (optional) Used to parametrize withdrawal as a change address for left coins from transaction. XPub or attr ...
            ->setAttr('null')

            // (optional) Extended public key (xpub) of the wallet associated with the accounts.
            ->setXpub($vcc->xpub);

        try {
            $fast = 0;
            $medium = 0;
            $slow = 0;
            /**
             * POST /v3/offchain/blockchain/estimate
             *
             * @var \Tatum\Model\FeeBtc $response
             */
            $response = $sdk//->mainnet()
            ->api()
                ->virtualAccountBlockchainFees()
                ->offchainEstimateFee($arg_offchain_estimate_fee);

            $fast = $response->getFast();
            $medium = $response->getMedium();
            $slow = $response->getSlow();
            return ['fast' => $fast, 'medium' => $medium, 'slow' => $slow];

        } catch (\Tatum\Sdk\ApiException $apiExc) {
            echo sprintf(
                "API Exception when calling api()->virtualAccountBlockchainFees()->offchainEstimateFee(): %s\n",
                var_export($apiExc->getResponseObject(), true)
            );
        } catch (\Exception $exc) {
            echo sprintf(
                "Exception when calling api()->virtualAccountBlockchainFees()->offchainEstimateFee(): %s\n",
                $exc->getMessage()
            );
        }
    }else{
        $fast = 2;
        $medium =2;
        $slow =2;
        return ['fast' => $fast, 'medium' => $medium, 'slow' => $slow];
    }
}

function getUSDTAddress() {
    try {
        // Fetch the first address where assigned_to is null
        $address = UsdtAddress::whereNull('assigned_to')->first();
        //->first(['address', 'derivative_index', 'master_address', 'token_address', 'master_derivative']);

        return $address; // Returns a single address object or null
    } catch (\Exception $e) {
        // Handle any exceptions
        error_log("Database error: " . $e->getMessage()); // Log error for debugging
        return null; // Return null on error to indicate no address was found
    }
}

function assignAddressToVA($accountId, $address){

    $client = new Client();

    try {
        $response = $client->request('POST', "https://api.tatum.io/v3/offchain/account/$accountId/address/$address", [
            'headers' => [
                'accept' => 'application/json',
                'x-api-key' => env("TTAPIKEYLIVE"),
            ],
        ]);

        // Decode the response body
        $responseData = json_decode($response->getBody(), true);

        // Check if the response contains the expected data
        if (isset($responseData['address']) && isset($responseData['currency'])) {
            // Return false to indicate success
            return true;
        }

    } catch (RequestException $e) {
        // Handle exceptions (for example, log the error message)
        echo "Request failed: " . $e->getMessage();
        // Optionally return null or throw an exception
        return false;
    }

    // If the response does not match the expected structure, return null or handle as needed
    return false;



}

function getTatumKey($type){
    if($type=='test'){
        return env('TTAPIKEYTEST');

    }elseif($type=='live'){
        return env("TTAPIKEYLIVE");
    }
}

function generateTronPrivateKey($account){

// Set your API Keys 👇 here
    $sdk = initiateTatum();

// 🐛 Enable debugging on the MainNet
    // $sdk->mainnet()->config()->setDebug(true);

    $arg_priv_key_request = (new \Tatum\Model\PrivKeyRequest())

        // Derivation index of private key to generate.
        ->setIndex($account->master_derivative)

        // Mnemonic to generate private key from.
        ->setMnemonic($account->blockchain->menonic);

    try {

        /**
         * POST /v3/tron/wallet/priv
         *
         * @var \Tatum\Model\PrivKey $response
         */
        $response = $sdk
            ->api()
            ->tron()
            ->tronGenerateAddressPrivateKey($arg_priv_key_request);

        return $response->getKey();

    } catch (\Tatum\Sdk\ApiException $apiExc) {
        echo sprintf(
            "API Exception when calling api()->tron()->tronGenerateAddressPrivateKey(): %s\n",
            var_export($apiExc->getResponseObject(), true)
        );
        return null;
    } catch (\Exception $exc) {
        echo sprintf(
            "Exception when calling api()->tron()->tronGenerateAddressPrivateKey(): %s\n",
            $exc->getMessage()
        );
        return null;
    }
}
function activateTronGasPumpAddress($account, $privateKey) {
    $client = new \GuzzleHttp\Client();

    try {
        // Prepare the request body with proper variable interpolation
        $body = json_encode([
            'chain' => 'TRON',
            // 'feesCovered' => true,
            'owner' => $account->master_address,
            'from' => $account->derivation_key,
            'to' => $account->derivation_key,
            'feeLimit' => 50,
            'fromPrivateKey' => $privateKey,
        ]);

        // Make the API request
        $response = $client->request('POST', 'https://api.tatum.io/v3/gas-pump/activate', [
            'body' => $body,
            'headers' => [
                'accept' => 'application/json',
                'content-type' => 'application/json',
                'x-api-key' => getTatumKey('live'),
            ],
        ]);
//dd((string) $response->getBody());
        // Check if the response status code is 200
        if ($response->getStatusCode() === 200) {
            $responseData = json_decode($response->getBody(), true);
//dd($responseData);
            // Check if 'txId' is present in the response
            if (isset($responseData['txId'])) {
                return $responseData['txId'];
            } else {
                return ""; // Return empty string if 'txId' is not set
            }
        } else {
            // Handle non-200 responses
            return ""; // You might want to log or handle this case further
        }

    } catch (\GuzzleHttp\Exception\RequestException $e) {
        dd((string) $response->getBody());
        // Handle exceptions (e.g., network errors)
        // Log the error message for debugging
        echo "Request failed: " . $e->getMessage();
        // return ""; // Return empty string on exception
    }

}

function checkifActivate($account){

    $client = new Client();

    try {
        // Make the API request
        $response = $client->request('GET', "https://api.tatum.io/v3/gas-pump/activated/TRON/{$account->master_address}/{$account->derivation_key}", [
            'headers' => [
                'accept' => 'application/json',
                'x-api-key' => getTatumKey('live'),
            ],
        ]);

        // Check if the response status code is 200
        if ($response->getStatusCode() === 200) {
            // Decode the response body
            $responseData = json_decode($response->getBody(), true);
//dd($responseData);
            // Check the 'activated' field
            if (isset($responseData['activated'])) {
                return $responseData['activated'];
            } else {
                return false;
            }
        } else {
            // Handle non-200 responses
            return false;
        }
    } catch (\GuzzleHttp\Exception\RequestException $e) {
        // Handle exceptions (e.g., network errors)
        echo "Request failed: " . $e->getMessage();

        return false;
    }
}

function checkAccount($currency, $accountNumber){

// Set your API Keys 👇 here
    $sdk = initiateTatum();


// Max number of items per page is 50.
    $arg_page_size = 20;

// Page number
    $arg_page = 0;

// Direction of sorting. Can be asc or desc
    $arg_sort = "asc";

// Sort by
    $arg_sort_by = "ACCOUNT_NUMBER";

// Filter only active or non active accounts
    $arg_active = true;

// Filter only accounts with non zero balances
    $arg_only_non_zero_balance = false;

// Filter only frozen or non frozen accounts
    $arg_frozen = false;

// Filter by currency
    $arg_currency = $currency;

// Filter by account number
    $arg_account_number = $accountNumber;

    try {

        /**
         * GET /v3/ledger/account
         *
         * @var \Tatum\Model\Account[] $response
         */
        $response = $sdk//->mainnet()
        ->api()
            ->account()
            ->getAccounts($arg_page_size, $arg_page, $arg_sort, $arg_sort_by, $arg_active, $arg_only_non_zero_balance, $arg_frozen, $arg_currency, $arg_account_number);

        dd($response);

    } catch (\Tatum\Sdk\ApiException $apiExc) {
        echo sprintf(
            "API Exception when calling api()->account()->getAccounts(): %s\n",
            var_export($apiExc->getResponseObject(), true)
        );
    } catch (\Exception $exc) {
        echo sprintf(
            "Exception when calling api()->account()->getAccounts(): %s\n",
            $exc->getMessage()
        );
    }
}

function getTronBalance($address) {
    $url = "https://api.tronscan.org/api/account?address=" . $address;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($response, true);
    if (isset($data['data']['balance'])) {
        return $data['data']['balance'] / 1000000; // Balance in TRX
    }

// Usage
    $tronAddress = "YOUR_TRON_ADDRESS";
    $balance = getTronBalance($tronAddress);
    echo "TRON Balance: " . $balance . " TRX";
    return null; // Return null if unable to retrieve balance
}

function getUsdtAddressBalance($tronAddress, $contractAddress) {

    $apiKey = env('trongrid'); // Your TronGrid API key

    // Define the TronGrid API endpoint
    $url = "https://api.trongrid.io/v1/accounts/" . $tronAddress;

    // Initialize cURL session
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Add the API key to headers for authentication
    $headers = [
        "TRON-PRO-API-KEY: $apiKey"
    ];
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    // Execute the cURL request
    $response = curl_exec($ch);
    curl_close($ch);

    // Check for errors in the response
    if ($response === false) {
        return "Error: " . curl_error($ch);
    }

    // Decode the JSON response
    $data = json_decode($response, true);
//dd($data);
    // Check if the 'data' field exists
    if (isset($data['data'][0]['trc20'])) {
        $trc20Tokens = $data['data'][0]['trc20'];

        // Check for the specific contract address (e.g., USDT)
        if (isset($trc20Tokens[0][$contractAddress])) {
            $balance = $trc20Tokens[0][$contractAddress]; // The balance in smallest unit
            $decimal = 6; // USDT has 6 decimal places
            return $balance / pow(10, $decimal); // Convert to human-readable format
        }
    }

    return 0;


}
function getTRXBalance($tronAddress) {

   // $tronAddress = "TSkXHYUGBDGEeykGHSGa9PBYVhT5gJR682"; // Replace with the Tron address

    $apiKey = env('TRONGRID'); // Your TronGrid API key

    // Define the TronGrid API endpoint
    $url = "https://api.trongrid.io/v1/accounts/" . $tronAddress;

    // Initialize cURL session
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Add the API key to headers for authentication
    $headers = [
        "TRON-PRO-API-KEY: $apiKey"
    ];
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    // Execute the cURL request
    $response = curl_exec($ch);
    curl_close($ch);

    // Check for errors in the response
    if ($response === false) {
        return "Error: " . curl_error($ch);
    }

    // Decode the JSON response
    $data = json_decode($response, true);

    // Check if the 'data' field exists and retrieve the TRX balance
    if (isset($data['data'][0]['balance'])) {
        $trxBalance = $data['data'][0]['balance']; // TRX balance in sun (smallest unit)
        return $trxBalance / pow(10, 6); // Convert to human-readable format (1 TRX = 1,000,000 sun)
    }

    return 0; // Return 0 if no balance found




}


function formatDate($date, $format = 'Y-m-d H:i:s') {
    try {
        // Parse the date using Carbon
        $carbonDate = Carbon::createFromFormat($format, $date);

        // Format the date to include AM/PM
        return $carbonDate->format('Y-m-d'); // h: 12-hour format, A: AM/PM
    } catch (\Exception $e) {
        return "Invalid date format";
    }
}

function formatDatetime($date, $format = 'Y-m-d H:i:s') {
    try {
        // Parse the date using Carbon
        $carbonDate = Carbon::createFromFormat($format, $date);

        // Format the date to include AM/PM
        return $carbonDate->format('Y-m-d h:i A'); // h: 12-hour format, A: AM/PM
    } catch (\Exception $e) {
        return "Invalid date format";
    }
}


function formatTime($date, $format = 'Y-m-d H:i:s') {
    try {
        // Parse the date using Carbon
        $carbonDate = Carbon::createFromFormat($format, $date);

        // Format the date to include AM/PM
        return $carbonDate->format('h:i A'); // h: 12-hour format, A: AM/PM
    } catch (\Exception $e) {
        return "Invalid date format";
    }
}

function loadState($id){
    return DB::select('select id, name from states where country_id=:ct',[':ct'=>$id]);

}
function loadCity($id){
    return DB::select('select id, name from city where state_id=:ct',[':ct'=>$id]);

}


function repushBolddNotification($transactionRef){
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => 'https://api.oneappgo.com/v1/business/repushnotification',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'GET',
        CURLOPT_POSTFIELDS =>'{
    "reference": "$transactionRef"
}',
        CURLOPT_HTTPHEADER => array(
            'Authorization: Bearer '.env("CARD_API_SECRET"),
            'Content-Type: application/json'
        ),
    ));

    $response = curl_exec($curl);

    curl_close($curl);

    $apiResponse = json_decode($response, true);

    // Check if the response indicates success
    if (isset($apiResponse['status']) && $apiResponse['status'] === true) {
        return true;
    }
}

function getPendingKyc(){
    $totalCount = DB::table('virtual_card_kys')
        ->where('status', 'like', 'pending')
        ->count();

    return $totalCount;

}

function  getCardSetting(){
    return DB::table('virtual_cards_settings')->where('status','active')->first();
}

function getCardBalance($cardId){
    $baseUrl = env("CARD_URL");
    $secretKey = env("CARD_API_SECRET");

    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => $baseUrl . '/business/vcard-details',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => '{
                         "cardid": "'.$cardId.'"
                        }',
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json',
            'Authorization: ' . 'Bearer '.$secretKey,
        ),
    ));

    $cardDetailsResponse = curl_exec($curl);
    curl_close($curl);
    if ($cardDetailsResponse) {
        $cardDetails = json_decode($cardDetailsResponse, true);
//return $cardDetails;
        if (isset($cardDetails['currency'])) {
            // Store or update the virtual card details in the database
             VirtualCard::updateOrCreate(
                ['card_id' => $cardId],
                [

                    'currency' => $cardDetails['currency'],
                    'card_balance' => $cardDetails['current_bal'],

                    'available_bal' => $cardDetails['available_bal'],
                    'created_at' => now(),
                    'updated_at' => now(),
                ]
            );
             return true;
        }
    }
        }


        function saveReferTracking($owner_id, $earn_from, $refer_user, $amount){
            $refer = new ReferBonus();
            $refer->owner_id = $owner_id;
            $refer->earn_from=$earn_from;
            $refer->refer_user = $refer_user;
            $refer->amount = $amount;
            $refer->created_by = Auth()->user()->id;
            $refer->save();
        }

        function systemInternalAsset($senderAccount, $recipientAccount, $assetAmount, $description ){
            $paymentId= uniqid().time() . Auth()->user()->id;
            $orderId = 'R2T-'.$paymentId;

            $sdk = initiateTatum();
// 🐛 Enable debugging on the MainNet
            // $sdk->testnet()->config()->setDebug(true);

            $arg_create_transaction = (new \Tatum\Model\CreateTransaction())

                // Internal sender account ID within Tatum platform
                ->setSenderAccountId($senderAccount->virtual_account_id)

                // Internal recipient account ID within Tatum platform
                ->setRecipientAccountId($recipientAccount->virtual_account_id)

                // Amount to be sent.
                ->setAmount($assetAmount)

                // (optional) Anonymous transaction does not show sender account to recipient, default is false
                ->setAnonymous(false)

                // (optional) Enable compliant checks. Transaction will not be processed, if compliant check fails.
                ->setCompliant(false)

                // (optional) For bookkeeping to distinct transaction purpose.
                ->setTransactionCode($orderId)

                // (optional) Payment ID, External identifier of the payment, which can be used to pair transactions within Tat...
                ->setPaymentId($paymentId)

                // (optional) Note visible to both, sender and recipient
                ->setRecipientNote($description)

                // (optional) Exchange rate of the base pair. Only applicable for Tatum's Virtual currencies Ledger transaction...
                //  ->setBaseRate(1)

                // (optional) Note visible to sender
                ->setSenderNote($description);

            try {

                /**
                 * POST /v3/ledger/transaction
                 *
                 * @var \Tatum\Model\TransactionResult $response
                 */
                $response = $sdk
                    ->api()
                    ->transaction()
                    ->sendTransaction($arg_create_transaction);
                $transaction_reference = $response->getReference();
//dd($transaction_reference);
                if(!empty($transaction_reference)){
                    //save transaction
                    return response()->json([
                        'status' => 'success',
                        'message' => $transaction_reference
                    ], 200);
                }
            } catch (\Tatum\Sdk\ApiException $apiExc) {
                /*
                echo sprintf(
                    "API Exception when calling api()->transaction()->sendTransaction(): %s\n",
                    var_export($apiExc->getResponseObject(), true)
                );*/
                $errorCode = $apiExc->getResponseObject()['errorCode'];
                if($errorCode=='balance.insufficient') {
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Insufficient balance please deposit to your wallet and try again!!'
                    ], 400);
                }else{
                    return response()->json([
                        'status' => 'error',
                        'message' =>  var_export($apiExc->getResponseObject(), true)
                    ], 400);
                }

            } catch (\Exception $exc) {
                echo sprintf(
                    "Exception when calling api()->transaction()->sendTransaction(): %s\n",
                    $exc->getMessage()
                );
            }
        }

        function getAllCoin(){
    return DB::table('coins')->select('code', 'name')->get();
        }













