<?php
/**
 * Users List Template
 *
 * @package WooCommerce Points and Rewards
 * @version 1.0.0
 */

namespace DDWCPointsAndRewards\Templates\Admin\Users;

use DDWCPointsAndRewards\Helper\Point\DDWCPR_Point_Helper;
use DDWCPointsAndRewards\Helper\Rank\DDWCPR_Rank_Helper;

defined( 'ABSPATH' ) || exit();

if ( ! class_exists( 'DDWCPR_Users_List_Template' ) ) {
	/**
	 * Users list class
	 */
	class DDWCPR_Users_List_Template extends \WP_List_table {
		/**
		 * Configuration Variable
		 *
		 * @var array
		 */
		protected $ddwcpr_configuration;

		/**
		 * Point Helper Variable
		 *
		 * @var object
		 */
		protected $point_helper;

		/**
		 * Construct
		 * 
		 * @param array $ddwcpr_configuration
		 */
		public function __construct( $ddwcpr_configuration ) {
			$this->ddwcpr_configuration = $ddwcpr_configuration;
			$this->point_helper         = new DDWCPR_Point_Helper( $ddwcpr_configuration );

			parent::__construct( [
				'singular' => esc_html__( 'User List', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'plural'   => esc_html__( 'Users List', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'ajax'     => false,
			] );
		}

		/**
		 * Prepare Items
		 *
		 * @return void
		 */
		public function prepare_items() {
			$this->_column_headers = $this->get_column_info();

			$request_scheme = is_ssl() ? 'https' : 'http';
			$current_url    = "$request_scheme://" . sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) . sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

			if ( strpos( $current_url, '_wp_http_referer' ) !== false ) {
				$new_url = remove_query_arg( [ '_wp_http_referer', '_wpnonce' ], stripslashes( $current_url ) );
				wp_safe_redirect( $new_url );
				exit();
			}

			$this->process_bulk_action();
			$this->process_row_action();

			$search         = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
			$per_page       = $this->get_items_per_page( 'ddwcpr_users_per_page', 20 );
			$current_page   = $this->get_pagenum();
			$off            = ( $current_page - 1 ) * $per_page;

			$args = [
				'number'         => $per_page,
				'offset'         => $off,
				'order'          => ! empty( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'DESC',
				'orderby'        => ! empty( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'ID',
				'search'         => '*' . esc_attr( $search ) . '*',
				'search_columns' => [ 'user_nicename', 'ID', 'user_login', 'user_email', 'display_name' ],
				'fields'         => [ 'ID', 'display_name', 'user_email', 'user_login' ],
			];

			$query = new \WP_User_Query( $args );

			wp_reset_postdata();

			$this->set_pagination_args( [
				'total_items' => $query->get_total(),
				'per_page'    => $per_page,
			] );

			$data = $this->ddwcpr_prepare_data( $query->get_results() );

			usort( $data, [ $this, 'usort_reorder' ] );

			$this->items = $data;
		}

		/**
		 * Usort
		 *
		 * @param int $first First value.
		 * @param int $second Second value.
		 * @return $result
		 */
		public function usort_reorder( $first, $second ) {
			$orderby = ! empty( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'id';
			$order   = ! empty( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'desc';
			$result  = strnatcmp( $first[ $orderby ], $second[ $orderby ] );

			return 'asc' === $order ? $result : -$result;
		}

		/**
		 * Fetch Data function
		 *
		 * @param array $users
		 * @return array $data
		 */
		public function ddwcpr_prepare_data( $users ) {
			$data = [];

			if ( ! empty( $users ) ) {
				$rank_helper = new DDWCPR_Rank_Helper( $this->ddwcpr_configuration );

				foreach ( $users as $user ) {
					$user_id = $user->ID;

					$earned_points           = $this->point_helper->ddwcpr_get_user_earned_points( $user_id );
					$available_redeem_points = $this->point_helper->ddwcpr_get_user_available_points( $user_id );
					$rank                    = $rank_helper->ddwcpr_get_user_rank( $user_id );

					$data[] = [
						'id'                      => $user_id,
						'username'                => $user->display_name,
						'email'                   => $user->user_email,
						'earned_points'           => $earned_points,
						'available_redeem_points' => $available_redeem_points,
						'rank'                    => $rank,
					];
				}
			}

			return apply_filters( 'ddwcpr_users_list_data', $data );
		}

		/**
		 * Process bulk actions
		 *
		 * @return void
		 */
		public function process_bulk_action() {
			if ( ! empty( $_GET['ddwcpr_nonce'] ) ) {
				if ( wp_verify_nonce( sanitize_text_field( wp_unslash ( $_GET['ddwcpr_nonce'] ) ), 'ddwcpr_nonce_action' ) ) {
					$action = $this->current_action();

					if ( in_array( $action, [ 'delete', 'pending', 'approved', 'rejected', 'banned' ] ) ) {
						if ( ! empty( $_GET['ddwcpr-id'] ) ) { // WPCS: input var ok.
							if ( is_array( $_GET['ddwcpr-id'] ) ) { // WPCS: input var ok.
								$ids = array_map( 'sanitize_text_field', wp_unslash( $_GET['ddwcpr-id'] ) ); // WPCS: input var ok.

								$success = $error = 0;

								foreach ( $ids as $id ) {
									if ( 'delete' === $action ) {
										$response = wp_delete_user( $id );
									} else {
										$this->point_helper->ddwcpr_update_affiliate_status( $id, $action );
										$response = true;
									}

									if ( $response ) {
										$success++;
									} else {
										$error++;
									}
								}

								if ( $success ) {
									if ( 'delete' === $action ) {
										$message = sprintf( esc_html__( '%d user(s) deleted successfully.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $success );
									} else {
										$message = sprintf( esc_html__( 'Status changed for %d user(s) successfully.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $success );
									}

									ddfw_print_notification( $message );
								}

								if ( $error ) {
									$message = sprintf( esc_html__( '%d user(s) not exists.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $error );
									ddfw_print_notification( $message, 'error' );
								}
							}
						} else {
							$message = esc_html__( 'Select user(s) to delete.', 'loyaltyx-points-and-rewards-for-woocommerce' );
							ddfw_print_notification( $message, 'error' );
						}
					}
				} else {
					$message = esc_html__( 'Invalid nonce. Security check failed!!!', 'loyaltyx-points-and-rewards-for-woocommerce' );
					ddfw_print_notification( $message, 'error' );
				}
			}
		}

		/**
		 * Process row actions
		 *
		 * @return void
		 */
		public function process_row_action() {
			if ( ! empty( $_GET['ddwcpr_nonce'] ) ) {
				if ( wp_verify_nonce( sanitize_text_field( wp_unslash ( $_GET['ddwcpr_nonce'] ) ), 'ddwcpr_nonce_action' ) ) {

					$action = $this->current_action();

					if ( in_array( $action, [ 'delete' ] ) ) {
						if ( ! empty( $_GET['ddwcpr-id'] ) && ! is_array( $_GET['ddwcpr-id'] ) ) { // WPCS: input var ok.
							$id       = intval( wp_unslash( $_GET['ddwcpr-id'] ) );  // WPCS: input var ok.
							$response = wp_delete_user( $id );

							if ( $response ) {
								$message = esc_html__( 'User is deleted successfully.', 'loyaltyx-points-and-rewards-for-woocommerce' );
								ddfw_print_notification( $message );
							} else {
								$message = esc_html__( 'User not exists.', 'loyaltyx-points-and-rewards-for-woocommerce' );
								ddfw_print_notification( $message, 'error' );
							}
						}
					}
				} else {
					$message = esc_html__( 'Invalid nonce. Security check failed!!!', 'loyaltyx-points-and-rewards-for-woocommerce' );
					ddfw_print_notification( $message, 'error' );
				}
			}
		}

		/**
		 *  No items
		 *
		 * @return void
		 */
		public function no_items() {
			esc_html_e( 'No users avaliable.', 'loyaltyx-points-and-rewards-for-woocommerce' );
		}

		/**
		 * Hidden Columns
		 *
		 * @return array
		 */
		public function get_hidden_columns() {
			return [];
		}

		/**
		 *  Associative array of columns
		 *
		 * @return array
		 */
		public function get_columns() {
			$columns = [
				'cb'                      => '<input type="checkbox" />',
				'username'                => esc_html__( 'Name', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'email'                   => esc_html__( 'Email', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'earned_points'           => esc_html__( 'Earned Points', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'available_redeem_points' => esc_html__( 'Points to Redeem', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'rank'                    => esc_html__( 'Rank', 'loyaltyx-points-and-rewards-for-woocommerce' ),
			];

			return apply_filters( 'ddwcpr_users_list_columns', $columns );
		}

		/**
		 * Render a column when no column specific method exists.
		 *
		 * @param array  $item Items.
		 * @param string $column_name Name.
		 *
		 * @return mixed
		 */
		public function column_default( $item, $column_name ) {
			return array_key_exists( $column_name, $item ) ? $item[ $column_name ] : print_r( $item, true );
		}

		/**
		 * Columns to make sortable.
		 *
		 * @return array
		 */
		public function get_sortable_columns() {
			return apply_filters( 'ddwcpr_users_list_sortable_columns', [
				'id'                      => [ 'id', true ],
				'username'                => [ 'username', true ],
				'email'                   => [ 'email', true ],
				'earned_points'           => [ 'earned_points', true ],
				'available_redeem_points' => [ 'available_redeem_points', true ],
				'rank'                    => [ 'rank', true ],
			] );
		}

		/**
		 * Render the bulk edit checkbox
		 *
		 * @param array $item Item.
		 * @return string
		 */
		public function column_cb( $item ) {
			return sprintf( '<input type="checkbox" name="ddwcpr-id[]" value="%d" />', esc_attr( $item['id'] ) );
		}

		/**
		 * Column actions
		 *
		 * @param array $item Items.
		 * @return array $actions
		 */
		public function column_username( $item ) {
			$page         = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
			$menu         = isset( $_GET['menu'] ) ? sanitize_text_field( wp_unslash( $_GET['menu'] ) ) : '';
			$search       = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
			$current_page = $this->get_pagenum();

			$actions = [
				'username' => sprintf( 'ID: %s', $item['id'] ),
				'view'     => sprintf( '<a href="%s">%s</a>', esc_url( admin_url( "admin.php?page={$page}&menu={$menu}&action=view&ddwcpr-id={$item['id']}" ) ), esc_html__( 'View', 'loyaltyx-points-and-rewards-for-woocommerce' ) ),
				'delete'   => sprintf( '<a href="%s">%s</a>', wp_nonce_url( "admin.php?page={$page}&menu={$menu}&action=delete&s={$search}&paged={$current_page}&ddwcpr-id={$item['id']}", 'ddwcpr_nonce_action', 'ddwcpr_nonce' ), esc_html__( 'Delete', 'loyaltyx-points-and-rewards-for-woocommerce' ) ),
			];

			return sprintf( '%1$s %2$s', $item['username'], $this->row_actions( apply_filters( 'ddwcpr_users_list_line_actions', $actions ) ) );
		}

		/**
		 * Bulk actions on list.
		 * 
		 * @return array
		 */
		public function get_bulk_actions() {
			return apply_filters( 'ddwcpr_modify_bulk_actions_in_affiliates_list', [
				'delete'   => esc_html__( 'Delete', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'pending'  => esc_html__( 'Change Affiliate Status to Pending', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'approved' => esc_html__( 'Approve Affiliate', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'rejected' => esc_html__( 'Reject Affiliate', 'loyaltyx-points-and-rewards-for-woocommerce' ),
				'banned'   => esc_html__( 'Ban Affiliate', 'loyaltyx-points-and-rewards-for-woocommerce' ),
			] );
		}
	}
}
