<?php
/**
 * Grieg Dashboard
 *
 * @package Nisje
 */

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

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

/**
 * Grieg dashboard class.
 */
class Grieg_Users_Dashboard {
	/**
	 * Base key
	 *
	 * @var string
	 */
	public $base_key = '';

	/**
	 * Base key
	 *
	 * @var string
	 */
	public $base_url = '';

	/**
	 * List table object
	 *
	 * @var object
	 */
	public $list_table;

	/**
	 * Empty constructor
	 */
	public function __construct() {
		$this->base_key = 'grieg-dashboard';
		$this->base_url = 'admin.php?page=grieg-dashboard';
	}

	/**
	 * Init class
	 */
	public function init() {
		add_filter( 'set-screen-option', [ $this, 'set_screen' ], 10, 3 );
		add_action( 'admin_menu', [ $this, 'menu' ] );
	}

	/**
	 * Set screen option.
	 *
	 * @param bool   $keep   Whether to save or skip saving the screen option value. Default false.
	 * @param string $option The option name.
	 * @param int    $value  The number of rows to use.
	 */
	public static function set_screen( bool $keep, string $option, int $value ) {
		return $value;
	}

	/**
	 * Add page menu
	 */
	public function menu() {
		$grieg_hook = add_menu_page(
			esc_html__( 'Custom User Dashboard', 'nisje-grieg' ),
			esc_html__( 'Custom User Dashboard', 'nisje-grieg' ),
			'list_users',
			$this->base_key,
			[ $this, 'view' ]
		);

		add_action( "load-{$grieg_hook}", [ $this, 'load_dashboard' ] );
	}

	/**
	 * Register assets
	 */
	public function load_dashboard() {
		$this->list_object = new \Nisje\Grieg\Dashboard\ListTable\Grieg_List_Table();
		$this->requests();
		$this->screen_option();
	}

	/**
	 * Register assets
	 */
	public function requests() {
		global $wpdb;

		$doaction = $this->list_object->current_action();
		$pagenum  = $this->list_object->get_pagenum();
		$sendback = add_query_arg( 'paged', $pagenum, admin_url( $this->base_url ) );

		if ( $doaction ) {
			$sendback = add_query_arg( 'paged', $pagenum, admin_url( $this->base_url ) );

			switch ( $doaction ) {
				case 'csv':
					$this->parse_csv();
					break;
				case 'excel':
					$this->parse_excel();
					break;
			}

			$sendback = remove_query_arg( [ 'action', 'action2', 'bulk_edit', 'users' ], $sendback );

			wp_safe_redirect( $sendback );
			exit;
		} elseif ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { // phpcs:ignore
			wp_safe_redirect( remove_query_arg( [ '_wp_http_referer', '_wpnonce' ], wp_unslash( $_SERVER['REQUEST_URI'] ) ) ); // phpcs:ignore
			exit;
		}
	}

	/**
	 * Screen options
	 */
	public function screen_option() {
		$option = 'per_page';
		$args   = [
			'label'   => esc_html__( 'Users', 'nisje-grieg' ),
			'default' => 300,
			'option'  => 'grieg_per_page',
		];
		add_screen_option( $option, $args );
	}

	/**
	 * View
	 */
	public function view() {
		$this->list_object->prepare_items();

		$nav = '<a href="' . esc_url( home_url() ) . '">Tilbake til administrasjonsgrensesnittet</a>';
		?>
		<div class="wrap">
			<h1 class="wp-heading-inline"><?php esc_html_e( 'Users', 'nisje-grieg' ); ?></h1>
			<hr class="wp-header-end">

			<?php $this->list_object->views(); ?>
			<form id="posts-filter" method="get" action="<?php echo esc_url( admin_url( $this->base_url ) ); ?>">
				<input type="hidden" name="page" value="grieg-dashboard" />
				<?php $this->list_object->display(); ?>
			</form>

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

	/**
	 * Returns an array of user roles for a given user object.
	 *
	 * @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 );
	}

	/**
	 * Export projects as CSV
	 */
	public function parse_csv() {
		$users = get_users( [
			'number' => 9999,
		] );

		if ( $users ) {
			header( 'Content-Type: text/csv; charset=utf-8' );
			header( 'Content-Disposition: attachment; filename=data-' . current_time( 'timestamp' ) . '.csv' ); // phpcs:ignore

			$output = fopen( 'php://output', 'w' ); // phpcs:ignore

			fputs( $output, $bom = chr(0xEF) . chr(0xBB) . chr(0xBF) ); // phpcs:ignore

			$headings = [
				esc_html__( 'ID', 'nisje-grieg' ),
				esc_html__( 'Username', 'nisje-grieg' ),
				esc_html__( 'Name', 'nisje-grieg' ),
				esc_html__( 'Email', 'nisje-grieg' ),
				esc_html__( 'Workplace', 'nisje-grieg' ),
				esc_html__( 'Department', 'nisje-grieg' ),
				esc_html__( 'Main Group', 'nisje-grieg' ),
				esc_html__( 'Location', 'nisje-grieg' ),
				esc_html__( 'Company', 'nisje-grieg' ),
				esc_html__( 'Skills', 'nisje-grieg' ),
				esc_html__( 'Membertype', 'nisje-grieg' ),
				esc_html__( 'Employee Number', 'nisje-grieg' ),
				esc_html__( 'Role', 'nisje-grieg' ),
				esc_html__( 'Registered', 'nisje-grieg' ),
				esc_html__( 'Last activity', 'nisje-grieg' ),
				esc_html__( 'Deactivated', 'nisje-grieg' ),
			];

			fputcsv( $output, $headings );

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

				$name = '';
				if ( $user->first_name && $user->last_name ) {
					$name .= "$user->first_name $user->last_name";
				} elseif ( $user->first_name ) {
					$name .= $user->first_name;
				} elseif ( $user->last_name ) {
					$name .= $user->last_name;
				} else {
					$name .= 'No name';
				}

				$main_group = '';
				if ( isset( $user_meta['main_group'] ) ) {
					$main_group = absint( implode( ',', $user_meta['main_group'] ) );
					$main_group = bp_get_group_name( groups_get_group( $main_group ) );
				}

				$user_roles = $this->get_role_list( $user );
				$roles_list = implode( ', ', $user_roles );

				$member_type = bp_get_member_type( $user->ID );
				if ( ! $member_type ) {
					$member_type = '';
				}

				$values = [
					$user->ID,
					$user->user_login,
					$name,
					$user->user_email,
					isset( $user_meta['workplace'] ) ? implode( ',', $user_meta['workplace'] ) : '',
					isset( $user_meta['department'] ) ? implode( ',', $user_meta['department'] ) : '',
					$main_group,
					isset( $user_meta['location'] ) ? implode( ',', $user_meta['location'] ) : '',
					isset( $user_meta['company'] ) ? implode( ',', $user_meta['company'] ) : '',
					isset( $user_meta['skills'] ) ? implode( ',', $user_meta['skills'] ) : '',
					$member_type,
					isset( $user_meta['employee_number'] ) ? implode( ',', $user_meta['employee_number'] ) : '',
					$roles_list,
					$user->user_registered,
					bp_get_user_last_activity( $user->ID ),
					( '1' === $user->user_status ) ? 'Deactivated' : '',
				];

				fputcsv( $output, $values );
			}

			fclose( $output ); // phpcs:ignore
			exit;
		}
	}

	/**
	 * Export projects as Excel
	 */
	public function parse_excel() {
		if ( ! class_exists( '\\PhpOffice\\PhpSpreadsheet\\Spreadsheet' ) ) {
			wp_die( 'Missing export class' );
		}

		$users = get_users( [
			'number' => 9999,
		] );

		$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
		$spreadsheet->getActiveSheet()->setTitle( 'Export users 135.grieg.com' );

		if ( $users ) {
			$row_counter = 2;

			foreach ( $users as $user ) {
				$headings = [
					esc_html__( 'ID', 'nisje-grieg' ),
					esc_html__( 'Username', 'nisje-grieg' ),
					esc_html__( 'Name', 'nisje-grieg' ),
					esc_html__( 'Email', 'nisje-grieg' ),
					esc_html__( 'Workplace', 'nisje-grieg' ),
					esc_html__( 'Department', 'nisje-grieg' ),
					esc_html__( 'Main Group', 'nisje-grieg' ),
					esc_html__( 'Location', 'nisje-grieg' ),
					esc_html__( 'Company', 'nisje-grieg' ),
					esc_html__( 'Skills', 'nisje-grieg' ),
					esc_html__( 'Membertype', 'nisje-grieg' ),
					esc_html__( 'Employee Number', 'nisje-grieg' ),
					esc_html__( 'Role', 'nisje-grieg' ),
					esc_html__( 'Registered', 'nisje-grieg' ),
					esc_html__( 'Last activity', 'nisje-grieg' ),
					esc_html__( 'Deactivated', 'nisje-grieg' ),
				];

				$counter = 1;
				foreach ( $headings as $head ) {
					$column = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex( $counter );
					$spreadsheet->setActiveSheetIndex( 0 )->setCellValue( "{$column}1", $head );
					$counter++;
				}

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

				$name = '';
				if ( $user->first_name && $user->last_name ) {
					$name .= "$user->first_name $user->last_name";
				} elseif ( $user->first_name ) {
					$name .= $user->first_name;
				} elseif ( $user->last_name ) {
					$name .= $user->last_name;
				} else {
					$name .= 'No name';
				}

				$main_group = '';
				if ( isset( $user_meta['main_group'] ) ) {
					$main_group = absint( implode( ',', $user_meta['main_group'] ) );
					$main_group = bp_get_group_name( groups_get_group( $main_group ) );
				}

				$user_roles = $this->get_role_list( $user );
				$roles_list = implode( ', ', $user_roles );

				$member_type = bp_get_member_type( $user->ID );
				if ( ! $member_type ) {
					$member_type = '';
				}

				$values = [
					$user->ID,
					$user->user_login,
					$name,
					$user->user_email,
					isset( $user_meta['workplace'] ) ? implode( ',', $user_meta['workplace'] ) : '',
					isset( $user_meta['department'] ) ? implode( ',', $user_meta['department'] ) : '',
					$main_group,
					isset( $user_meta['location'] ) ? implode( ',', $user_meta['location'] ) : '',
					isset( $user_meta['company'] ) ? implode( ',', $user_meta['company'] ) : '',
					isset( $user_meta['skills'] ) ? implode( ',', $user_meta['skills'] ) : '',
					$member_type,
					isset( $user_meta['employee_number'] ) ? implode( ',', $user_meta['employee_number'] ) : '',
					$roles_list,
					$user->user_registered,
					bp_get_user_last_activity( $user->ID ),
					( '1' === $user->user_status ) ? 'Deactivated' : '',
				];

				$counter = 1;
				foreach ( $values as $value ) {
					$column = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex( $counter );
					$spreadsheet->setActiveSheetIndex( 0 )->setCellValue( "{$column}{$row_counter}", $value );
					$counter++;
				}

				$row_counter++;
			}

			foreach ( range( 'A', $spreadsheet->getActiveSheet()->getHighestDataColumn() ) as $col ) {
				$spreadsheet->getActiveSheet()->getColumnDimension( $col )->setAutoSize( true );
			}

			// Set workbook properties.
			$spreadsheet->getProperties()->setCreator( 'Grieg' )->setSubject( 'User export' );

			// Set active sheet index to the first sheet, so Excel opens this as the first sheet.
			$spreadsheet->setActiveSheetIndex( 0 );
			header( 'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' );
			header( 'Content-Disposition: attachment; filename=data-' . current_time( 'timestamp' ) . '.xlsx' ); // phpcs:ignore
			header( 'Cache-Control: max-age=0' );
			// If you're serving to IE 9, then the following may be needed.
			header( 'Cache-Control: max-age=1' );

			// If you're serving to IE over SSL, then the following may be needed.
			header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' ); // Date in the past.
			header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); // always modified.
			header( 'Cache-Control: cache, must-revalidate' ); // HTTP/1.1.
			header( 'Pragma: public' ); // HTTP/1.0.

			$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter( $spreadsheet, 'Xlsx' );
			$writer->save( 'php://output' );

			$spreadsheet->disconnectWorksheets();
			unset( $spreadsheet );

			exit;
		}
	}
}
