<?php
/**
 * Grieg List table
 *
 * @package Nisje
 */

declare( strict_types = 1 );
namespace Nisje\Grieg\Dashboard\ListTable;

defined( 'ABSPATH' ) || die( 'Shame on you' );

if ( ! class_exists( '\WP_List_Table' ) ) {
	return;
}

/**
 * Grieg List Table
 */
class Grieg_List_Table extends \WP_List_Table {
	/**
	 * Default Users per page.
	 *
	 * @var string $users_per_page.
	 */
	private $users_per_page = 300;

	/**
	 * Constructor.
	 */
	public function __construct() {
		parent::__construct(
			[
				'singular' => 'user',
				'plural'   => 'users',
				'screen'   => isset( $args['screen'] ) ? $args['screen'] : null,
			]
		);
	}

	/**
	 * Prepare the users list for display.
	 */
	public function prepare_items() {
		global $role, $usersearch;

		$usersearch     = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : ''; // phpcs:ignore
		$role           = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : ''; // phpcs:ignore
		$users_per_page = $this->get_items_per_page( 'grieg_per_page' );

		$paged = $this->get_pagenum();

		if ( 'none' === $role ) {
			$args = [
				'number'  => $users_per_page,
				'offset'  => ( $paged - 1 ) * $users_per_page,
				'include' => wp_get_users_with_no_role( $this->site_id ),
				'search'  => $usersearch,
				'fields'  => 'all_with_meta',
			];
		} else {
			$args = [
				'number' => $users_per_page,
				'offset' => ( $paged - 1 ) * $users_per_page,
				'role'   => $role,
				'search' => $usersearch,
				'fields' => 'all_with_meta',
			];
		}

		if ( '' !== $args['search'] ) {
			$args['search'] = '*' . $args['search'] . '*';
		}

		if ( $this->is_site_users ) {
			$args['blog_id'] = $this->site_id;
		}

		if ( isset( $_REQUEST['orderby'] ) ) { // phpcs:ignore
			$args['orderby'] = $_REQUEST['orderby']; // phpcs:ignore
		}

		if ( isset( $_REQUEST['order'] ) ) { // phpcs:ignore
			$args['order'] = $_REQUEST['order']; // phpcs:ignore
		}

		$args = apply_filters( 'users_list_table_query_args', $args );

		// Query the user IDs for this page.
		$wp_user_search = new \WP_User_Query( $args );
		$this->items    = $wp_user_search->get_results();
		$this->set_pagination_args(
			[
				'total_items' => $wp_user_search->get_total(),
				'per_page'    => $users_per_page,
			]
		);
	}
	/**
	 * Output 'no users' message.
	 */
	public function no_items() {
		esc_html_e( 'No users found.', 'nisje-grieg' );
	}

	/**
	 * Return an associative array listing all the views that can be used
	 * with this table.
	 *
	 * Provides a list of roles and user count for that role for easy
	 * Filtersing of the user table.
	 *
	 * @return array An array of HTML links, one for each view.
	 */
	protected function get_views() {
		global $role;

		$wp_roles      = wp_roles();
		$users_of_blog = count_users();
		$url           = 'users.php';

		$total_users = $users_of_blog['total_users'];
		$avail_roles =& $users_of_blog['avail_roles'];
		unset( $users_of_blog );

		$current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : '';

		$role_links = [];

		// Translators: %s All.
		$role_links['all'] = "<a href='$url'$current_link_attributes>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users', 'nisje-grieg' ), number_format_i18n( $total_users ) ) . '</a>';

		foreach ( $wp_roles->get_names() as $this_role => $name ) {
			if ( ! isset( $avail_roles[ $this_role ] ) ) {
				continue;
			}

			$current_link_attributes = '';
			if ( $this_role === $role ) {
				$current_link_attributes = ' class="current" aria-current="page"';
			}

			$name = translate_user_role( $name );
			/* translators: User role name with count */
			$name                     = sprintf( __( '%1$s <span class="count">(%2$s)</span>', 'nisje-grieg' ), $name, number_format_i18n( $avail_roles[ $this_role ] ) );
			$role_links[ $this_role ] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$current_link_attributes>$name</a>";
		}

		if ( ! empty( $avail_roles['none'] ) ) {
			$current_link_attributes = '';
			if ( 'none' === $role ) {
				$current_link_attributes = ' class="current" aria-current="page"';
			}
			$name = __( 'No role', 'nisje-grieg' );
			/* translators: User role name with count */
			$name               = sprintf( __( '%1$s <span class="count">(%2$s)</span>', 'nisje-grieg' ), $name, number_format_i18n( $avail_roles['none'] ) );
			$role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$current_link_attributes>$name</a>";
		}

		return $role_links;
	}
	/**
	 * Retrieve an associative array of bulk actions available on this table.
	 *
	 * @return array Array of bulk actions.
	 */
	protected function get_bulk_actions() {
		$actions = [];

		$actions['csv']   = esc_html__( 'Export to CSV', 'nisje-grieg' );
		$actions['excel'] = esc_html__( 'Export to Excel', 'nisje-grieg' );

		return $actions;
	}

	/**
	 * Get a list of columns for the list table.
	 *
	 * @return array Array in which the key is the ID of the column,
	 *               and the value is the description.
	 */
	public function get_columns() {
		$c = [
			'user-id'     => esc_html__( 'ID', 'nisje-grieg' ),
			'username'    => esc_html__( 'Username', 'nisje-grieg' ),
			'name'        => esc_html__( 'Name', 'nisje-grieg' ),
			'email'       => esc_html__( 'Email', 'nisje-grieg' ),
			'workplace'   => esc_html__( 'Workplace', 'nisje-grieg' ),
			'department'  => esc_html__( 'Department', 'nisje-grieg' ),
			'main-group'  => esc_html__( 'Main Group', 'nisje-grieg' ),
			'location'    => esc_html__( 'Location', 'nisje-grieg' ),
			'company'     => esc_html__( 'Company', 'nisje-grieg' ),
			'skills'      => esc_html__( 'Skills', 'nisje-grieg' ),
			'member-type' => esc_html__( 'Membertype', 'nisje-grieg' ),
			'emp_num'     => esc_html__( 'Employee Number', 'nisje-grieg' ),
			'userrole'    => esc_html__( 'Role', 'nisje-grieg' ),
			'registered'  => esc_html__( 'Registered', 'nisje-grieg' ),
			'activity'    => esc_html__( 'Last activity', 'nisje-grieg' ),
			'deactivated' => esc_html__( 'Deactivated', 'nisje-grieg' ),
		];

		return $c;
	}
	/**
	 * Get a list of sortable columns for the list table.
	 *
	 * @return array Array of sortable columns.
	 */
	protected function get_sortable_columns() {
		$c = [
			'id'       => 'ID',
			'username' => 'login',
			'email'    => 'email',
			'name'     => 'display_name',
		];

		return $c;
	}
	/**
	 * Generate the list table rows.
	 */
	public function display_rows() {
		foreach ( $this->items as $userid => $user_object ) {
			echo "\n\t" . $this->single_row( $user_object ); //phpcs:ignore
		}
	}
	/**
	 * Generate HTML for a single row on the users.php admin panel.
	 *
	 * @since 3.1.0
	 *
	 * @param WP_User $user_object The current user object.
	 * @return string Output for a single row.
	 */
	public function single_row( $user_object ) {
		if ( ! ( $user_object instanceof \WP_User ) ) {
			$user_object = get_userdata( (int) $user_object );
		}

		$user_object->filter = 'display';
		$email               = $user_object->user_email;

		if ( $this->is_site_users ) {
			$url = "site-users.php?id={$this->site_id}&amp;";
		} else {
			$url = 'users.php?';
		}

		$user_roles = $this->get_role_list( $user_object );

		// Set up the hover actions for this user.
		$actions  = [];
		$checkbox = '';

		// Check if the user for this row is editable.
		if ( current_user_can( 'list_users' ) ) {
			// Set up the user editing link.
			$edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user_object->ID ) ) ); //phpcs:ignore
			if ( current_user_can( 'edit_user', $user_object->ID ) ) {
				$edit            = "<strong><a href=\"{$edit_link}\">{$user_object->user_login}</a></strong><br />";
				$actions['edit'] = '<a href="' . $edit_link . '">' . esc_html__( 'Edit', 'nisje-grieg' ) . '</a>';
			} else {
				$edit = "<strong>{$user_object->user_login}</strong><br />";
			}

			$actions = apply_filters( 'user_row_actions', $actions, $user_object );

			// Role classes.
			$role_classes = esc_attr( implode( ' ', array_keys( $user_roles ) ) );
			// Set up the checkbox ( because the user is editable, otherwise it's empty ).
			// translators: %s select label.
			$checkbox = '<label class="screen-reader-text" for="user_' . $user_object->ID . '">' . sprintf( esc_html__( 'Select %s', 'nisje-grieg' ), $user_object->user_login ) . '</label>'
						. "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='{$role_classes}' value='{$user_object->ID}' />";
		} else {
			$edit = "<strong>{$user_object->user_login}</strong>";
		}

		$avatar = get_avatar( $user_object->ID, 32 );

		// Comma-separated list of user roles.
		$roles_list = implode( ', ', $user_roles );

		$trclass = '';
		if ( '1' === $user_object->user_status ) {
			$trclass = ' class="site-spammed"';
		}

		$r = "<tr id='user-$user_object->ID'$trclass>";

		list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();

		$user_meta = get_user_meta( $user_object->ID );

		foreach ( $columns as $column_name => $column_display_name ) {
			$classes = "$column_name column-$column_name";
			if ( $primary === $column_name ) {
				$classes .= ' has-row-actions column-primary';
			}

			if ( in_array( $column_name, $hidden, true ) ) {
				$classes .= ' hidden';
			}

			$data       = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"';
			$attributes = "class='$classes' $data";

			$r .= "<td $attributes>";
			switch ( $column_name ) {
				case 'user-id':
					$r .= $user_object->ID;
					break;
				case 'username':
					$r .= "$avatar $edit";
					break;
				case 'name':
					if ( $user_object->first_name && $user_object->last_name ) {
						$r .= "$user_object->first_name $user_object->last_name";
					} elseif ( $user_object->first_name ) {
						$r .= $user_object->first_name;
					} elseif ( $user_object->last_name ) {
						$r .= $user_object->last_name;
					} else {
						$r .= '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">' . _x( 'Unknown', 'name', 'nisje-grieg' ) . '</span>';
					}
					break;
				case 'email':
					$r .= "<a href='" . esc_url( "mailto:$email" ) . "'>$email</a>";
					break;
				case 'userrole':
					$r .= esc_html( $roles_list );
					break;
				case 'emp_num':
					if ( isset( $user_meta['employee_number'] ) ) {
						$r .= implode( ',', $user_meta['employee_number'] );
					}

					break;
				case 'workplace':
					if ( isset( $user_meta['workplace'] ) ) {
						$r .= implode( ',', $user_meta['workplace'] );
					}

					break;
				case 'department':
					if ( isset( $user_meta['department'] ) ) {
						$r .= implode( ',', $user_meta['department'] );
					}

					break;
				case 'main-group':
					if ( isset( $user_meta['main_group'] ) ) {
						$main_group = absint( implode( ',', $user_meta['main_group'] ) );
						$r         .= bp_get_group_name( groups_get_group( $main_group ) );
					}

					break;
				case 'location':
					if ( isset( $user_meta['location'] ) ) {
						$r .= implode( ',', $user_meta['location'] );
					}

					break;
				case 'company':
					if ( isset( $user_meta['company'] ) ) {
						$r .= implode( ',', $user_meta['company'] );
					}

					break;
				case 'skills':
					if ( isset( $user_meta['skills'] ) ) {
						$r .= implode( ',', $user_meta['skills'] );
					}

					break;
				case 'member-type':
					$r .= bp_get_member_type( $user_object->ID );
					break;
				case 'registered':
					$r .= $user_object->user_registered;
					break;
				case 'activity':
					$r .= bp_get_user_last_activity( $user_object->ID );
					break;
				case 'deactivated':
					$r .= ( '1' === $user_object->user_status ) ? 'Deactivated' : '';
					break;
			}

			$r .= '</td>';
		}

		$r .= '</tr>';
		return $r;
	}

	/**
	 * Gets the name of the default primary column.
	 *
	 * @since 4.3.0
	 *
	 * @return string Name of the default primary column, in this case, 'username'.
	 */
	protected function get_default_primary_column_name() {
		return 'username';
	}

	/**
	 * Returns an array of user roles for a given user object.
	 *
	 * @since 4.4.0
	 *
	 * @param WP_User $user_object The WP_User object.
	 * @return string[] An array of user roles.
	 */
	protected function get_role_list( $user_object ) {
		$wp_roles  = wp_roles();
		$role_list = [];
		foreach ( $user_object->roles as $role ) {
			if ( isset( $wp_roles->role_names[ $role ] ) ) {
				$role_list[ $role ] = translate_user_role( $wp_roles->role_names[ $role ] );
			}
		}

		if ( empty( $role_list ) ) {
			$role_list['none'] = _x( 'None', 'no user roles', 'nisje-grieg' );
		}

		return apply_filters( 'get_role_list', $role_list, $user_object );
	}
}
