<?php
/**
 * @since 5.6.3
 */
class WPBDP__Admin__Listing_Owner {

	public static $users = array();

	public $listing_id = 0;

	private $dropdown_users_args_stack = array();

	public function __construct( $post_id = 0 ) {
		$this->listing_id = $post_id;

		add_filter( 'wp_dropdown_users_args', array( $this, '_dropdown_users_args' ), 10, 2 );

		add_action( 'wp_ajax_wpbdp-autocomplete-users', array( $this, 'ajax_autocomplete_users' ) );
	}

	public function set_listing_id( $listing_id ) {
		$this->listing_id = $listing_id;
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $query_args     An array of configuration parameters.
	 */
	public function _dropdown_users_args( $query_args, $r ) {
		if ( isset( $r['wpbdp_skip_dropdown_users_args'] ) ) {
			return $query_args;
		}

		global $post;

		if ( is_admin() && get_post_type( $post ) === WPBDP_POST_TYPE ) {
			add_filter( 'wp_dropdown_users', array( $this, '_dropdown_users' ) );
			array_push( $this->dropdown_users_args_stack, $r );
		}

		$query_args['include_selected'] = true;

		return $query_args;
	}

	/**
	 * @since 5.6.3
	 *
	 * @param string $output     HTML output generated by wp_dropdown_users().
	 */
	public function _dropdown_users( $output ) {
		global $post;

		remove_filter( 'wp_dropdown_users', array( $this, '_dropdown_users' ) );

		if ( ! $this->dropdown_users_args_stack ) {
			return $output;
		}

		$args = array_pop( $this->dropdown_users_args_stack );

		$params = array(
			'default'       => __( 'Please select a user', 'business-directory-plugin' ),
			'id'            => 'authors',
			'name'          => 'post_author',
			'mode'          => null,
			'class'         => array( 'wpbdp-user-selector' ),
			'wrapper_class' => array( 'wpbdp-user-select' ),
			'wrapper_id'    => 'wpbdp-user-select',

		);

		if ( $this->get_mode( $params ) === 'ajax' ) {
			return '';
		}

		return $this->render( $params );
	}

	/**
	 * @since 5.6.3
	 */
	public function render_metabox() {
		$post = get_post( $this->listing_id );

		$params = array(
			'selected'    => (int) $post->post_author,
			'label'       => __( 'Listing Owner', 'business-directory-plugin' ),
			'label_class' => 'screen-reader-text',
			'default'     => __( 'Please select a user', 'business-directory-plugin' ),
			'id'          => 'post_author_override',
			'name'        => 'post_author_override',
			'class'       => array( 'wpbdp-user-selector' ),
		);

		return $this->render( $params );
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	public function render( $params ) {
		return wpbdp_render_page(
			WPBDP_PATH . 'templates/admin/metaboxes-listing-owner.tpl.php',
			$this->prepare_paramaters( $params )
		);
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function prepare_paramaters( $params ) {
		$params = wp_parse_args(
			$params,
			array(
				'label'       => false,
				'label_class' => false,
				'required'    => false,
				'selected'    => null,
				'mode'        => null,
				'users'       => array(),
				'nonce'       => '',
				'listing_id'  => '',
			)
		);

		$params['mode'] = $this->get_mode( $params );

		if ( 'ajax' === $params['mode'] ) {
			return $this->prepare_ajax_mode_parameters( $params );
		}

		return $this->prepare_inline_mode_parameters( $params );
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function get_mode( $params ) {
		if ( $params['mode'] ) {
			return apply_filters( 'wpbdp_admin_listing_owner_mode', $params['mode'] );
		}

		if ( function_exists( 'get_user_count' ) ) {
			// WP 6.0 or higher.
			$user_count = get_user_count();
		} else {
			_deprecated_function( 'count_users', 'WP 6.0', 'WP 6.0+' );
			$users      = count_users();
			$user_count = $users['total_users'];
		}

		$mode = $user_count > 100 ? 'ajax' : 'inline';
		return apply_filters( 'wpbdp_admin_listing_owner_mode', $mode );
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function prepare_ajax_mode_parameters( $params ) {
		$params['configuration'] = $this->get_ajax_mode_configuration( $params );

		return $params;
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function get_ajax_mode_configuration( $params ) {
		$configuration = $this->get_common_configuration( $params );

		$configuration['select2'] = array(
			'ajax' => array(
				'url'      => add_query_arg( 'action', 'wpbdp-autocomplete-users', admin_url( 'admin-ajax.php' ) ),
				'dataType' => 'json',
			),
		);

		$configuration['security']   = wp_create_nonce( 'ajax_autocomplete_users_' . $this->listing_id );
		$configuration['listing_id'] = $this->listing_id;

		return $configuration;
	}

	/**
	 * @since 5.6.3
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function get_common_configuration( $params ) {
		$users = $this->get_all_users();

		return array(
			'selected' => ! empty( $params['selected'] ) ? array(
				'id'   => $params['selected'],
				'text' => $users[ $params['selected'] ],
			) : '',
			'mode'     => $params['mode'],
		);
	}

	/**
	 * @since 4.0.0
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function prepare_inline_mode_parameters( $params ) {
		$params['users']         = $this->get_all_users();
		$params['configuration'] = $this->get_iniline_mode_configuration( $params );
		$params['listing_id']    = $this->listing_id;

		return $params;
	}

	/**
	 * @since 5.9.2
	 */
	private function get_all_users() {
		if ( ! self::$users ) {
			self::$users = wpbdp_users_dropdown();
		}
		return self::$users;
	}

	/**
	 * @since 4.0.0
	 *
	 * @param array $params     An array of configuration parameters.
	 */
	private function get_iniline_mode_configuration( $params ) {
		$configuration = $this->get_common_configuration( $params );

		$configuration['select2'] = array();

		return $configuration;
	}

	public function ajax_autocomplete_users() {
		WPBDP_App_Helper::permission_check();

		global $wpdb;

		$request = wp_unslash( $_REQUEST );

		if ( ! ( isset( $request['security'] ) && isset( $request['listing_id'] ) && wp_verify_nonce( $request['security'], 'ajax_autocomplete_users_' . $request['listing_id'] ) ) ) {
			wp_send_json(
				array(
					'status' => 'fail',
				)
			);
		}

		$users = get_users(
			array(
				'fields'         => array( 'ID', 'user_login' ),
				'search'         => ! empty( $request['term'] ) ? "*{$request['term']}*" : '',
				'search_columns' => array( 'user_login', 'user_nicename', 'display_name' ),
				'number'         => 100,
				'orderby'        => 'ID',
			)
		);

		wp_send_json(
			array(
				'status' => 'ok',
				'items'  => array_values( $users ),
			)
		);
	}
}
