<?php
/**
 * Class file that handles PayPal payment processing and settings.
 *
 * @since 4.1.5
 * @package rsvp-pro-plugin
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) :
	exit;
endif;

/**
 * Class for handling PayPal payment handling.
 *
 * @since 4.1.5
 */
class Rsvp_Pro_PayPal_Payment_Gateway {

	/**
	 * Creates the RSVP Pro PayPal Payment Gateway object.
	 */
	public function __construct() {
		add_action( 'rsvp_pro_event_payment_settings_tab', array( $this, 'display_paypal_payment_settings' ) );
		add_filter( 'rsvp_pro_event_save_additional_settings', array( $this, 'save' ) );
		add_filter( 'rsvp_pro_frontend_payment_form', array( $this, 'frontend_payment_form' ), 10, 3 );
	}

	/**
	 * Displays the form elements for getting PayPal payments integrated with the RSVP form.
	 *
	 * @param  array $options The options associated with the paypal payments.
	 */
	public function display_paypal_payment_settings( $options ) {
		$event_options = $options['event_options'];
		?>
		<tr class="subEventHide">
			<th scope="row" colspan="2">
				<h3><?php echo rsvp_pro_get_admin_string( 'paypal_form_settings_label' ); ?></h3>
			</th>
		</tr>
		<tr class="subEventHide">
			<th scope="row">
				<label for="paypal_email"><?php echo rsvp_pro_get_admin_string( 'paypal_email_settings_label' ); ?></label>
			</th>
			<td>
				<input type="text" name="paypal_email" id="paypal_email" value="<?php echo esc_attr( stripslashes( $event_options->retrieve_value( 'paypal_email' ) ) ); ?>" />
				<br />
				<span class="description"><?php echo rsvp_pro_get_admin_string( 'paypal_email_settings_description' ); ?></span>
			</td>
		</tr>
		<tr class="subEventHide">
			<th scope="row" colspan="2">
				<h3><?php echo rsvp_pro_get_admin_string( 'paypal_api_credentials_header' ); ?></h3>
			</th>
		</tr>
		<tr class="subEventHide">
			<th scope="row">
				<label for="paypal_live_client_id"><?php echo rsvp_pro_get_admin_string( 'paypal_live_client_id_settings_label' ); ?></label>
			</th>
			<td>
				<input type="text" name="paypal_live_client_id" id="paypal_live_client_id" value="<?php echo esc_attr( stripslashes( $event_options->retrieve_value( 'paypal_live_client_id' ) ) ); ?>" />
				<br />
				<span class="description"><?php echo rsvp_pro_get_admin_string( 'paypal_live_client_id_settings_description' ); ?></span>
			</td>
		</tr>
		<tr class="subEventHide">
			<th scope="row">
				<label for="paypal_live_client_secret"><?php echo rsvp_pro_get_admin_string( 'paypal_live_client_secret_settings_label' ); ?></label>
			</th>
			<td>
				<input type="text" name="paypal_live_client_secret" id="paypal_live_client_secret" value="<?php echo esc_attr( stripslashes( $event_options->retrieve_value( 'paypal_live_client_secret' ) ) ); ?>" />
				<br />
				<span class="description"><?php echo rsvp_pro_get_admin_string( 'paypal_live_client_secret_settings_description' ); ?></span>
			</td>
		</tr>
		<tr class="subEventHide">
			<th scope="row">
				<label for="paypal_sandbox_client_id"><?php echo rsvp_pro_get_admin_string( 'paypal_sandbox_client_id_settings_label' ); ?></label>
			</th>
			<td>
				<input type="text" name="paypal_sandbox_client_id" id="paypal_sandbox_client_id" value="<?php echo esc_attr( stripslashes( $event_options->retrieve_value( 'paypal_sandbox_client_id' ) ) ); ?>" />
				<br />
				<span class="description"><?php echo rsvp_pro_get_admin_string( 'paypal_sandbox_client_id_settings_description' ); ?></span>
			</td>
		</tr>
		<tr class="subEventHide">
			<th scope="row">
				<label for="paypal_sandbox_client_secret"><?php echo rsvp_pro_get_admin_string( 'paypal_sandbox_client_secret_settings_label' ); ?></label>
			</th>
			<td>
				<input type="text" name="paypal_sandbox_client_secret" id="paypal_sandbox_client_secret" value="<?php echo esc_attr( stripslashes( $event_options->retrieve_value( 'paypal_sandbox_client_secret' ) ) ); ?>" />
				<br />
				<span class="description"><?php echo rsvp_pro_get_admin_string( 'paypal_sandbox_client_secret_settings_description' ); ?></span>
			</td>
		</tr>
		<?php
	}

	/**
	 * Records the event totals that the attendee will be charged for.
	 *
	 * @param  Rsvp_Pro_Attendee $attendee       The attendee we want to save the information for.
	 * @param  array             $totals         The array of totals for each individual attendee that will be charged in this transaction.
	 * @param  string            $transaction_id The transaction ID for the paypal processing.
	 */
	private function record_attendee_payments( $attendee, $totals, $transaction_id ) {
		if ( isset( $totals['attendee_totals'][ $attendee->get_id() ] ) ) {
			foreach ( $totals['attendee_totals'][ $attendee->get_id() ] as $key => $value) {
				$event_cost = new Rsvp_Pro_Attendee_Event_Costs();
				$event_cost->set_attendee_id( $attendee->get_id() );
				$event_cost->set_rsvp_event_id( $key );
				$event_cost->set_amount( $value );
				$attendee->add_event_costs( $event_cost );
				if ( $key == $attendee->get_rsvp_event_id() ) {
					$attendee->set_amount( $value );
					$attendee->set_transaction_id( $transaction_id );
					$attendee->set_payment_status( RSVP_PRO_PROCESSING_STATUS );
				} else {
					$event_record = rsvp_pro_get_attendee_event_record( $key, $attendee->get_id() );
					$event_record->set_transaction_id( $transaction_id );
					$event_record->set_payment_status( RSVP_PRO_PROCESSING_STATUS );
					$event_record->set_amount( $value );
					$event_record->save();
				}
			}
		}
		$attendee->save();
	}

	/**
	 * Displays the front-end to pay for the event with PayPal.
	 *
	 * @param  stirng $output    The existing output that we want to add to.
	 * @param  int    $event_id  The main event ID we are wanting to pay for.
	 * @param  int    $attendee_id The main attendee ID we are using to calculate total due.
	 * @return string            The additional output so people can pay with PayPal.
	 */
	public function frontend_payment_form( $output, $event_id, $attendee_id ) {
		ob_start();
		$output = '';
		$event = new Rsvp_Pro_Event_Options( $event_id );

		if ( 'Y' === $event->get_enable_payments() ) {
			$attendee      = new Rsvp_Pro_Attendee( $attendee_id );
			$client_id     = $event->retrieve_value( 'paypal_live_client_id' );
			$client_secret = $event->retrieve_value( 'paypal_live_client_secret' );

			if ( 'Y' === $event->get_payment_testing() ) {
				$client_id     = $event->retrieve_value( 'paypal_sandbox_client_id' );
				$client_secret = $event->retrieve_value( 'paypal_sandbox_client_secret' );
			}

			$api_context = new \PayPal\Rest\ApiContext(
				new \PayPal\Auth\OAuthTokenCredential(
					$client_id,
					$client_secret
				)
			);

			$payer = new \PayPal\Api\Payer();
			$payer->setPaymentMethod( 'paypal' );

			$totals   = rsvp_pro_existing_attendee_calculate_total_due( $event_id, $attendee );
			$currency = $event->get_currency();
			if ( $totals['total']  > 0 ) {
				$amount = new \PayPal\Api\Amount();
				$amount->setTotal( $totals['total'] );
				$amount->setCurrency( $currency );

				$transaction_description = rsvp_pro_get_admin_string( 'transaction_description' );
				if ( '' !== $event->get_payment_description() ) {
					$transaction_description = $event->get_payment_description();
				}
				$transaction_description = sprintf( $transaction_description, rsvp_pro_get_event_name( $event_id ) );

				$transaction = new \PayPal\Api\Transaction();
				$transaction->setAmount( $amount )
					->setDescription( $transaction_description );

				$redirect_urls = new \PayPal\Api\RedirectUrls();
				$success_url   = get_site_url();
				$cancel_url    = get_site_url();

				if ( '' !== $event->get_payment_success_url() ) {
					$success_url = $event->get_payment_success_url();
				}

				if ( '' !== $event->get_payment_failure_url() ) {
					$cancel_url = $event->get_payment_failure_url();
				}
				$redirect_urls->setReturnUrl( $success_url )
					->setCancelUrl( $cancel_url );

				$payment = new \PayPal\Api\Payment();
				$payment->setIntent('sale')
					->setPayer( $payer )
					->setTransactions( array( $transaction ) )
					->setRedirectUrls( $redirect_urls );
				try {
					$payment->create( $api_context );
					$payment->getId();
					// Note - when we add additional payment processors we will want to move these records to a global function.
					// We will still need a way to record the payment processor's token, etc.. though
					$this->record_attendee_payments( $attendee, $totals, $payment->getId() );

					foreach ( $attendee->get_associated_attendees() as $aa ) {
						$assoc = new Rsvp_Pro_Attendee( $aa );
						$this->record_attendee_payments( $assoc, $totals, $payment->getId() );
					}
					?>

					<p><a href="<?php echo $payment->getApprovalLink() ; ?>"><img src="https://www.paypalobjects.com/webstatic/en_US/i/buttons/checkout-logo-large.png" alt="Check out with PayPal" /></a></p>
					<?php		
				} catch (\PayPal\Exception\PayPalConnectionException $ex) {
					// This will print the detailed information on the exception.
					//REALLY HELPFUL FOR DEBUGGING
					echo $ex->getData();
				}
			}
		}

		$output = ob_get_clean();
		return $output;
	}

	/**
	 * Saves the information to the event's main settings array and then returns it.
	 *
	 * @param  array $options The key=>value array that holds this event's information.
	 * @return array          The options array with the PayPal settings saved.
	 */
	public function save( $options ) {
		$options['paypal_email']                  = $_POST['paypal_email'];
		$options['paypal_live_client_id']         = $_POST['paypal_live_client_id'];
		$options['paypal_live_client_secret']     = $_POST['paypal_live_client_secret'];
		$options['paypal_sandbox_client_id']      = $_POST['paypal_sandbox_client_id'];
		$options['paypal_sandbox_client_secret']  = $_POST['paypal_sandbox_client_secret'];
		return $options;
	}
}
