<?php
defined('BASEPATH') OR exit('No direct script access allowed');

include APPPATH.'third_party/Braintree/Braintree.php';

/*
 *  Braintree_lib
 *	Braintree PHP SDK v3.*
 *  For Codeigniter 3.*
 */

class Braintree_lib {

	function __construct() {
        $CI = &get_instance();
        $this->CI = &get_instance();
		$CI->config->load('braintree', TRUE);
		$braintree = $CI->config->item('braintree');
        $this->CI->load->model('PBReusableModel_Errors','errors');
        $this->CI->load->model('PBReusableModel_Global','global');
        $this->CI->load->model('PBReusableModel_User','users');
		Braintree_Configuration::environment($braintree['braintree_environment']);
		Braintree_Configuration::merchantId($braintree['braintree_merchant_id']);
		Braintree_Configuration::publicKey($braintree['braintree_public_key']);
		Braintree_Configuration::privateKey($braintree['braintree_private_key']);

        // $token = 'access_token$production$s979wjdn9j6xts5t$ed88d2030f682553523e8f5f858a383e'; // Production (TAW)
        // type$environment$merchant_id$token
        // $token = 'access_token$sandbox$fgjwzqcswq52t4s9$56274d508348744662cad49326959a15'; // Sandbox (PixelBeard)
        // $token = 'access_token$sandbox$2xx4kytt4pjt9q7f$x6mxm269_2xx4kytt4pjt9q7f'; // Sandbox (PixelBeard)
		$this->gateway = new Braintree_Gateway([
            'environment' => 'sandbox',
            'merchantId' => '2xx4kytt4pjt9q7f',
            'publicKey' => 'yrrccvrnn9wkkkhs',
            'privateKey' => '3fc714565a721aa7ef194dc1bb87fc6a'
		]);
	}

    // *******************************************************
    // SUBSCRIPTIONS
    // *******************************************************

	function getAllPlansNoUserData() {
        // getUserSubscriptionsForAMember
        $plans = $this->gateway->plan()->all();
        if(!$plans) {
            $plans_response = array();
            $plans_response['success'] = true;
            $plans_response['message'] = 'No plans to retrieve.';
            $plans_response['subscriptions'] = array();
            return $plans_response;
        } else {
            $plans_response = array();
            $plans_response['success'] = true;
            $plans_response['message'] = 'Successfully retrieved the subscription plans.';
            $plans_array = array();
            foreach($plans as $plan) {
                $plan_array = array();
                $plan_array['id'] = $plan->id;
                if($plan->id == 7) {
                    $plan_array['audio'] = true;
                    $plan_array['video'] = false;
                } else if ($plan->id == 8) {
                    $plan_array['audio'] = false;
                    $plan_array['video'] = true;
                }
                else if ($plan->id == 9) {
                   $plan_array['audio'] = true;
                   $plan_array['video'] = true;
               }
                $plan_array['description'] = $plan->description;
                $plan_array['name'] = $plan->name;
                $plan_array['price'] = $plan->price;
                array_push($plans_array,$plan_array);
            }
            $sorted_array = $this->CI->global->sortArrayByKey($plans_array,'id',SORT_ASC);
            $plans_response['subscriptions'] = $sorted_array;
            return $plans_response;
        }
    }

    function getAllPlans() {

       
        $this->headers = $this->CI->input->request_headers();

        // $user = $this->CI->users->getFullUserByTokenFrontend($this->headers['User-Api-Token']);
        $user = $this->CI->users->getFullUserByTokenFrontend('06072b0536fda3846569d8ce07e09456');
        $user = $this->CI->users->getUserObject($user['email']);

        // getUserSubscriptionsForAMember
        $plans = $this->gateway->plan()->all();
        if(!$plans) {
            $plans_response = array();
            $plans_response['success'] = true;
            $plans_response['message'] = 'No plans to retrieve.';
            $plans_response['subscriptions'] = array();
            return $plans_response;
        } else {
            $plans_response = array();
            $plans_response['success'] = true;
            $plans_response['message'] = 'Successfully retrieved the subscription plans.';
            $plans_array = array();
            foreach($plans as $plan) {
                $plan_array = array();
                $plan_array['id'] = $plan->id;
                if($user['subscriptions']) {
                    if($plan->id == $user['subscriptions'][0]['subscription_auth_level']) {
                        $plan_array['current_plan'] = true;
                    } else {
                        $plan_array['current_plan'] = false;
                    }
                } else {
                    $plan_array['current_plan'] = false;
                }
                $plan_array['description'] = $plan->description;
                $plan_array['name'] = $plan->name;
                $plan_array['price'] = $plan->price;
                array_push($plans_array,$plan_array);
            }
            $sorted_array = $this->CI->global->sortArrayByKey($plans_array,'id',SORT_ASC);
            $plans_response['user'] = $user;
            $plans_response['subscriptions'] = $sorted_array;
            return $plans_response;
        }
    }

    // *******************************************************
    // CUSTOMERS
    // *******************************************************

    function api_create_customer($customer) {
        $result = $this->gateway->customer()->create($customer);
		$result->success;
		$result->customer->id;
        return $result;
    }

    function api_find_customer($customer_id) {
        $result = $this->gateway->customer()->find($customer_id);
        return $result;
    }

    function api_update_customer($customer_id,$array) {
        $result = $this->gateway->customer()->update($customer_id,$array);
        return $result;
    }


    function checkout_sub($amount,$nonce) {
        $result = $this->gateway->transaction()->sale([
            'amount' => $amount,
            'paymentMethodNonce' => $nonce,
            'options' => [
                'submitForSettlement' => true,
                'storeInVault' => true,
            ]
        ]);

        var_dump($result);
        if ($result->success || !is_null($result->transaction)) {
            $transaction = $result->transaction;
            echo json_encode(
    			array(
    				'success' => true,
    				'friendly_message' => 'Transaction successful',
    				'debug_message' => 'Everything was awesome!',
    				'transaction' => $transaction
    			)
    		);
            // header("Location: " . base_url() . "transaction.php?id=" . $transaction->id);
        } else {
            $errorString = "";

            foreach($result->errors->deepAll() as $error) {
                $errorString .= 'Error: ' . $error->code . ": " . $error->message . "\n";
            }

            $_SESSION["errors"] = $errorString;
            // header("Location: " . $baseUrl . "index.php");
            echo json_encode(
    			array(
    				'success' => false,
    				'friendly_message' => 'Transaction Failed',
    				'debug_message' => 'Everything was NOT awesome!',
    				'errors' => $_SESSION["errors"]
    			)
    		);
        }
    }

	function createClientToken() {
		echo json_encode(
			array(
				'success' => true,
				'friendly_message' => 'Client token generated',
				'debug_message' => 'Everything was awesome!',
				'token' => $this->gateway->clientToken()->generate([
                    "merchantAccountId" => "2xx4kytt4pjt9q7f",
                ])
			)
		);
	}

	function createNewPaymentMethod() {
		$this->gateway->paymentMethod()->create([
		    'customerId' => '12345',
		    'paymentMethodNonce' => nonceFromTheClient
		]);
	}

    function getJsonData($object){
        $var = get_object_vars($object);
        foreach ($var as &$value) {
            if (is_object($value) && method_exists($value,'getJsonData')) {
                $value = $value->getJsonData();
            }
        }
        return $var;
    }

    function obj2array ( &$Instance ) {
        $clone = (array) $Instance;
        $rtn = array ();
        $rtn['___SOURCE_KEYS_'] = $clone;

        while ( list ($key, $value) = each ($clone) ) {
            $aux = explode ("\0", $key);
            $newkey = $aux[count($aux)-1];
            $rtn[$newkey] = &$rtn['___SOURCE_KEYS_'][$key];
        }

        return $rtn;
    }

    function object_to_array($obj) {
        $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
        foreach ($_arr as $key => $val) {
                $val = (is_array($val) || is_object($val)) ? object_to_array($val) : $val;
                $arr[$key] = $val;
        }
        return $arr;
}

	function createNewCustomer($customer) {
		$result = $this->gateway->customer()->create($customer);
		if(!$result->success) {
            // If errors are found, we exit here!
            $this->CI->errors->processErrorsFromBraintree(
                $result->errors->deepAll(),
                'Failed to create a customer inside the Braintree vault.'
            );
        } else {
            $paypal_accounts = $result->customer->paypalAccounts;
            $paypal_accounts_array = $this->obj2array($paypal_accounts[0]);
            $paypal_accounts_array = $paypal_accounts_array["___SOURCE_KEYS_"];
            $ppa = array();
            foreach($paypal_accounts_array as $account) {
                array_push($ppa,$account);
            }

            $payment_methods = $result->customer->paymentMethods;
            $payment_methods_array = $this->obj2array($payment_methods[0]);
            $payment_methods_array = $payment_methods_array["___SOURCE_KEYS_"];
            $pma = array();
            foreach($payment_methods as $method) {
                $method = $this->obj2array($method);
                $method = $method["___SOURCE_KEYS_"];
                $a = array();
                foreach($method as $param) {
                    array_push($a,$param);
                }
                array_push($pma,$a);
            }

            $created_date = $result->customer->createdAt;
            $created_date_array = $this->obj2array($created_date);
            $created_date_array = $created_date_array["___SOURCE_KEYS_"];
            $cda = array();
            foreach($created_date_array as $date) {
                array_push($cda,$date);
            }

            $updated_date = $result->customer->updatedAt;
            $updated_date_array = $this->obj2array($updated_date);
            $updated_date_array = $updated_date_array["___SOURCE_KEYS_"];
            $uda = array();
            foreach($updated_date_array as $date) {
                array_push($uda,$date);
            }

            $customer_array = array(
                "customer_id" => $result->customer->id,
                "merchant_id" => $result->customer->merchantId,
                "first_name" => $result->customer->firstName,
                "last_name" => $result->customer->lastName,
                "company" => $result->customer->company,
                "email" => $result->customer->email,
                "phone" => $result->customer->phone,
                "fax" => $result->customer->fax,
                "website" => $result->customer->website,
                "created_at" => $cda,
                "updated_at" => $uda,
                "custom_fields" => $result->customer->customFields,
                "global_id" => $result->customer->globalId,
                "credit_cards" => $result->customer->creditCards,
                "addresses" => $result->customer->addresses,
                "coinbase_accounts" => $result->customer->coinbaseAccounts,
                "paypal_accounts" => $ppa,
                "apple_pay_cards" => $result->customer->applePayCards,
                "android_pay_cards" => $result->customer->androidPayCards,
                "amex_express_checkout_cards" => $result->customer->amexExpressCheckoutCards,
                "venmo_accounts" => $result->customer->venmoAccounts,
                "payment_methods" => $pma[0],
            );
            $array = array(
                "success" => $result->success,
                "customer" => $customer_array
            );
    		return json_encode($array,JSON_PRETTY_PRINT);
        }
	}

	function testPurchase($data) {
		// $data = $this->input->post();

		$result = $this->gateway->transaction()->sale([
		    "amount" => $data['amount'],
		    'merchantAccountId' => 'USD',
		    "paymentMethodNonce" => $data['payment_method_nonce'],
		    "orderId" => $data['inv_no'],
		    "descriptor" => [
		      "name" => "Descriptor displayed in customer CC statements. 22 char max"
		    ],
		    "shipping" => [
		      "firstName" => "Jen",
		      "lastName" => "Smith",
		      "company" => "Braintree",
		      "streetAddress" => "1 E 1st St",
		      "extendedAddress" => "Suite 403",
		      "locality" => "Bartlett",
		      "region" => "IL",
		      "postalCode" => "60103",
		      "countryCodeAlpha2" => "US"
		    ],
		    "options" => [
		      "paypal" => [
		        "customField" => "PayPal custom field",
		        "description" => "Description for PayPal email receipt"
		      ],
		    ]
		]);
		if ($result->success) {
		  print_r("Success ID: " . $result->transaction->id);
		} else {
		  print_r("Error Message: " . $result->message);
		}
	}
}
