<?php
if (!defined('MYCRED_PURCHASE'))
	exit;

/**
 * buyCRED_Pending_Payments class
 * @since 1.7
 * @version 1.2
 */
if (!class_exists('buyCRED_Pending_Payments')):
	class buyCRED_Pending_Payments extends myCRED_Module
	{

		/**
		 * Construct
		 */
		function __construct($type = MYCRED_DEFAULT_TYPE_KEY)
		{

			parent::__construct('buyCRED_Pending_Payments', array(
				'module_name' => 'pending_payments',
				'option_id' => '',
				'defaults' => array(),
				'screen_id' => '',
				'accordion' => false,
				'add_to_core' => false,
				'menu_pos' => 75
			), $type);

		}

		/**
		 * Load
		 * @version 1.0.1
		 */
		public function load()
		{

			add_action('mycred_init', array($this, 'module_init'), $this->menu_pos);
			add_action('mycred_admin_init', array($this, 'module_admin_init'), $this->menu_pos);

		}

		/**
		 * Module Init
		 * @since 1.7
		 * @version 1.2
		 */
		public function module_init()
		{

			$this->register_pending_payments();

			add_shortcode(MYCRED_SLUG . '_buy_pending', 'mycred_render_pending_purchases');

			add_action('mycred_pre_process_buycred', array($this, 'intercept_cancellations'));

			add_action('mycred_add_menu', array($this, 'add_to_menu'), $this->menu_pos);
			add_action('transition_post_status', array($this, 'pending_transitions'), 10, 3);

		}

		/**
		 * Intercept Cancellations
		 * @since 1.7
		 * @version 1.1
		 */
		public function intercept_cancellations()
		{

			global $buycred_instance;

			// Intercept payment cancellations
			if (isset($_REQUEST['buycred-cancel']) && isset($_REQUEST['_token']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_token'])), 'buycred-cancel-pending-payment')) {

				// Get pending payment object
				$pending_payment_id = sanitize_text_field(wp_unslash($_REQUEST['buycred-cancel']));

				// Move item to trash
				buycred_trash_pending_payment($pending_payment_id);

				// Redirect
				wp_safe_redirect(remove_query_arg(array('buycred-cancel', '_token')));
				exit;

			}

		}

		/**
		 * Pending Transitions
		 * @since 1.8
		 * @version 1.0
		 */
		public function pending_transitions($new_status, $old_status, $post)
		{

			if ($post->post_status == MYCRED_BUY_KEY) {

				mycred_delete_user_meta($post->post_author, 'buycred_pending_payments');

			}

		}

		/**
		 * Module Admin Init
		 * @since 1.7
		 * @version 1.1
		 */
		public function module_admin_init()
		{

			add_filter('parent_file', array($this, 'parent_file'));
			add_filter('submenu_file', array($this, 'subparent_file'), 10, 2);

			add_action('admin_notices', array($this, 'admin_notices'));
			add_filter('post_row_actions', array($this, 'adjust_row_actions'), 10, 2);
			add_action('admin_head-post.php', array($this, 'edit_pending_payment_style'));
			add_action('admin_head-edit.php', array($this, 'pending_payments_style'));
			add_filter('post_updated_messages', array($this, 'post_updated_messages'));

			add_filter('manage_' . MYCRED_BUY_KEY . '_posts_columns', array($this, 'adjust_column_headers'));
			add_action('manage_' . MYCRED_BUY_KEY . '_posts_custom_column', array($this, 'adjust_column_content'), 10, 2);
			add_filter('bulk_actions-edit-' . MYCRED_BUY_KEY, array($this, 'bulk_actions'));
			add_action('save_post_' . MYCRED_BUY_KEY, array($this, 'save_pending_payment'), 10, 2);

			// Intercept payment completions
			if (isset($_GET['credit']) && isset($_GET['token']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['token'])), 'buycred-payout-pending')) {

				$pending_id = absint($_GET['credit']);

				if ($this->core->user_is_point_editor()) {

					$url = remove_query_arg(array('credit', 'token'));

					if (buycred_complete_pending_payment($pending_id)) {
						$url = add_query_arg(array('credited' => 1), $url);
					} else {
						$url = add_query_arg(array('credited' => 0), $url);
					}

					wp_safe_redirect($url);
					exit;

				}

			}

		}

		/**
		 * Register Pending Payments
		 * @since 1.5
		 * @version 1.1
		 */
		protected function register_pending_payments()
		{

			$labels = array(
				'name' => _x('buyCred Pending Payments', 'Post Type General Name', 'mycred'),
				'singular_name' => _x('buyCred Pending Payment', 'Post Type Singular Name', 'mycred'),
				'menu_name' => __('buyCred Pending Payments', 'mycred'),
				'parent_item_colon' => '',
				'all_items' => __('buyCred Pending Payments', 'mycred'),
				'view_item' => '',
				'add_new_item' => '',
				'add_new' => '',
				'edit_item' => __('Edit buyCred Pending Payment', 'mycred'),
				'update_item' => '',
				'search_items' => 'Search',
				'not_found' => __('Not found in Trash', 'mycred'),
				'not_found_in_trash' => __('Not found in Trash', 'mycred'),
			);
			$args = array(
				'labels' => $labels,
				'supports' => array('title', 'comments'),
				'hierarchical' => false,
				'public' => false,
				'show_ui' => true,
				'show_in_menu' => false,
				'show_in_nav_menus' => false,
				'show_in_admin_bar' => false,
				'can_export' => true,
				'has_archive' => false,
				'exclude_from_search' => true,
				'publicly_queryable' => false,
				'register_meta_box_cb' => array($this, 'add_metaboxes')
			);
			register_post_type(MYCRED_BUY_KEY, apply_filters('mycred_setup_pending_payment', $args));

		}

		/**
		 * Adjust Post Updated Messages
		 * @since 1.7
		 * @version 1.1
		 */
		public function post_updated_messages($messages)
		{

			$messages[MYCRED_BUY_KEY] = array(
				0 => '',
				1 => __('Payment Updated.', 'mycred'),
				2 => __('Payment Updated.', 'mycred'),
				3 => __('Payment Updated.', 'mycred'),
				4 => __('Payment Updated.', 'mycred'),
				5 => __('Payment Updated.', 'mycred'),
				6 => __('Payment Updated.', 'mycred'),
				7 => __('Payment Updated.', 'mycred'),
				8 => __('Payment Updated.', 'mycred'),
				9 => __('Payment Updated.', 'mycred'),
				10 => ''
			);

			return $messages;

		}

		/**
		 * Add Comment
		 * @since 1.7
		 * @version 1.0
		 */
		public function add_comment($post_id, $event = '', $time = NULL)
		{

			return buycred_add_pending_comment($post_id, $event, $time);

		}

		/**
		 * Admin Notices
		 * @since 1.7
		 * @version 1.1
		 */
		public function admin_notices()
		{

			if (isset($_GET['post_type']) && $_GET['post_type'] == MYCRED_BUY_KEY && isset($_GET['credited'])) {

				if ($_GET['credited'] == 1)
					echo '<div id="message" class="updated notice is-dismissible"><p>' . esc_html__('Pending payment successfully credited to account.', 'mycred') . '</p><button type="button" class="notice-dismiss"></button></div>';
				elseif ($_GET['credited'] == 0)
					echo '<div id="message" class="error notice is-dismissible"><p>' . esc_html__('Failed to credit the pending payment to account.', 'mycred') . '</p><button type="button" class="notice-dismiss"></button></div>';

			}

		}

		/**
		 * Add Admin Menu Item
		 * @since 1.7
		 * @version 1.1
		 */
		public function add_to_menu()
		{

			mycred_add_main_submenu(
				__('Pending Payments', 'mycred'),
				__('Pending Payments', 'mycred'),
				$this->core->get_point_editor_capability(),
				'edit.php?post_type=' . MYCRED_BUY_KEY
			);

		}

		/**
		 * Parent File
		 * @since 1.7
		 * @version 1.0.1
		 */
		public function parent_file($parent = '')
		{

			global $pagenow;

			if (isset($_GET['post']) && mycred_get_post_type(absint($_GET['post'])) == MYCRED_BUY_KEY && isset($_GET['action']) && $_GET['action'] == 'edit')
				return MYCRED_MAIN_SLUG;

			return $parent;

		}

		/**
		 * Sub Parent File
		 * @since 1.7.8
		 * @version 1.0
		 */
		public function subparent_file($subparent = '', $parent = '')
		{

			global $pagenow;

			if (($pagenow == 'edit.php' || $pagenow == 'post-new.php') && isset($_GET['post_type']) && $_GET['post_type'] == MYCRED_BUY_KEY) {

				return 'edit.php?post_type=' . MYCRED_BUY_KEY;

			} elseif ($pagenow == 'post.php' && isset($_GET['post']) && mycred_get_post_type(absint($_GET['post'])) == MYCRED_BUY_KEY) {

				return 'edit.php?post_type=' . MYCRED_BUY_KEY;

			}

			return $subparent;

		}

		/**
		 * Pending Payment Column Headers
		 * @since 1.5
		 * @version 1.0
		 */
		public function adjust_column_headers($columns)
		{

			return array(
				'cb' => $columns['cb'],
				'comments' => $columns['comments'],
				'title' => __('Transaction ID', 'mycred'),
				'date' => $columns['date'],
				'author' => __('Buyer', 'mycred'),
				'amount' => __('Amount', 'mycred'),
				'cost' => __('Cost', 'mycred'),
				'gateway' => __('Gateway', 'mycred'),
				'ctype' => __('Type', 'mycred')
			);

		}

		/**
		 * Pending Payment Column Content
		 * @since 1.5
		 * @version 1.0
		 */
		public function adjust_column_content($column_name, $post_id)
		{

			global $mycred_modules;

			switch ($column_name) {
				case 'author':

					$from = (int) mycred_get_post_meta($post_id, 'from', true);
					$user = get_userdata($from);

					if (isset($user->display_name))
						echo '<a href="' . esc_url(add_query_arg(array('user_id' => $user->ID), admin_url('user-edit.php'))) . '">' . esc_html($user->display_name) . '</a>';
					else
						echo 'ID: ' . esc_html($from);

					break;
				case 'amount':

					$type = mycred_get_post_meta($post_id, 'point_type', true);
					$amount = mycred_get_post_meta($post_id, 'amount', true);
					$mycred = mycred($type);

					echo esc_html($mycred->format_creds($amount));

					break;
				case 'cost':

					$cost = mycred_get_post_meta($post_id, 'cost', true);
					$currency = mycred_get_post_meta($post_id, 'currency', true);

					echo esc_html($cost . ' ' . $currency);

					break;
				case 'gateway':

					$gateway = mycred_get_post_meta($post_id, 'gateway', true);
					$installed = $mycred_modules['solo']['buycred']->get();

					if (isset($installed[$gateway]))
						echo esc_html($installed[$gateway]['title']);
					else
						echo esc_html($gateway);

					break;
				case 'ctype':

					$type = mycred_get_post_meta($post_id, 'point_type', true);

					if (isset($this->point_types[$type]))
						echo esc_html($this->point_types[$type]);
					else
						echo esc_html($type);

					break;
			}

		}

		/**
		 * Adjust Bulk Actions
		 * @since 1.5
		 * @version 1.0
		 */
		public function bulk_actions($actions)
		{

			unset($actions['edit']);
			return $actions;

		}

		/**
		 * Pending Payment Row Actions
		 * @since 1.5
		 * @version 1.2
		 */
		public function adjust_row_actions($actions, $post)
		{

			if ($post->post_type == MYCRED_BUY_KEY && $post->post_status != 'trash') {

				unset($actions['inline hide-if-no-js']);

				// Add option to "Pay Out" now
				if ($this->core->user_is_point_editor())
					$actions['credit'] = '<a href="' . esc_url(add_query_arg(array(
						'post_type' => $post->post_type,
						'credit' => $post->ID,
						'token' => wp_create_nonce('buycred-payout-pending')
					), admin_url('edit.php'))) . '">' . __('Pay Out', 'mycred') . '</a>';

			}

			return $actions;

		}

		/**
		 * Edit Pending Payment Style
		 * @since 1.7
		 * @version 1.0.1
		 */
		public function edit_pending_payment_style()
		{

			global $post_type;

			if ($post_type !== MYCRED_BUY_KEY)
				return;

			wp_enqueue_style('mycred-bootstrap-grid');

			add_filter('postbox_classes_buycred_payment_buycred-pending-payment', array($this, 'metabox_classes'));
			add_filter('postbox_classes_buycred_payment_buycred-pending-comments', array($this, 'metabox_classes'));

			?>
			<script type="text/javascript">
				jQuery(function ($) {

					$(document).ready(function () {
						$('h1 .page-title-action, .wrap .page-title-action').remove();
						$('#titlewrap #title').attr('readonly', 'readonly').addClass('readonly');
					});

				});
			</script>
			<?php

		}

		/**
		 * Pending Payment Style
		 * @since 1.7
		 * @version 1.0.1
		 */
		public function pending_payments_style()
		{

			global $post_type;

			if ($post_type !== MYCRED_BUY_KEY)
				return;

			?>
			<script type="text/javascript">
				jQuery(function ($) {

					$(document).ready(function () {
						$('h1 .page-title-action, .wrap .page-title-action').remove();
					});

				});
			</script>
			<?php

		}

		/**
		 * Add Metaboxes
		 * @since 1.7
		 * @version 1.1
		 */
		public function add_metaboxes()
		{

			add_meta_box(
				'buycred-pending-payment',
				__('Pending Payment', 'mycred'),
				array($this, 'metabox_pending_payment'),
				MYCRED_BUY_KEY,
				'normal',
				'high'
			);

			if (MYCRED_BUY_PENDING_COMMENTS)
				add_meta_box(
					'buycred-pending-comments',
					__('History', 'mycred'),
					array($this, 'metabox_pending_comments'),
					MYCRED_BUY_KEY,
					'normal',
					'default'
				);

			remove_meta_box('commentstatusdiv', MYCRED_BUY_KEY, 'normal');
			remove_meta_box('commentsdiv', MYCRED_BUY_KEY, 'normal');

			remove_meta_box('submitdiv', MYCRED_BUY_KEY, 'side');
			add_meta_box(
				'submitdiv',
				__('Actions', 'mycred'),
				array($this, 'metabox_pending_actions'),
				MYCRED_BUY_KEY,
				'side',
				'high'
			);

		}

		/**
		 * Metabox: Pending Actions
		 * @since 1.7
		 * @version 1.0
		 */
		public function metabox_pending_actions($post)
		{

			$payout_url = add_query_arg(array(
				'post_type' => $post->post_type,
				'credit' => $post->ID,
				'token' => wp_create_nonce('buycred-payout-pending')
			), admin_url('edit.php'));

			$delete_url = get_delete_post_link($post->ID);

			?>
			<div class="submitbox mycred-metabox" id="submitpost">
				<div id="minor-publishing">
					<div style="display:none;">
						<?php submit_button(__('Save', 'mycred'), 'button', 'save'); ?>
					</div>

					<div id="minor-publishing-actions">

						<div><a href="<?php echo esc_url($payout_url); ?>"
								class="button button-secondary button-block"><?php esc_html_e('Pay Out', 'mycred'); ?></a></div>
						<div><a href="<?php echo esc_url($delete_url); ?>"
								class="button button-secondary button-block"><?php esc_html_e('Trash', 'mycred'); ?></a></div>

					</div>

					<div class="clear"></div>
				</div>
				<div id="major-publishing-actions">

					<div id="publishing-action">
						<span class="spinner"></span>

						<input type="submit" id="publish" class="button button-primary primary button-large"
							value="<?php esc_attr_e('Save Changes', 'mycred'); ?>" />

					</div>
					<div class="clear"></div>
				</div>
			</div>
			<?php

		}

		/**
		 * Metabox: Pending Payment
		 * @since 1.7
		 * @version 1.0.1
		 */
		public function metabox_pending_payment($post)
		{

			global $mycred_modules;

			$pending_payment = buycred_get_pending_payment($post->ID);
			$buyer_name = 'ID: ' . $pending_payment->buyer_id;

			$buyer_object = get_userdata($pending_payment->buyer_id);
			if (isset($buyer_object->ID)) {
				$buyer_name = $buyer_object->display_name;
				if ($buyer_name == '')
					$buyer_name = $buyer_object->user_email;
			}

			if ($pending_payment->recipient_id == $pending_payment->buyer_id)
				$recipient_name = $buyer_name;
			else {
				$recipient_name = 'ID: ' . $pending_payment->recipient_id;
				$recipient_object = get_userdata($pending_payment->recipient_id);
				if (isset($recipient_object->ID)) {
					$recipient_name = $recipient_object->display_name;
					if ($recipient_name == '')
						$recipient_name = $recipient_object->user_email;
				}
			}

			if ($pending_payment->point_type == $this->core->cred_id)
				$mycred = $this->core;
			else
				$mycred = mycred($pending_payment->point_type);

			?>
			<div class="form">
				<div class="row">
					<div class="col-md-6">
						<div class="form-group">
							<label><?php esc_html_e('Payer', 'mycred'); ?></label>
							<p class="form-control-static"><?php echo esc_attr($buyer_name); ?></p>
						</div>
					</div>
					<div class="col-md-6">
						<div class="form-group">
							<label><?php esc_html_e('Recipient', 'mycred'); ?></label>
							<p class="form-control-static"><?php echo esc_attr($recipient_name); ?></p>
						</div>
					</div>
				</div>
				<div class="row">
					<div class="col-md-3 col-sm-6">
						<div class="form-group">
							<label for="buycred-pending-payment-point_type"><?php esc_html_e('Point Type', 'mycred'); ?></label>
							<?php

							// Just one point type is set for sale. No need for a dropdown menu
							if (count($this->core->buy_creds['types']) == 1) {

								?>
								<p class="form-control-static"><?php echo esc_html($mycred->plural()); ?></p>
								<input type="hidden" name="buycred_pending_payment[point_type]"
									value="<?php echo esc_attr($pending_payment->point_type); ?>" />
								<?php

							}

							// Multiple point types are set for sale. Show a dropdown menu
							else {

								?>
								<select name="buycred_pending_payment[point_type]" id="buycred-pending-payment-point_type"
									class="form-control">
									<?php

									foreach ($this->core->buy_creds['types'] as $point_type) {

										echo '<option value="' . esc_attr($point_type) . '"';
										if ($pending_payment->point_type == $point_type)
											echo ' selected="selected"';
										echo '>' . esc_html(mycred_get_point_type_name($point_type, false)) . '</option>';

									}

									?>
								</select>
								<?php

							}

							?>
						</div>
					</div>
					<div class="col-md-3 col-sm-6">
						<div class="form-group">
							<label for="buycred-pending-payment-gateway"><?php esc_html_e('Gateway', 'mycred'); ?></label>
							<select name="buycred_pending_payment[gateway]" id="buycred-pending-payment-gateway"
								class="form-control">
								<?php

								foreach ($mycred_modules['solo']['buycred']->get() as $gateway_id => $info) {

									echo '<option value="' . esc_attr($gateway_id) . '"';
									if ($pending_payment->gateway_id == $gateway_id)
										echo ' selected="selected"';
									if (!$mycred_modules['solo']['buycred']->is_active($gateway_id))
										echo ' disabled="disabled"';
									echo '>' . esc_html($info['title']) . '</option>';

								}

								?>
							</select>
						</div>
					</div>
					<div class="col-md-2 col-sm-6">
						<div class="form-group">
							<label for="buycred-pending-payment-amount"><?php esc_html_e('Amount', 'mycred'); ?></label>
							<input type="text" name="buycred_pending_payment[amount]" id="buycred-pending-payment-amount"
								class="form-control"
								value="<?php echo esc_attr($mycred->number($pending_payment->amount)); ?>" />
						</div>
					</div>
					<div class="col-md-2 col-sm-6">
						<div class="form-group">
							<label for="buycred-pending-payment-cost"><?php esc_html_e('Cost', 'mycred'); ?></label>
							<input type="text" name="buycred_pending_payment[cost]" id="buycred-pending-payment-cost"
								class="form-control" value="<?php echo esc_attr($pending_payment->cost); ?>" />
						</div>
					</div>
					<div class="col-md-2 col-sm-6">
						<div class="form-group">
							<label for="buycred-pending-payment-currency"><?php esc_html_e('Currency', 'mycred'); ?></label>
							<input type="text" name="buycred_pending_payment[currency]" id="buycred-pending-payment-currency"
								class="form-control" value="<?php echo esc_attr($pending_payment->currency); ?>" />
						</div>
					</div>
				</div>
			</div>
			<?php

		}

		/**
		 * Metabox: Pending Payment Comments
		 * @since 1.7
		 * @version 1.0
		 */
		public function metabox_pending_comments($post)
		{

			$comments = get_comments(array('post_id' => $post->ID));

			echo '<ul class="history">';

			if (empty($comments)) {

				$c = new StdClass();
				$c->comment_date = $post->post_date;
				$c->comment_content = __('Pending request created.', 'mycred');

				$event = $this->add_comment($post->ID, $c->comment_content, $c->comment_date);
				if ($event === false)
					$c->comment_content .= ' Unsaved';
				else
					$c->comment_content .= ' ' . $event;

				$comments[] = $c;

			}

			foreach ($comments as $comment) {

				echo '<li><time>' . esc_html($comment->comment_date) . '</time><p>' . esc_html($comment->comment_content) . '</p></li>';

			}

			echo '</ul>';

		}

		/**
		 * Save Pending Payment
		 * @since 1.7
		 * @version 1.0
		 */
		public function save_pending_payment($post_id, $post)
		{

			if (!$this->core->user_is_point_editor() || !isset($_POST['buycred_pending_payment']))
				return;

			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			$pending_payment = $_POST['buycred_pending_payment'];
			$changed = false;

			foreach ($pending_payment as $meta_key => $meta_value) {

				$new_value = sanitize_text_field($meta_value);
				$old_value = mycred_get_post_meta($post_id, $meta_key, true);
				if ($new_value != $old_value) {
					mycred_update_post_meta($post_id, $meta_key, $new_value);
					$changed = true;
				}

			}

			if ($changed) {
				$user = wp_get_current_user();
				$this->add_comment($post_id, sprintf(__('Pending payment updated by %s', 'mycred'), $user->user_login));
			}

		}

	}
endif;

/**
 * Load buyCRED Pending Module
 * @since 1.7
 * @version 1.0
 */
if (!function_exists('mycred_load_buycred_pending_addon')):
	function mycred_load_buycred_pending_addon($modules, $point_types)
	{

		$modules['solo']['buycred-pending'] = new buyCRED_Pending_Payments();
		$modules['solo']['buycred-pending']->load();

		return $modules;

	}
endif;
add_filter('mycred_load_modules', 'mycred_load_buycred_pending_addon', 40, 2);
