<?php
require_once("class.setting.php");
class Pesapal
{
    /////
    private $helper;
    /////////
    private $restapi;
    ////
    public $settings;
    ////////
    public $utils;
    public $setting;
    private $dbUtils;

    public function __construct($auth, $restapi = null)
    {
        $company = $auth["company"];
        extract($company);
        ///////////////////////////////////////////
        $this->restapi = $restapi;
        $this->utils = new Utils();
        /////////////////////////////////////////////
        $this->dbUtils = new DBUtils($db_name);
        $this->setting = new Setting($restapi, $db_name);
        $this->settings = $this->setting->getSettings($id);
        /////////////////////////////////////////
        if (!$this->dbUtils->isDBInService()) {
            die($this->restapi->Response(["message" => "Failed to connect to the database, please try again laiter", "success" => false], 500));
        }
        /////////////////////////////////////////
    }

    ###########################################
    public function saveTransation($data)
    {
        ############################################
        // SETTINGS 
        $settings = $this->settings;
        $response = new stdClass;
        $trx_id = "KRB" . $this->utils->getRandom();
        $trx_amount = $data->trx_amount;
        $email_address = $data->email_address;
        $phone_number = $data->phone_number;
        $country_code = $data->country_code;
        $first_name = $data->first_name;
        $last_name = $data->last_name;
        $line_1 = $data->line_1;
        $line_2 = $data->line_2;
        $city = $data->city;
        $state = $data->state;
        $postal_code = $data->postal_code;
        $zip_code = $data->zip_code;
        $description = $data->description;
        $hotel_name = $data->hotel_name;
        $period = $data->period;
        $package = $data->package;
        $noofpos = intval($data->noofpos);
        $installation_type = $data->installation_type;
        $remote_access = $data->remote_access ? true : false;
        /// settings
        $currency = $settings["PESAPAL_CURRENCY"]["entry_value"];
        $notification_id = $settings["PESAPAL_IPN_ID"]["entry_value"];
        ///////////////////////////
        $mtoken = $this->getToken();
        // print_r($mtoken);
        if ($mtoken->token == null) {
            $response->message = "Failed to obtain request token, please try again laiter";
            $response->success = false;
            return $response;
        } else {
            $ndata = json_decode(json_encode($data), true);
            $submit_request = $this->SubmitOrderRequest($ndata, $mtoken->token["token"], $trx_id);
            if ($submit_request == null) {
                $response->message = "Failed to submit payment request, please try again laiter";
                $response->success = false;
                return $response;
            } else {
                // echo json_encode($submit_request);
                if ($submit_request->status != 200) {
                    $response->message = $submit_request->error->message;
                    $response->success = false;
                    return $response;
                } else {
                    $order_tracking_id = $submit_request->order_tracking_id;
                    ###################################
                    $sql = "INSERT INTO karibu_pesapal_transactions(
                        `trx_id`,
                        `trx_amount`,
                        `notification_id`,
                        `email_address`,
                        `phone_number`, 
                        `country_code`, 
                        `order_tracking_id`,
                        `first_name`, 
                        `last_name`,
                        `line_1`, 
                        `line_2`, 
                        `city`, 
                        `state`, 
                        `postal_code`,
                        `zip_code`, 
                        `description`, 
                        `currency_code`,
                        `trx_status`, 
                        `hotel_name`,
                        `period`, 
                        `package`, 
                        `noofpos`, 
                        `installation_type`, 
                        `remote_access`)
                        VALUES (
                        '$trx_id',
                        '$trx_amount',
                        '$notification_id',
                        '$email_address',
                        '$phone_number',
                        '$country_code', 
                        '$order_tracking_id',
                        '$first_name',
                        '$last_name',
                        '$line_1',
                        '$line_2',
                        '$city',
                        '$state',
                        '$postal_code',
                        '$zip_code', 
                        '$description',
                        '$currency',
                        'PENDING', 
                        '$hotel_name',
                        '$period',
                        '$package',
                        '$noofpos', 
                        '$installation_type',
                        '$remote_access')";
                    /////////////////
                    $stmt = $this->dbUtils->runQuery($sql);
                    //////////////////////////////////////////
                    if ($stmt->execute()) {
                        $response = $submit_request;
                        $response->message = "Transaction initiated";
                        $response->success = true;
                    } else {
                        $response->message = "Something went wrong, please try again laiter";
                        $response->success = false;
                    }
                }
            }
        }
        return $response;
    }

    public function UpdateTransation($orderTrackingId)
    {
        $response = new stdClass;
        $trx_status = $this->getTrxStatus($orderTrackingId);
        if ($trx_status != null) {
            $payment_status_description = $trx_status->payment_status_description;
            $merchant_reference = $trx_status->merchant_reference;
            $sql =  "UPDATE karibu_pesapal_transactions SET trx_status='$payment_status_description' WHERE trx_id='$merchant_reference'";
            $stmt = $this->dbUtils->runQuery($sql);
            if ($stmt->execute()) {
                $response->message = "Transaction updated";
                $response->success = true;
            } else {
                $response->message = "Something went wrong, please try again laiter";
                $response->success = false;
            }
        } else {
            return false;
        }
    }

    public function getAllTransations()
    {
        $stmt = $this->dbUtils->runQuery("SELECT * FROM karibu_pesapal_transactions ORDER BY id DESC LIMIT 20");
        $stmt->execute();
        $counter = $stmt->rowCount();
        $rows = $stmt->fetch(PDO::FETCH_ASSOC);
        return $rows;
    }

    public function getTransactionById($trx_id)
    {
        $stmt = $this->dbUtils->runQuery("SELECT * FROM karibu_pesapal_transactions WHERE trx_id = '$trx_id'");
        $stmt->execute();
        $counter = $stmt->rowCount();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row;
    }

    public function getToken()
    {
        $response = new stdClass;
        $settings = $this->settings;
        $params = array("consumer_key" => $settings["PESAPAL_CONSUMER_KEY"]["entry_value"], "consumer_secret" => $settings["PESAPAL_CONSUMER_SECRET"]["entry_value"]);
        $token = $this->restapi->execPostRequest($settings["PESAPAL_API_URL"]["entry_value"] . "/Auth/RequestToken", json_encode(($params)));
        $response->message = "";
        $response->token = $token;
        $response->success = true;
        return $response;
    }

    public function SubmitOrderRequest($data, $token, $trx_id)
    {
        extract($data);
        $settings = $this->settings;
        ///////////////////// Settings
        $currency = $settings["PESAPAL_CURRENCY"]["entry_value"];
        $ipn_id = $settings["PESAPAL_IPN_ID"]["entry_value"];
        $callback_url = $settings["PESAPAL_CALLBACK_URL"]["entry_value"];
        ///////////////////////////////////////////////////////////
        $params = '{
                    "id": "' . $trx_id . '",
                    "currency": "' . $currency . '",
                    "amount": ' . floatval($trx_amount) . ',
                    "description": "' . $description . '",
                    "callback_url": "' . $callback_url . '?reference=' . $trx_id . '",
                    "notification_id": "' . $ipn_id . '",
                    "billing_address": {
                        "email_address": "' . $email_address . '",
                        "phone_number": "' . $phone_number . '",
                        "country_code": "' . $country_code . '",
                        "first_name": "' . $first_name . '",
                        "middle_name": "",
                        "last_name": "' . $last_name . '",
                        "line_1": "' . $line_1 . '",
                        "line_2": "' . $line_2 . '",
                        "city": "' . $city . '",
                        "state": "' . $state . '",
                        "postal_code": "' . $postal_code . '",
                        "zip_code": "' . $zip_code . '"
                    }
                }';
        ////////////////
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $settings["PESAPAL_API_URL"]["entry_value"] . '/Transactions/SubmitOrderRequest',
            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 => $params,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json',
                'Authorization: Bearer ' . $token
            ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return json_decode($response);
    }
    ////////////////////////////////////////////////////
    public function registerIPN($IPN_URL, $token)
    {
        $settings = $this->settings;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $settings["PESAPAL_API_URL"]["entry_value"]   . '/URLSetup/RegisterIPN',
            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 => '{
            "url": "' . $IPN_URL . '",
                "ipn_notification_type": "GET"
            }',
            CURLOPT_HTTPHEADER => array(
                'Accept: application/json',
                'Content-Type: application/json',
                'Authorization: Bearer ' . $token
            ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }

    public function getTrxStatus($orderTrackingId)
    {
        $settings =  $this->settings;
        $mtoken = $this->getToken();
        // print_r($mtoken);
        if ($mtoken->token == null) {
            return null;
        } else {
            $token = $mtoken->token["token"];
            $curl = curl_init();
            curl_setopt_array($curl, array(
                CURLOPT_URL => $settings["PESAPAL_API_URL"]["entry_value"] . '/Transactions/GetTransactionStatus?orderTrackingId=' . $orderTrackingId,
                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(
                    'Accept: application/json',
                    'Content-Type: application/json',
                    'Authorization: Bearer ' . $token
                ),
            ));
            $response = curl_exec($curl);
            curl_close($curl);
            return json_decode($response);
        }
    }
}
