<?php

/**
 * Handles user authentication for wiaas
 *
 * User roles are inherited from organization
 *
 * Class Wiaas_Authentication
 */
class Wiaas_Authentication {

	const SUPER_ADMIN_USER_ID = 1;

	public static function init() {
		// authenticate current user
		add_action('determine_current_user', array(__CLASS__, 'authenticate_current_user'), 999);

		// authenticates user on login
		add_filter( 'authenticate', array( __CLASS__, 'authenticate_user_on_login' ), 999, 3);

		add_filter('jwt_auth_token_before_dispatch', array(__CLASS__, 'authenticate_rest_user_on_login'), 999, 2);

		// redirect to dashboard after login
		add_filter( 'login_redirect', array( __CLASS__, 'login_redirect' ) );
	}

	/**
	 * Redirect admin user to dashboard
	 *
	 * @return string
	 */
	public static function login_redirect() {
		return  admin_url('index.php') ;
	}


	/**
	 * Authenticate current user based on roles assigned to organization
	 *
	 * If this is non admin request successfully validate user if he can have customer role.
	 *
	 * If this is admin panel request successfully validate user if has admin panel role selected
	 * and also he still can have that role (role was not removed from his customer organization)
	 *
	 * @param int|false $user_id
	 * @return int|false|WP_Error
	 */
	public static function authenticate_current_user($user_id) {
		// do nothing if user not authenticated, user is super admin or this is REST API request
		if (! $user_id || (int) $user_id === self::SUPER_ADMIN_USER_ID) {
			return $user_id;
		}

		global $current_user;

		if (empty($current_user)) {

			$current_user = new WP_User($user_id);
		}

		$rest_api_slug = rest_get_url_prefix();
		$valid_api_uri = strpos($_SERVER['REQUEST_URI'], $rest_api_slug);

		if ($valid_api_uri) {
			//for non admin request check if user has customer role
			$role = 'customer';
		} else {
			// for admin panel request check if user has selected role
			$role =  get_user_meta($user_id, '_wiaas_admin_role', true);
		}

		if ( empty($role) || ! user_can($user_id, 'wiaas_' . $role)) {
			// not available roles for user
			$current_user->set_role('');

			return new WP_Error('wiaas_authentication_error', 'No set permissions!',  array(
				'status' => 403,
			));
		}

		// authenticate valid admin panel user
		$current_user->set_role($role);

		return $user_id;
	}

	/**
	 * Authenticate wiaas user on login based on roles assigned to organization
	 *
	 * If this is non admin panel request authenticate user if he can be customer.
	 *
	 * If this is admin panel login request user will be authenticated with previously selected or first available role
	 * from his organization roles.
	 *
	 * @param WP_User $user
	 * @return WP_User|WP_Error
	 */
	public static function authenticate_user_on_login($user) {
		// do nothing if there is an error already,
		// user is super admin
		if (is_wp_error($user) || $user->ID === self::SUPER_ADMIN_USER_ID ) {
			return $user;
		}


		$rest_api_slug = rest_get_url_prefix();
		$valid_api_uri = strpos($_SERVER['REQUEST_URI'], $rest_api_slug);


		/**
		 * CUSTOMER API AUTHENTICATION
		 */
		// validate customer user login
		if ($valid_api_uri) {

			$role = user_can($user->ID, 'wiaas_customer') ? 'customer' : '';
			$user->set_role($role);

			return empty($role) ?
				new WP_Error('wiaas_authentication_error', 'No Customer permissions!',  array(
					'status' => 403,
				)) :
				$user;
		}

		/**
		 * ADMIN PANEL AUTHENTICATION
		 */

		// retrieve selected role for user
		$role =  get_user_meta($user->ID, '_wiaas_admin_role', true);
		// if user has selected role then use it
		if (! empty($role) && user_can($user->ID, 'wiaas_' . $role)) {
			return $user;
		}

		// user does not have selected role so try to assign one in order of access
		if (user_can($user->ID, 'wiaas_administrator')) {
			$role = 'administrator';
		} else if (user_can($user->ID, 'wiaas_commercial_lead')) {
			$role = 'commercial_lead';
		} else if (user_can($user->ID, 'wiaas_supplier')) {
			$role = 'supplier';
		}

		if (empty($role)) {
			return new WP_Error('wiaas_authentication_error', 'No permissions!',  array(
				'status' => 403,
			));
		}

		update_user_meta($user->ID, '_wiaas_admin_role', $role);

		$user->set_role($role);

		return $user;
	}

	/**
	 * validate that successfully logged in rest api user can be customer
	 *
	 * @param array $data
	 * @param WP_User $user
	 * @return array | WP_Error
	 *
	 */

	public static function authenticate_rest_user_on_login($data, $user) {
		// if admin do nothing
		if ($user->ID === self::SUPER_ADMIN_USER_ID) {
			return $data;
		}
		$role = user_can($user->ID, 'wiaas_customer') ? 'customer' : '';
		$user->set_role($role);

		return empty($role) ?
			new WP_Error('wiaas_authentication_error', 'No Customer permissions!',  array(
				'status' => 403,
			)) :
			$data;
	}

}

Wiaas_Authentication::init();
