<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit ; // Exit if accessed directly
}

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php' ;

ComposerAutoloaderInit7a93031aedce0fe3fa1cfa18bf1045f6::getLoader() ;

use \PayPal\Api\PayoutSenderBatchHeader ;
use \PayPal\Api\Payout ;
use \PayPal\Api\PayoutItem ;
use \PayPal\Auth\OAuthTokenCredential ;
use \PayPal\Rest\ApiContext ;

/**
 * Handle PayPal Payouts API
 * 
 * @class FS_Affiliates_PayPal_Payouts
 * @category Class
 */
class FS_Affiliates_PayPal_Payouts {

	protected $environment = 'sandbox' ;
	protected $sender_batch_id ;
	protected $receivers ;
	protected $currency ;
	protected $email_subject ;
	protected $item_note ;
	/*
	 * Plugin slug
	 */
	protected $plugin_slug = 'fs_affiliates' ;

	public function __construct( $args ) {
		$args = wp_parse_args( $args , array (
			'sender_batch_id' => uniqid() ,
			'receivers'       => array () ,
			'currency'        => 'USD' ,
			'email_subject'   => __( 'You have a payout!' , FS_AFFILIATES_LOCALE ) ,
			'item_note'       => __( 'Thanks for your patronage!' , FS_AFFILIATES_LOCALE ) ,
				) ) ;

		foreach ( $args as $prop => $value ) {
			$this->{$prop} = $value ;
		}
	}

	public function get_credentials() {
		$this->environment = 'yes' === get_option( $this->plugin_slug . '_paypal_payouts_mode' , 'no' ) ? 'sandbox' : 'live' ;

		$client_id  = get_option( $this->plugin_slug . '_paypal_payouts_live_client_id' ) ;
		$secret_key = get_option( $this->plugin_slug . '_paypal_payouts__live_client_key' ) ;

		if ( 'sandbox' === $this->environment ) {
			$client_id  = get_option( $this->plugin_slug . '_paypal_payouts_sandbox_client_id' ) ;
			$secret_key = get_option( $this->plugin_slug . '_paypal_payouts_sandbox_client_key' ) ;
		}

		return array (
			'client_id'  => $client_id ,
			'secret_key' => $secret_key ,
				) ;
	}

	public function getApiContext() {
		$credentials          = $this->get_credentials() ;
		$oAuthTokenCredential = new OAuthTokenCredential( $credentials[ 'client_id' ] , $credentials[ 'secret_key' ] ) ;

		return new ApiContext( $oAuthTokenCredential ) ;
	}

	public function getPayoutItems() {
		$items = array () ;

		foreach ( $this->receivers as $affiliate_id => $amount ) {
			$items[] = new PayoutItem( array (
				'recipient_type' => 'EMAIL' ,
				'receiver'       => get_post_meta( $affiliate_id , 'payment_email' , true ) ,
				'note'           => $this->item_note ,
				'sender_item_id' => uniqid() ,
				'amount'         => array (
					'value'    => $amount ,
					'currency' => $this->currency ,
				) ,
					) ) ;
		}
		return $items ;
	}

	public function getPayoutBatchStatus( $payout_batch_id ) {

		try {
			$this->setEnvironment( $this->getApiContext() ) ;
			$payoutBatchStatus = Payout::get( $payout_batch_id , $this->getApiContext() ) ;
		} catch ( Exception $e ) {
			return $e->getMessage() ;
		}
		return $payoutBatchStatus ;
	}

	public function getPayoutItemStatus( $payoutItemId ) {

		try {
			$this->setEnvironment( $this->getApiContext() ) ;
			$payoutItemStatus = PayoutItem::get( $payoutItemId , $this->getApiContext() ) ;
		} catch ( Exception $e ) {
			return $e->getMessage() ;
		}
		return $payoutItemStatus ;
	}

	public function setEnvironment( $apiContext ) {

		$apiContext->setConfig(
				array (
					'mode'             => $this->environment ,
					'log.LogEnabled'   => true ,
					'log.FileName'     => '../PayPal.log' ,
					'log.LogLevel'     => 'sandbox' === $this->environment ? 'DEBUG' : 'FINE' ,
					'validation.level' => 'log' ,
					'cache.enabled'    => true ,
				)
		) ;
	}

	public function createBatchPayout() {

		$senderBatchHeader = new PayoutSenderBatchHeader() ;
		$senderBatchHeader->setSenderBatchId( $this->sender_batch_id ) ;
		$senderBatchHeader->setEmailSubject( $this->email_subject ) ;

		$payout = new Payout() ;
		$payout->setSenderBatchHeader( $senderBatchHeader ) ;

		$items = $this->getPayoutItems() ;

		foreach ( $items as $item ) {
			$payout->addItem( $item ) ;
		}

		try {
			$this->setEnvironment( $this->getApiContext() ) ;
			$_payout = $payout->create( array (
				'sync_mode' => 'false' ,
					) , $this->getApiContext() ) ;
		} catch ( Exception $e ) {
			return $e->getMessage() ;
		}
		return $_payout ;
	}

	public function processPayout( $payout_batch_id ) {

		$PayoutBatchStatus = $this->getPayoutBatchStatus( $payout_batch_id ) ;

		if ( isset( $PayoutBatchStatus->batch_header->payout_batch_id ) ) {
			if ( doing_action( 'save_post' ) ) {
				$GLOBALS[ 'wpdb' ]->update( $GLOBALS[ 'wpdb' ]->posts , array ( 'post_status' => 'fs_' . strtolower( $PayoutBatchStatus->batch_header->batch_status ) ) , array ( 'ID' => $this->sender_batch_id ) ) ;
				clean_post_cache( $this->sender_batch_id ) ;
			} else {
				wp_update_post( array_merge( array ( 'ID' => $this->sender_batch_id ) , array ( 'post_status' => 'fs_' . strtolower( $PayoutBatchStatus->batch_header->batch_status ) ) ) ) ;
			}

			update_post_meta( $this->sender_batch_id , '_payout_batch_header' , array (
				'payout_batch_id'     => $PayoutBatchStatus->batch_header->payout_batch_id ,
				'batch_status'        => $PayoutBatchStatus->batch_header->batch_status ,
				'time_created'        => $PayoutBatchStatus->batch_header->time_created ,
				'time_completed'      => isset( $PayoutBatchStatus->batch_header->time_completed ) ? $PayoutBatchStatus->batch_header->time_completed : '' ,
				'payout_batch_amount' => array (
					'currency' => $PayoutBatchStatus->batch_header->amount->currency ,
					'value'    => $PayoutBatchStatus->batch_header->amount->value ,
				) ,
				'payout_batch_fee'    => array (
					'currency' => $PayoutBatchStatus->batch_header->fees->currency ,
					'value'    => $PayoutBatchStatus->batch_header->fees->value ,
				) ,
				'email_subject'       => $PayoutBatchStatus->batch_header->sender_batch_header->email_subject ,
			) ) ;

			$payout_items = array () ;
			foreach ( $PayoutBatchStatus->items as $item ) {
				$payout_items[ $item->payout_item->receiver ] = array (
					'payout_item_id'     => $item->payout_item_id ,
					'sender_item_id'     => $item->payout_item->sender_item_id ,
					'transaction_status' => $item->transaction_status ,
					'payout_item_fee'    => array (
						'currency' => $item->payout_item_fee->currency ,
						'value'    => $item->payout_item_fee->value ,
					) ,
					'payout_item_amount' => array (
						'currency' => $item->payout_item->amount->currency ,
						'value'    => $item->payout_item->amount->value ,
					) ,
					'note'               => $item->payout_item->note ,
						) ;
			}
			update_post_meta( $this->sender_batch_id , '_payout_batch_items' , $payout_items ) ;
		}
		return $PayoutBatchStatus ;
	}

}
