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

/**
 * WP_Job_Manager_SPL_Gateway class.
 */
abstract class WRE_SPL_Gateway {

	protected $current_user_id = '';
	protected $paypal_link = 'https://www.paypal.com/cgi-bin/webscr?';
	/**
	 * __construct function.
	 */
	public function __construct() {
		$this->current_user_id = get_current_user_id();
		if (  wre_option( 'wre_paypal_enable_sandbox' ) == 'on' ) {
			$this->paypal_link = 'https://www.sandbox.paypal.com/cgi-bin/webscr?test_ipn=1&';
		}
		add_filter( 'wp_mail_content_type', array( $this, 'set_content_type' ) );
	}

	/**
	 * Set the email content type
	 */
	public function set_content_type( $content_type ) {
		$return = 'text/html';
		return $return;
	}

	/**
	 * Find strings to replace in email
	 */
	public static function find() {
		$find = array();
		$find['payment_received'] = '{payment_received}';
		$find['actual_payment'] = '{actual_payment}';
		$find['listing_id'] = '{listing_id}';
		$find['user_id'] = '{user_id}';
		$find['user_name'] = '{user_name}';
		$find['user_email'] = '{user_email}';
		$find['listing_name'] = '{listing_name}';
		$find['transaction_id'] = '{transaction_id}';
		$find['payment_method'] = '{payment_method}';
		$find['price'] = '{price}';
		$find['package_name'] = '{package_name}';
		return apply_filters( 'wre_submit_form_find', $find );
	}

	/**
	 * Replace strings found in email
	 */
	public static function replace( $mail_details ) {
		$replace = array();
		$user_id = isset($mail_details['user_id']) ? $mail_details['user_id'] : get_current_user_id();
		$membership_id = wre_get_membership_details( $user_id, 'id' );

		$listing_ID = isset($mail_details['listing_id']) ? $mail_details['listing_id'] : '';
		$payment_received = isset($mail_details['payment_received']) ? $mail_details['payment_received'] : '';
		$actual_payment = isset($mail_details['actual_payment']) ? $mail_details['actual_payment'] : '';
		$transaction_id = isset($mail_details['transaction_id']) ? $mail_details['transaction_id'] : '';
		$price = isset($mail_details['price']) ? $mail_details['price'] : '';
		$payment_method = isset($mail_details['payment_method']) ? $mail_details['payment_method'] : '';
		$package_name = isset($mail_details['package_name']) ? $mail_details['package_name'] : '';

		$replace['payment_received'] = $payment_received;
		$replace['actual_payment'] = $actual_payment;
		$replace['listing_id'] = $listing_ID;
		$replace['user_id'] = $user_id;
		$replace['user_name'] = get_the_author_meta( 'display_name', $user_id );
		$replace['user_email'] = get_the_author_meta( 'user_email', $user_id );
		$replace['listing_name'] = get_the_title( $listing_ID );
		$replace['transaction_id'] = $transaction_id;
		$replace['payment_method'] = $payment_method;
		$replace['price'] = $price;
		if( $membership_id ) {
			$replace['package_name'] = get_the_title( $membership_id );
		}
		return apply_filters( 'wre_submit_form_replace', $replace );
	}

	/**
	 * Format email string.
	 *
	 */
	public static function format_string( $string, $mail_details ) {
		return str_replace( self::find(), self::replace( $mail_details ), $string );
	}

	/**
	 * Send a message to admin about payment
	 *
	 * @param  string	$email_subject
	 * @param  string	$email_message
	 */
	public static function send_admin_email( $email_subject, $email_message ) {
		$mail =  wre_option( 'wre_new_listing_notification' ) ? wre_option( 'wre_new_listing_notification' ) : get_option( 'admin_email' );
		$email_message = wpautop( $email_message );
		wp_mail( $mail, $email_subject, $email_message );
	}
	
	/**
	 * Send a message to customer about payment
	 *
	 * @param  string	$email_subject
	 * @param  string	$email_message
	 */
	public static function send_customer_email( $email_subject, $email_message ) {
		$user_id = get_current_user_id();
		$user_email = get_the_author_meta( 'user_email', $user_id );
		$payment_type = wre_get_membership_details('', 'payment_type');
		if( $payment_type == 'bacs' ) {
			$subscription_id = get_user_meta( $user_id, '_wre_subscription_id', true );
			$email_message .= WRE_Gateway_BACS::bank_details($subscription_id);
		}
		wp_mail( $user_email, $email_subject, $email_message );
	}

	/**
	 * Payment is complete - update listing
	 *
	 * @param	int	$listing_id
	 */
	public static function payment_complete( $listing_id, $flag = '', $subscription_id = '', $user_id = '' ) {
		$listing = get_post( $listing_id );
		if ( in_array( $listing->post_status, array( 'draft' ) ) ) {
			// Update status
			$update_listing                  = array();
			$update_listing['ID']            = $listing_id;
			$update_listing['post_status']   = wre_option( 'wre_auto_publish_listings' ) == 'on' ? 'publish' : 'draft';
			$update_listing['post_date']     = current_time( 'mysql' );
			$update_listing['post_date_gmt'] = current_time( 'mysql', 1 );
			wp_update_post( $update_listing );
		}
		$membership_amt = wre_get_membership_details( $user_id, 'price' );

		if( $membership_amt > 0 && $flag != 'error' ) {
			update_post_meta( $listing_id, '_wre_listing_premium', 'on' );
			update_post_meta( $listing_id, '_wre_subscription_id', $subscription_id );
		}
		do_action( 'wre_listing_payment_complete', $listing_id );
	}

	/**
	 * Get Email Content
	 *
	 * @param  string	$notification_type
	 * @param  array	$mail_details
	 */
	public static function wre_email_notification( $notification_type, $mail_details = array() ) {
		if( $notification_type ) {
			$subscription_email_subject = wre_option( 'wre_'.$notification_type.'_email_subject' );
			$subscription_email_subject = self::format_string( $subscription_email_subject, $mail_details );

			$subscription_email_message = wre_option( 'wre_'.$notification_type.'_email_message' );
			$subscription_email_message = self::format_string( $subscription_email_message, $mail_details );
			if( $notification_type === 'customer_invoice' ) {
				self::send_customer_email( $subscription_email_subject, $subscription_email_message );
			} else {
				self::send_admin_email( $subscription_email_subject, $subscription_email_message );
			}
		}
	}
	/**
	 * Send invoice mail to user
	 */
	public static function wre_user_subscribed_notification( $subscription_id ) {
		
		$subscription_details = get_post_meta( $subscription_id, '_wre_subscription_details', true );

		$mail_details = array(
			'transaction_id'	=> $subscription_details['transaction_id'],
			'payment_method'	=> $subscription_details['payment_type'],
			'price'				=> $subscription_details['price'],
			'package_name'		=> $subscription_details['plan_name']
		);
		self::wre_email_notification( 'customer_invoice', $mail_details );
	}

	/**
	 * Get Expiration date of package
	 *
	 * @param  int    $package_id
	 * 
	 * $return date
	 */
	public static function wre_get_expiration_period( $package_id ) {
		$subscription_period = absint( wre_package_meta( 'subscription_period', $package_id ) );

		if( ! $subscription_period ) return '';

		$subscription_unit = wre_package_meta( 'subscription_unit', $package_id );
		$exp_date = '';
		$date = time();
		switch ( $subscription_unit ) {
			case 'years' :
				$exp_period = '+'.$subscription_period.' year';
				$exp_date = strtotime(date("Y-m-d", $date) . $exp_period);
			break;
			case 'months' :
				$exp_period = '+'.$subscription_period.' month';
				$exp_date = strtotime(date("Y-m-d", $date) . $exp_period);
			break;
			case 'weeks' :
				$exp_period = '+'.$subscription_period.' week';
				$exp_date = strtotime(date("Y-m-d", $date) . $exp_period);
			break;
			case 'days' :
				$exp_period = '+'.$subscription_period.' days';
				$exp_date = strtotime(date("Y-m-d", $date) . $exp_period);
			break;
		}// End switch().
		return $exp_date;
	}

	public function wre_update_membership_details( $membership_details = array() ) {
		if( isset( $membership_details['package_id'] ) && $membership_details['package_id'] != '' ) {
			$flag = '';
			$user_id = get_current_user_id();
			$package_id = $membership_details['package_id'];
			$listings_allowed = wre_package_meta( 'allowed_listings', $package_id );
			$package_amount = wre_package_meta( 'price', $package_id );
			$payment_status = 'pending';

			if( isset( $membership_details['payment_date'] ) )
				$payment_date = $membership_details['payment_date'];

			//Paypal and Stripe Payment
			if( isset( $membership_details['transaction_id'] ) )
				$transaction_id = $membership_details['transaction_id'];

			$listing_id = isset( $membership_details['listing_id'] ) ? $membership_details['listing_id'] : '';

			if( isset( $membership_details['payment_status'] ) && $membership_details['payment_status'] != '' ) {
				$payment_status = $membership_details['payment_status'];
				if( $payment_status == 'succeeded' || $payment_status == 'paid'  ) {
					$payment_status = 'completed';
				}

				if( isset( $membership_details['amount_received'] ) && $membership_details['amount_received'] != '' ) {
					$payment_received = $membership_details['amount_received'];
				} else {
					$payment_received = '';
				}
				$mail_details = array(
					'listing_id' => $listing_id,
					'user_id' => $user_id,
					'payment_received' => $payment_received,
					'actual_payment' => $package_amount,
				);
				switch ( $payment_status ) {
					case 'completed' :
						// Validate Amount
						if (  $package_amount != $payment_received ) {
							self::wre_email_notification( 'payment_mismatch', $mail_details );
							$flag = 'error';
						} else {
							// Notify admin
							if ( wre_option( 'wre_auto_publish_listings' ) == 'on' ) {
								self::wre_email_notification( 'payment_received', $mail_details );
							} else {
								self::wre_email_notification( 'payment_received_admin_approval', $mail_details );
							}
						}
					break;
					case 'pending' :
						self::wre_email_notification( 'pending_payment', $mail_details );
						$flag = 'error';
					break;
				}
			} else {
				self::wre_email_notification( 'new_subscription' );
			}

			$update_membership_details = array(
				'id'					=> $package_id,
				'plan_name'				=> get_the_title($package_id),
				'price'					=> $package_amount,
				'allowed_listings'		=> $listings_allowed,
				'payment_status'		=> $payment_status,
				'is_recurring'			=> '',
				'expiry_date'			=> self::wre_get_expiration_period( $package_id ),
				'transaction_id'		=> $transaction_id,
				'payment_date'			=> strtotime($payment_date),
				'payment_type'			=> $membership_details['payment_type'],
				'subscriber_ip_address' => self::get_ip_address()
			);

			$subscription_id = wp_insert_post(array(
				'post_type'=>'wre-subscription',
				'post_status' => 'publish',
				'post_title' => sprintf(
					__( 'Subscription &ndash; %s', 'wp-real-estate' ),
					strftime( '%b %d, %Y @ %I:%M %p' )
					)
				));

			if( $subscription_id ) {
				update_post_meta( $subscription_id, '_wre_subscription_details', $update_membership_details );
				update_post_meta( $subscription_id, '_wre_subscriber_id', $user_id );
				update_user_meta( $user_id, '_wre_subscription_id', $subscription_id );
				update_post_meta( $listing_id, '_wre_subscription_id', $subscription_id );

				if( $payment_status == 'completed' ) {
					$user_listings = wre_user_non_premium_listings();
					if( !empty($user_listings) ) {
						foreach( $user_listings as $user_listing ) {
							self::payment_complete( $user_listing, $flag, $subscription_id );
						}
					}
				}
				self::wre_user_subscribed_notification($subscription_id);
			}
		}
	}

	public static function get_ip_address() {
		if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
			return $_SERVER['HTTP_X_REAL_IP'];
		} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
			// Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
			// Make sure we always only send through the first IP in the list which should always be the client IP.
			return (string) self::is_ip_address( trim( current( explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) );
		} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
			return $_SERVER['REMOTE_ADDR'];
		}
		return '';
	}
	
	/**
	 * Check if is a valid IP address.
	 */
	private static function is_ip_address( $ip_address ) {
		// WP 4.7+ only.
		if ( function_exists( 'rest_is_ip_address' ) ) {
			return rest_is_ip_address( $ip_address );
		}

		$ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';

		if ( ! preg_match( $ipv4_pattern, $ip_address ) ) {
			return false;
		}

		return $ip_address;
	}

	public function get_stripe_payment_data( $listing_id ) {
		ob_start();
		?>
			<form method="post" id="wre-listing-preview">
				<input type="submit" name="continue" id="wre_listing_preview_submit_button" value='' />
				<input type="hidden" name="listing_id" value="<?php echo absint( $listing_id ); ?>" />
			</form>
			<a href="#" class="pay-listing wre-stripe-pay-button">
				<i class="wre-icon-stripe"></i>
				<span><?php echo __( 'Stripe', 'wp-real-estate' ); ?></span>
			</a>
		<?php
		return ob_get_clean();
	}

}