<?php

namespace App\Http\Services\Deposit\Bank;

use App\Http\Services\Deposit\Bank\Util\ResponseBankUtilDepositServices;
use App\Models\Gateway;
use Illuminate\Support\Facades\URL;

/**
 * Laravel/Symfony Developer
 * Name: Pynith Limited
 * Telegram: @pynith
 * Hire me via Telegram: pynith
 */
class OTPayBankDepositServices
{

    /**
     * Deposit Payment
     * 
     * @param string reference
     * @param string currency
     * @param string amount
     * @param string method
     */
    public function deposit(
        string $reference,
        string $currency,
        string $amount,
        string $method
    ) {
        try {
			$user = auth()->user();
			
            // Find Setting
            $setting = Gateway::where(['code' => '104', 'status' => 1])->first();

            // Exception
            if(!$setting) throw new \Exception("Service not enabled at the moment");

            // Parse setting
            $setting = json_decode($setting->gateway_parameters);

            // Request Body
            $requestBody = array(
                "merchantId" => intval($setting->merchantId->value),
                "merchantOrderId" => $reference,
                "amount" 		=> $amount,
            );
			
            // Build Sign
            $sign = self::buildSignDigest($requestBody, $setting->appSecret->value);
            $requestBody['sign'] = $sign;

            $requestBody['firstName'] = $user->firstname;
            $requestBody['lastName'] = $user->lastname;
            $requestBody['email'] = $user->email;
            $requestBody['mobile'] = $user->mobile;
            $requestBody['paymentType'] = 1;
            $requestBody['notifyUrl'] = URL::route('ipn.otpay') . '';
            $requestBody['callbackUrl'] = URL::route('ipn.otpay') . '';
			
            // Send Curl Request
			$sendRequest = $this->curlRequest('POST', 'api/order/submit', $requestBody);
			
            // Exception
            if ($sendRequest instanceof \Exception) throw new \Exception(@$sendRequest['error']);
			
            // Check if successful
            if ($sendRequest['code'] != 0) throw new \Exception($sendRequest['error']);

            // Format Response
			$response = ResponseBankUtilDepositServices::response(200, 2, true, $reference, $sendRequest['data']['orderId'], $currency, $amount, $method, $sendRequest['data']['h5Url']);

            // Response
            return $response;
        } catch (\Exception $th) {
            //throw $th;
            return $th;
        }
    }

    /**
     * Verify Payment
     * 
     * @param string reference
     * @param string method
     */
    public function verify(
        string $reference,
        string $method,
        string $orderID
) {
        try {
			
            // Find Setting
            $setting = Gateway::where(['code' => '104', 'status' => 1])->first();

            // Exception
            if(!$setting) throw new \Exception("Service not enabled at the moment");

            // Parse setting
            $setting = json_decode($setting->gateway_parameters);

            // Request Body
            $requestBody = array(
                "merchantId" => intval($setting->merchantId->value),
                "merchantOrderId" => $reference
            );

            // Build Sign
            $sign = self::buildSignDigest($requestBody, $setting->appSecret->value);
            $requestBody['sign'] = $sign;

            // Send Curl Request
            $sendRequest = $this->getRequest('api/order/status', $requestBody);

            // Exception
            if ($sendRequest instanceof \Exception) throw new \Exception($sendRequest->getMessage());

            // Response
            return $sendRequest;
        } catch (\Exception $th) {
            return $th;
        }
    }


    /**
     * Get Account Balance
     * 
     * @param Void
     */
    public function balance() {
        try {

            // Find Setting
            $setting = Gateway::where(['code' => '104', 'status' => 1])->first();

            // Exception
            if(!$setting) throw new \Exception("Service not enabled at the moment");

            // Parse setting
            $setting = json_decode($setting->gateway_parameters);

            // Request Body
            $requestBody = array(
                "merchantId" => intval($setting->merchantId->value),
            );

            // Build Sign
            $sign = self::buildSignDigest($requestBody, $setting->appSecret->value);
            $requestBody['sign'] = $sign;

            // Send Curl Request
            $sendRequest = $this->curlRequest('POST', 'api/payout/balance/query', $requestBody);

            // Exception
            if ($sendRequest instanceof \Exception) throw new \Exception($sendRequest->getMessage());

            // Response
            return $sendRequest;
        } catch (\Exception $th) {
            return $th;
        }
    }
	
	
	public function getRequest(string $endpoint,array $body = [])
	{
		
        try {
		
			$header = array(
				'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
			);
			
			$url = 'https://pay.otpay.io/' . $endpoint . '?' . http_build_query($body);
			
			
            $curl = curl_init();
            curl_setopt_array($curl, array(
                CURLOPT_URL => $url,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => '',
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 60,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => 'GET',
                CURLOPT_HTTPHEADER => array(
                    'Content-Type: application/x-www-form-urlencoded;charset=utf-8'
                ),
            ));

            $response = curl_exec($curl);
            $err = curl_error($curl);
            $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

            // there was an error contacting
            if ($err) throw new \Exception('Curl returned error: ' . $err);

            // Convert Json to Json Array
            $response_array = json_decode($response, true);
			
            // Check status
            if (!in_array($httpcode, ['200'])) throw new \Exception('Error getting response');

            return $response_array;
        } catch (\Exception $th) {
            //throw $th;
            return $th;
        }		
		
	}
	
    /**
     * Cur Request
     * send request
     * 
     * @param string method
     * @param string endpoint
     * @param string body
     */
    public function curlRequest(string $method,string $endpoint,array $body = []) {

        try {

            // Convert request data to JSON
            $jsonData = json_encode($body);

            // Curl Request
            $curl = curl_init();
            curl_setopt_array($curl, array(
                CURLOPT_URL => 'https://pay.otpay.io/' . $endpoint,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => '',
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 60,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => $method,
                CURLOPT_POSTFIELDS => $jsonData,
                CURLOPT_HTTPHEADER => array(
                    'Content-Type: application/json',
				    'Content-Length: ' . strlen($jsonData)
                ),
            ));

            $response = curl_exec($curl);
            $err = curl_error($curl);
            $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
			

            // there was an error contacting
            if ($err) throw new \Exception('Curl returned error: ' . $err);

            // Convert Json to Json Array
            $response_array = json_decode($response, true);
			
            // Check status
            if (!in_array($httpcode, ['200'])) throw new \Exception(@$response_array['error']);

            return $response_array;
        } catch (\Exception $th) {
            //throw $th;
            return $th;
        }
    }


    public static function buildSignDigest($data, $secret_key)
    {
        // Concatenate the string in the format key=value&key=value
        $signString = '';
        foreach ($data as $key => $value) {
            if (!empty($value)) {
                $signString .= $key . '=' . $value . '&';
            }
        }

        // Append the private key to the string
        $signString .= 'appSecret=' . $secret_key;

        // Perform MD5 signature on the generated string
        $sign = md5($signString);

        return $sign;
    }
}
