<?php
require __DIR__ . '/config.php';

use PayPal\Api\Webhook;
use PayPal\Api\WebhookEventType;
use PayPal\Api\PayoutSenderBatchHeader;
use PayPal\Api\PayoutItem;
use PayPal\Api\Currency;
use PayPal\Api\Payout;

$order_class = new WPJ_Orders();

// Initiate the payment
if ( isset ( $paypal_payout_requests_info ) ) {

	// Create endpoint
	$webhook = new Webhook();

	if ( ( ! $webhook->getUrl() || strpos( $webhook->getUrl(), 'payout_response=paypal' ) === false ) && is_ssl() ) {
		$webhook->setUrl( get_bloginfo( 'url' ) . "/?payout_response=paypal&payment_type_name=withdraw&action=notify" );
		$webhookEventTypes = array();
		$webhookEventTypes[] = new WebhookEventType( '{ "name":"*" }' );
		$webhook->setEventTypes( $webhookEventTypes );

		try {
			$output = $webhook->create( $apiContext );

		} catch ( Exception $ex ) {
			$err_data = wpj_json_decode( $ex->getData(), true );
			if ( isset( $err_data['name'] ) && $err_data['name'] != 'WEBHOOK_URL_ALREADY_EXISTS' ) {
				$paypal_error[] = $err_data['message'];
			} elseif ( isset( $err_data['error'] ) ) {
				$paypal_error[] = $err_data['error'];
			}

		}
	}

	if ( $webhook->getUrl() && ! isset( $paypal_error ) ) {

		foreach ( $paypal_payout_requests_info as $paypal_payout_info ) {
			$senderBatchHeader = new PayoutSenderBatchHeader();
			$senderBatchHeader->setSenderBatchId( uniqid() )->setEmailSubject( "You have a payout!" );

			// Sender Item
			$senderItem = new PayoutItem();
			$senderItem->setRecipientType( 'EMAIL' )
				->setNote( 'Thanks for your patronage!' )
				->setReceiver( $paypal_payout_info['email'] )
				->setSenderItemId( $paypal_payout_info['uniqueid'] )
				->setAmount( new Currency( '{"value":"' . number_format( $paypal_payout_info['amount'], 2 ) . '", "currency":"' . $currency . '"}' ) );

			$payouts = new Payout();
			$payouts->setSenderBatchHeader( $senderBatchHeader )
				->addItem( $senderItem );

			// Create Payout
			try {
				$output = $payouts->create( '', $apiContext );
				$output_arr[$paypal_payout_info['uniqueid']] = wpj_json_decode( $output );
			} catch ( Exception $ex ) {
				$err_data = wpj_json_decode( $ex->getData(), true );

				$payout_err = '<br>';
				if ( isset( $err_data['name'] ) ) {
					$payout_err .= 'Name: ' . $err_data['name'] . '<br>';
				}

				if ( isset( $err_data['error_description'] ) ) {
					$payout_err .= 'Description: ' . $err_data['error_description'] . '<br>';
				}

				if ( isset( $err_data['message'] ) ) {
					$payout_err .= 'Message: ' . $err_data['message'] . '<br>';
				}

				if ( isset( $err_data['details'] ) ) {
					if ( is_array( $err_data['details'] ) ) {
						foreach ( $err_data['details'] as $key => $value ) {
							$payout_err .= 'Detail # ' . ( $key + 1 ) . ': ' . $value['issue'] . '<br>';
						}
					}
				}

				$paypal_error[] = $payout_err;
			}
		}

	} else {

		if ( ! $webhook->getUrl() ) {
			if ( is_ssl() ) {
				$paypal_error[] = 'Something went wrong and we couldn\'t set the Webhook URL. Please set manually by accessing https://developer.paypal.com/developer/applications, select you application, Add Webhook for "All Events" and set the following Webhook Url: ' . get_bloginfo( 'url' ) . '/?payout_response=paypal&payment_type_name=withdraw&action=notify';

			} else {
				$paypal_error[] = 'In order to be able to use the Automatic Withdrawal PayPal system, you must have the https instead of http.';

			}
		}

	}

	if ( isset( $output_arr ) ) {
		foreach ( $output_arr as $item_id => $output_msg ) {
			$payouts_arr         = $payouts->get( $output_msg->batch_header->payout_batch_id, $apiContext );
			$payouts_arr_decoded = wpj_json_decode( $payouts_arr );

			if ( strtolower( $output_msg->batch_header->batch_status ) == 'pending' || strtolower( $output_msg->batch_header->batch_status ) == 'processing' ) {
				if ( strtolower( $payouts_arr_decoded->batch_header->batch_status ) == 'success' ) {
					$order_class->acceptWithdrawalRequest( $payouts_arr_decoded->items[0]->payout_item->sender_item_id );

					echo '<div class="notice notice-success is-dismissible"><p>' . sprintf( __( 'Payment completed for %s!', 'wpjobster' ), $payouts_arr_decoded->items[0]->payout_item->receiver ) . '</p></div>';

				} else {
					wpj_update_withdrawal_order( ['done' => '-2'], ['id' => $payouts_arr_decoded->items[0]->payout_item->sender_item_id] );

					echo '<div class="notice notice-success is-dismissible"><p>' . sprintf( __( 'Payment is being processed for %s! We sent your request to PayPal. As soon as we receive the confirmation, the order will be marked as complete.', 'wpjobster' ), $payouts_arr_decoded->items[0]->payout_item->receiver ) . '</p></div>';

				}

			} elseif ( strtolower( $output_msg->batch_header->batch_status ) == 'success' ) {
				$order_class->acceptWithdrawalRequest( $payouts_arr_decoded->items[0]->payout_item->sender_item_id );

				echo '<div class="notice notice-success is-dismissible"><p>' . sprintf( __( 'Payment completed for %s!', 'wpjobster' ), $payouts_arr_decoded->items[0]->payout_item->receiver ) . '</p></div>';

			} elseif ( strtolower( $output_msg->batch_header->batch_status ) == 'denied' || strtolower( $output_msg->batch_header->batch_status ) == 'canceled' ) {
				wpj_update_withdrawal_order( ['done' => '0'], ['id' => $payouts_arr_decoded->items[0]->payout_item->sender_item_id] );

				echo '<div class="notice notice-success is-dismissible"><p>' . sprintf( __( 'Payment denied for %s!', 'wpjobster' ), $payouts_arr_decoded->items[0]->payout_item->receiver ) . '</p></div>';

			}
		}
	}

	if ( isset( $paypal_error ) ) {
		foreach ( $paypal_error as $item_id => $paypal_errormessage ) {
			$row = wpj_get_withdrawal_order( 'payeremail', ['id' => $item_id], 'row' );

			echo '<div class="notice notice-error is-dismissible">';

				if ( $row ) {
					echo '<p>' . sprintf( __( 'Error for paypal email %s: %s', 'wpjobster' ), $row->payeremail, $paypal_errormessage ) . '</p>';

				} else {
					echo '<p>' . sprintf( __( 'ERROR: %s', 'wpjobster' ), $paypal_errormessage ) . '</p>';

				}

			echo '</div>';
		}
	}

}

// Complete the payment
$method       = WPJ_Form::get( 'payout_response' );
$payment_type = WPJ_Form::get( 'payment_type_name' );
$action       = WPJ_Form::get( 'action' );
if ( ! empty( $method ) && ! empty( $payment_type ) && ! empty( $action ) ) {
	$response         = file_get_contents( 'php://input' );
	$response_decoded = wpj_json_decode( $response );

	// Mark as completed
	if ( $response_decoded->event_type == 'PAYMENT.PAYOUTS-ITEM.SUCCEEDED' || $response_decoded->event_type == 'PAYMENT.PAYOUTSBATCH.SUCCESS' ) {
		if ( isset( $response_decoded->resource->payout_item->sender_item_id ) )
			$order_class->acceptWithdrawalRequest( $response_decoded->resource->payout_item->sender_item_id );

	} elseif (
		$response_decoded->event_type == 'PAYMENT.PAYOUTSBATCH.DENIED'
		|| $response_decoded->event_type == 'PAYMENT.PAYOUTS-ITEM.DENIED'
		|| $response_decoded->event_type == 'PAYMENT.PAYOUTS-ITEM.CANCELED'
		|| $response_decoded->event_type == 'PAYMENT.PAYOUTS-ITEM.FAILED'
		|| $response_decoded->event_type == 'PAYMENT.PAYOUTS-ITEM.UNCLAIMED'
	) {
		wpj_update_withdrawal_order( ['done' => '0'], ['id' => $response_decoded->resource->payout_item->sender_item_id] );

	}

	// Keep responses to database
	$webhook_id  = $response_decoded->id;
	$create_time = strtotime( $response_decoded->create_time );
	$type        = $response_decoded->event_type;
	$description = $response_decoded->summary;
	$order_id    = '';

	if ( $response_decoded->resource_type == 'payouts' ) {
		$payment_id      = $response_decoded->resource->batch_header->payout_batch_id;
		$status          = $response_decoded->resource->batch_header->batch_status;
		$amount          = $response_decoded->resource->batch_header->amount->value;
		$amount_currency = $response_decoded->resource->batch_header->amount->currency;
		$fees            = $response_decoded->resource->batch_header->fees->value;
		$fees_currency   = $response_decoded->resource->batch_header->fees->currency;
		$payment_type    = 'withdrawal';

	} else {
		$payment_id      = $response_decoded->resource->payout_batch_id;
		$status          = $response_decoded->resource->transaction_status;
		$amount          = $response_decoded->resource->payout_item->amount->value;
		$amount_currency = $response_decoded->resource->payout_item->amount->currency;
		$fees            = $response_decoded->resource->payout_item_fee->value;
		$fees_currency   = $response_decoded->resource->payout_item_fee->currency;
		$order_id        = $response_decoded->resource->payout_item->sender_item_id;
		$payment_type    = 'withdrawal';

	}

	if ( $order_id )
		wpj_update_webhook( ['order_id' => $order_id], ['payment_id' => $payment_id] );

	wpj_save_webhook( array(
		'webhook_id'       => $webhook_id,
		'payment_id'       => $payment_id,
		'status'           => $status,
		'type'             => $type,
		'description'      => $description,
		'amount'           => $amount,
		'amount_currency'  => $amount_currency,
		'fees'             => $fees,
		'fees_currency'    => $fees_currency,
		'create_time'      => $create_time,
		'payment_response' => $response,
		'payment_type'     => $payment_type,
		'order_id'         => $order_id
	) );

}