<?php

/**
 * Class to define an Admin Table for showing subscribers of a giveaway 
 */

if( ! defined( 'ABSPATH' ) ) {
	return;
}

if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}

class GA_Users_Table extends WP_List_Table {

	/**
	 * Settings
	 *
	 * @var null|array
	 */
	public $settings = null;

	/**
     * Form Fields
	 * @var null|array
	 */
	protected $form_fields = null;

	/** Class constructor */
	public function __construct() {

		parent::__construct( array(
			'singular' => __( 'User', 'giveasap' ), //singular name of the listed records
			'plural'   => __( 'Users', 'giveasap' ), //plural name of the listed records
			'ajax'     => false //should this table support ajax?
		));

		$this->_column_headers = $this->get_columns();
	}

	/**
	 * Get the settings
	 */
	public function get_settings() {
		if ( null === $this->settings ) {
			$this->settings = giveasap_get_settings();
		}

		return $this->settings;
	}

	/**
     * Get the form fields.
     *
	 * @param int $giveaway_id
	 *
	 * @return array|null
	 */
	protected function get_form_fields( $giveaway_id = 0 ) {
	    if ( null === $this->form_fields ) {
	        $this->form_fields = sg_get_form_fields( $giveaway_id );
        }

        return $this->form_fields;
    }

  	/**
	 * Retrieve user's data from the database
	 *
	 * @param int $per_page
	 * @param int $page_number
	 *
	 * @return mixed
	 */
	public static function get_users( $per_page = 5, $page_number = 1 ) {

	  global $wpdb;

	  $giveaway_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;

	  $sql = 'SELECT * FROM ' . $wpdb->giveasap_entries . ' as sg_entries';

		if ( ! empty( $_REQUEST['ga_search_name'] ) ) {
			$sql .= ' LEFT JOIN ' . $wpdb->giveasapmeta . ' as sg_meta on sg_meta.giveasap_id = sg_entries.id';
		}

	  $sql .= ' WHERE 1=1';

	  if ( $giveaway_id ) {
	      $sql .= ' AND post_id = %d';
      }

	  if ( ! empty( $_REQUEST['ga_search_email'] ) ) {
	      $sql .= ' AND email=\'' . esc_sql( $_REQUEST['ga_search_email'] ) . '\'';
      }

        if ( ! empty( $_REQUEST['ga_search_name'] ) ) {
            $sql .= $wpdb->prepare( ' AND sg_meta.meta_key=%s AND sg_meta.meta_value=%s', '_user_name', $_REQUEST['ga_search_name'] );
        }

	  if ( ! empty( $_REQUEST['orderby'] ) ) {
	    $sql .= ' ORDER BY ' . esc_sql( $_REQUEST['orderby'] );
	    $sql .= ! empty( $_REQUEST['order'] ) ? ' ' . esc_sql( $_REQUEST['order'] ) : ' ASC';
	  }

	  $sql .= ' LIMIT ' . $per_page;

	  $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;

	  if ( $giveaway_id ) {
		  $result = $wpdb->get_results( $wpdb->prepare( $sql, $giveaway_id ), 'ARRAY_A' );
	  } else {
		  $result = $wpdb->get_results( $sql, 'ARRAY_A' );
      }

	  return $result;
	}

	/**
	 * Delete a user record.
	 *
	 * @param int $id customer ID
	 */
	public static function delete_user( $id ) {
	  global $wpdb;

	  $ret = $wpdb->delete(
	    $wpdb->giveasap_entries,
	    array( 'id' => $id ),
	    array( '%d' )
	  );

	  if ( false !== $ret ) {
	      // Deleting meta
	      $wpdb->delete(
	        $wpdb->giveasapmeta,
            array( 'giveasap_id' => $id ),
            array( '%d' )
          );

	      // Deleting Extra Actions
		  $wpdb->delete(
			  $wpdb->giveasap_actions,
			  array( 'subscriber_id' => $id ),
			  array( '%d' )
		  );
      }
	}

	/**
	 * Returns the count of records in the database.
	 *
	 * @return null|string
	 */
	public static function record_count() {
	    global $wpdb;

	    $giveaway_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;

	    $sql = 'SELECT COUNT(*) FROM ' . $wpdb->giveasap_entries . ' as sg_entries';

		if ( ! empty( $_REQUEST['ga_search_name'] ) ) {
			$sql .= ' LEFT JOIN ' . $wpdb->giveasapmeta . ' as sg_meta on sg_meta.giveasap_id = sg_entries.id';
		}

		$sql .= ' WHERE 1=1';

		if ( ! empty( $_REQUEST['ga_search_email'] ) ) {
			$sql .= ' AND email=\'' . esc_sql( $_REQUEST['ga_search_email'] ) . '\'';
		}

		if ( ! empty( $_REQUEST['ga_search_name'] ) ) {
			$sql .= $wpdb->prepare( ' AND sg_meta.meta_key=%s AND sg_meta.meta_value=%s', '_user_name', $_REQUEST['ga_search_name'] );
		}

        if ( $giveaway_id ) {
          $sql .= ' AND post_id = %d';
          $sql  = $wpdb->prepare( $sql, $giveaway_id );
        }

	  return $wpdb->get_var( $sql );
	}

	/** Text displayed when no user data is available */
	public function no_items() {
	  _e( 'No users subscribed.', 'giveasap' );
	}

	/**
	 * Method for name column
	 *
	 * @param array $item an array of DB data
	 *
	 * @return string
	 */
	function column_email( $item ) {

	  // create a nonce
	  $delete_nonce = wp_create_nonce( 'giveasap_delete_customer' );
	  $resend_nonce = wp_create_nonce( 'giveasap_resend_email' );

	  $title = apply_filters( 'sg_subscriber_column_email', '<strong>' . $item['email'] . '</strong>', $item );

	  $referrer = giveasap_get_referrer( $item['id'] );

	  if ( $referrer ) {
		  $giveaway_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;

		  if( $giveaway_id ) {
			  $user = giveasap_get_user_by_id( $referrer, $giveaway_id );
			  if ( $user ) {
				  $title .= '(' . $user->email . ')';
			  }
		  }
	  }

	  $delete_action_args = array(
          'post_type'    => 'giveasap',
          'page'         => esc_attr( $_REQUEST['page'] ),
          'action'       => 'delete',
          'user'         => absint( $item['id'] ),
          'delete_nonce' => $delete_nonce
      );

	  if ( isset( $_REQUEST['id'] ) ) {
		  $delete_action_args['id'] = absint( $_REQUEST['id'] );
      }

      $delete_url = add_query_arg( $delete_action_args, admin_url( 'edit.php' ) );

	  $actions = array(
	    'delete'  => '<a href="' . $delete_url . '">' . __( 'Delete', 'giveasap' ) . '</a>',
	    'view'    => sprintf( '<a href="edit.php?post_type=giveasap&page=%s&user=%d&action=view">' . __( 'View', 'giveasap' ) . '</a>', 'giveasap-users', absint( $item['id'] ) ),
	    'entries' => sprintf( '<a href="edit.php?post_type=giveasap&page=%s&subscriber=%d">' . __( 'View Entries', 'giveasap' ) . '</a>', 'giveasap-subscriber-entries', absint( $item['id'] ) ),
      );

	  return $title . $this->row_actions( $actions );
	}

	/**
	 * Method for displaying the Column Name
	 *
	 * @param $item
	 *
	 * @return string
	 */
	function column_name( $item ) {
		$name = giveasap_get_meta( $item['id'], '_user_name', true );
		if ( ! $name ) {
			$name = giveasap_get_meta( $item['id'], '_name', true );
		}
		if ( ! $name ) {
			$name = '';
		}

		return $name;
	}

	/**
	 * Column Entries
	 * @param  array $item 
	 * @return string       
	 */
	function column_entries( $item ) {

	    ob_start();

		$output = '<span class="giveasap-user-entries">' . $item['entries'] . '<br/></span>';
		
		if ( giv_fs()->is_free_plan() ) {
			$output .= '<button disabled="disabled" type="button" class="button button-small button-secondary giveasap-edit-user">' . __( 'Edit', 'giveasap' ) . '</button>';
			$output .= '<a class="upgrade-link" href="' . giv_fs()->get_upgrade_url() . '">' .
            	__('Upgrade to Edit Entries!', 'giveasap') .
            '</a>';
		}

		echo $output;

		do_action( 'sg_subscribers_table_admin_column_entries', $item );


		return ob_get_clean();

	}

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

	/**
     * Return the Giveaway
	 * @param $item
	 */
	public function column_giveaway( $item ) {
        return get_the_title( $item['post_id'] );
    }

	/**
	 * @param $item
	 *
	 * @return string
	 */
    public function column_status( $item ) {
        $statuses = sg_subscriber_statuses();
        $status   = isset( $statuses[ $item['status'] ] ) ? $statuses[ $item['status'] ] : __( 'Pending', 'giveasap' );
        return '<span class="sg-badge sg-status sg-status-' . $item['status'] . '">' . $status . '</span>';
   }

	/**
     * Actions for each subscriber.
     *
	 * @param $item
     *
     * @return string
	 */
    public function column_actions( $item ) {
	    $resend_nonce = wp_create_nonce( 'giveasap_resend_email' );

	    $subscriber_actions = array();
	    $resend_args        = array(
		    'post_type'    => 'giveasap',
		    'page'         => esc_attr( $_REQUEST['page'] ),
		    'action'       => 'resend',
		    'user'         => absint( $item['id'] ),
		    'resend_nonce' => $resend_nonce,
		    'paged'        => isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1,
	    );

	    if ( isset( $_REQUEST['id'] ) ) {
	        $resend_args['id'] = absint( $_REQUEST['id'] );
        }

        $resend_url = add_query_arg( $resend_args, admin_url( 'edit.php' ) );
	    $subscriber_actions['resend'] = '<a class="button button-small sg-tooltip" href="' . esc_attr( $resend_url ) . '" title="' . __( 'Re-send Email', 'giveasap' ) . '"><span class="fal fa-envelope"></span></a>';


	    if ( isset( $item['status'] ) && 'blocked' !== $item['status'] ) {
		    $block_args = array(
			    'post_type'    => 'giveasap',
			    'page'         => esc_attr( $_REQUEST['page'] ),
			    'action'       => 'block',
			    'user'         => absint( $item['id'] ),
                'paged'        => isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1,
		    );

		    if ( isset( $_REQUEST['id'] ) ) {
		        $block_args['id'] = $_REQUEST['id'];
            }

		    $block_url = add_query_arg( $block_args, admin_url( 'edit.php' ) );
		    $subscriber_actions['block'] = '<a class="button button-small sg-button-red sg-tooltip" href="' . esc_attr( $block_url ) .'" title="' . __( 'Block', 'giveasap' ) . '"><span class="fal fa-ban"></span></a>';
	    }

	    if ( isset( $item['status'] ) && 'blocked' === $item['status'] ) {
		    $block_args = array(
			    'post_type'    => 'giveasap',
			    'page'         => esc_attr( $_REQUEST['page'] ),
			    'action'       => 'unblock',
			    'user'         => absint( $item['id'] ),
			    'paged'        => isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1,
		    );

		    if ( isset( $_REQUEST['id'] ) ) {
			    $block_args['id'] = $_REQUEST['id'];
		    }

		    $block_url = add_query_arg( $block_args, admin_url( 'edit.php' ) );
		    $subscriber_actions['block'] = '<a class="button button-small sg-tooltip" href="' . esc_attr( $block_url ) .'" title="' . __( 'Unblock', 'giveasap' ) . '"><span class="fal fa-check"></span></a>';
	    }

	    if ( isset( $item['status'] ) && 'pending' === $item['status'] ) {
		    $activate_args = array(
			    'post_type'    => 'giveasap',
			    'page'         => esc_attr( $_REQUEST['page'] ),
			    'action'       => 'activate',
			    'user'         => absint( $item['id'] ),
			    'paged'        => isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1,
		    );

		    if ( isset( $_REQUEST['id'] ) ) {
			    $activate_args['id'] = $_REQUEST['id'];
		    }

		    $activate_url = add_query_arg( $activate_args, admin_url( 'edit.php' ) );
            $subscriber_actions['activate_link'] = sprintf( ' <a class="button button-seconday button-small sg-button-action" data-text="%s" data-reload="1" href="%s">' . __( 'Activate', 'giveasap' ) . '</a>', __( 'Activating...', 'giveasap' ), $activate_url );
        }

        $subscriber_actions = apply_filters( 'sg_admin_subscriber_actions_column', $subscriber_actions, $item );
        $html = '';
        if ( $subscriber_actions ) {
            $html = implode( ' ', $subscriber_actions );
        }
        return $html;
    }

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

	/**
	 *  Associative array of columns
	 *
	 * @return array
	 */
	public function get_columns() {
	  $columns = array(
	    'cb'      => '<input type="checkbox" />',
	    'email'   => __( 'Email', 'giveasap' ),
	    'entries' => __( 'Entries', 'giveasap' ),
	  );

	  $giveaway_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;

	  $form_fields = $this->get_form_fields( $giveaway_id );

	  if ( isset( $form_fields['user_name'] ) ) {
	  	$columns[ 'name' ] = __( 'Name', 'giveasap' );
	  }

	  $columns['status'] = __( 'Status', 'giveasap' );

	  if ( ! $giveaway_id ) {
	      $columns['giveaway'] = __( 'Giveaway', 'giveasap' );
      }

      $columns['actions'] = __( 'Actions', 'giveasap' );

	  return $columns;
	}

	/**
	 * Columns to make sortable.
	 *
	 * @return array
	 */
	public function get_sortable_columns() {
	  $sortable_columns = array(
	    'entries' => array( 'entries', true )
	  );

	  return $sortable_columns;
	}

	/**
	 * Returns an associative array containing the bulk action
	 *
	 * @return array
	 */
	public function get_bulk_actions() {
	  $actions = array(
	    'bulk-delete' => 'Delete'
	  );

	  return $actions;
	}

	/**
	 * Handles data query and filter, sorting, and pagination.
	 */
	public function prepare_items() {

  	  $columns = $this->get_columns();
	  $hidden = array();
	  $sortable = $this->get_sortable_columns();
	  $this->_column_headers = array($columns, $hidden, $sortable);

	  /** Process bulk action */
	  $this->process_bulk_action();

	  if ( isset( $_REQUEST['user_notified'] ) ) {
	      ?>
          <div class="notice notice-success is-dismissible">
              <p><?php printf( __( 'Email sent to %s', 'giveasap' ), sanitize_text_field( $_REQUEST['user_notified'] ) ); ?></p>
          </div>
          <?php
      }

        if ( isset( $_REQUEST['user_blocked'] ) ) {
            ?>
            <div class="notice notice-success is-dismissible">
                <p><?php printf( __( 'Subscriber Blocked: %s', 'giveasap' ), sanitize_text_field( $_REQUEST['user_blocked'] ) ); ?></p>
            </div>
            <?php
        }

		if ( isset( $_REQUEST['user_unblocked'] ) ) {
			?>
            <div class="notice notice-success is-dismissible">
                <p><?php printf( __( 'Subscriber Unblocked: %s', 'giveasap' ), sanitize_text_field( $_REQUEST['user_unblocked'] ) ); ?></p>
            </div>
			<?php
		}

      do_action( 'sg_subscriber_admin_list_before_items' );

	  $per_page     = $this->get_items_per_page( 'sg_subscribers_per_page', 10 );
	  $current_page = $this->get_pagenum();
	  $total_items  = self::record_count();
 
	  $this->set_pagination_args( [
	    'total_items' => $total_items, //WE have to calculate the total number of items
	    'per_page'    => $per_page //WE have to determine how many items to show on a page
	  ] );


	  $this->items = self::get_users( $per_page, $current_page );
	    
	}

	public function process_bulk_action() {

	  //Detect when a bulk action is being triggered...
	  if ( 'delete' === $this->current_action() ) {

	    // In our file that handles the request, verify the nonce.
	    $nonce = esc_attr( $_REQUEST['delete_nonce'] );

	    if ( ! wp_verify_nonce( $nonce, 'giveasap_delete_customer' ) ) {
	      die( 'Go get a life script kiddies' );
	    }
	    else {
	      self::delete_user( absint( $_GET['user'] ) );
	    }

	  }

	  if ( 'activate' === $this->current_action() ) {
		  giveasap_activate_user( absint( $_GET['user'] ) );
      }

	  // If the delete bulk action is triggered
	  if ( ( isset( $_POST['action'] ) && $_POST['action'] == 'bulk-delete' )
	       || ( isset( $_POST['action2'] ) && $_POST['action2'] == 'bulk-delete' )
	  ) {

	    $delete_ids = esc_sql( $_POST['bulk-delete'] );

	    // loop over the array of record IDs and delete them
	    foreach ( $delete_ids as $id ) {
	      self::delete_user( $id );

	    }
	  }
	}



	/**
	 * Extra controls to be displayed between bulk actions and pagination
	 *
	 * @since 2.10.0
	 *
	 * @param string $which
	 */
	protected function extra_tablenav( $which ) {
	    if ( 'top' === $which ) {
	        $email = isset( $_REQUEST['ga_search_email'] ) ? $_REQUEST['ga_search_email'] : '';
		    $name = isset( $_REQUEST['ga_search_name'] ) ? $_REQUEST['ga_search_name'] : '';
		    ?>
            <div class="alignleft actions">
                <input type="email" name="ga_search_email" value="<?php echo esc_attr( $email ); ?>"
                       placeholder="<?php esc_attr_e( 'Search for an Email', 'giveasap' ); ?>"/>
                <?php
                $giveaway_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;

                $form_fields = $this->get_form_fields( $giveaway_id );

                if ( isset( $form_fields['user_name'] ) ) {
	                ?>
                     <input type="email" name="ga_search_name" value="<?php echo esc_attr( $name ); ?>"
                               placeholder="<?php esc_attr_e( 'Search by Name', 'giveasap' ); ?>"/>

	                <?php
                }
                ?>
                <button class="button ga-search-email"><?php _e( 'Search', 'giveasap' ); ?></button>
            </div>
		    <?php
	    }
	}

	/**
	 * Display the pagination.
	 *
	 * @since 3.1.0
	 *
	 * @param string $which
	 */
	protected function pagination( $which ) {
		if ( empty( $this->_pagination_args ) ) {
			return;
		}

		$total_items = $this->_pagination_args['total_items'];
		$total_pages = $this->_pagination_args['total_pages'];
		$infinite_scroll = false;
		if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
			$infinite_scroll = $this->_pagination_args['infinite_scroll'];
		}

		if ( 'top' === $which && $total_pages > 1 ) {
			$this->screen->render_screen_reader_content( 'heading_pagination' );
		}

		$output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';

		$current = $this->get_pagenum();
		$removable_query_args = wp_removable_query_args();

		$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );

		$current_url = remove_query_arg( $removable_query_args, $current_url );
        $current_url = remove_query_arg( 'user_notified', $current_url );
		$current_url = remove_query_arg( 'user_blocked', $current_url );
		$current_url = remove_query_arg( 'user_unblocked', $current_url );
		$page_links  = array();

		$total_pages_before = '<span class="paging-input">';
		$total_pages_after  = '</span></span>';

		$disable_first = $disable_last = $disable_prev = $disable_next = false;

		if ( $current == 1 ) {
			$disable_first = true;
			$disable_prev = true;
		}
		if ( $current == 2 ) {
			$disable_first = true;
		}
		if ( $current == $total_pages ) {
			$disable_last = true;
			$disable_next = true;
		}
		if ( $current == $total_pages - 1 ) {
			$disable_last = true;
		}

		if ( $disable_first ) {
			$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>';
		} else {
			$page_links[] = sprintf( "<a class='first-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
				esc_url( remove_query_arg( 'paged', $current_url ) ),
				__( 'First page' ),
				'&laquo;'
			);
		}

		if ( $disable_prev ) {
			$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>';
		} else {
			$page_links[] = sprintf( "<a class='prev-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
				esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ),
				__( 'Previous page' ),
				'&lsaquo;'
			);
		}

		if ( 'bottom' === $which ) {
			$html_current_page  = $current;
			$total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
		} else {
			$html_current_page = sprintf( "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' /><span class='tablenav-paging-text'>",
				'<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
				$current,
				strlen( $total_pages )
			);
		}
		$html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
		$page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;

		if ( $disable_next ) {
			$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>';
		} else {
			$page_links[] = sprintf( "<a class='next-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
				esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ),
				__( 'Next page' ),
				'&rsaquo;'
			);
		}

		if ( $disable_last ) {
			$page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>';
		} else {
			$page_links[] = sprintf( "<a class='last-page button' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
				esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
				__( 'Last page' ),
				'&raquo;'
			);
		}

		$pagination_links_class = 'pagination-links';
		if ( ! empty( $infinite_scroll ) ) {
			$pagination_links_class .= ' hide-if-js';
		}
		$output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';

		if ( $total_pages ) {
			$page_class = $total_pages < 2 ? ' one-page' : '';
		} else {
			$page_class = ' no-pages';
		}
		$this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";

		echo $this->_pagination;
	}
}