<?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;
    }

    /**
     * @param array $query_args     An array of configuration parameters.
     * @since 5.6.3
     */
    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;
    }

    /**
     * @param string $output     HTML output generated by wp_dropdown_users().
     * @since 5.6.3
     */
    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 );

    }

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

    /**
     * @param array $params     An array of configuration parameters.
     * @since 5.6.3
     */
    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 );
    }

    /**
     * @param array $params     An array of configuration parameters.
     * @since 5.6.3
     */
    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 );
    }

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

        return $params;
    }

    /**
     * @param array $params     An array of configuration parameters.
     * @since 5.6.3
     */
    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;
    }

    /**
     * @param array $params     An array of configuration parameters.
     * @since 5.6.3
     */
    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'],
        );
    }

    /**
     * @param array $params     An array of configuration parameters.
     * @since 4.0.0
     */
    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;
	}

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

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

        return $configuration;
    }

    public function ajax_autocomplete_users() {
        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 ),
            )
        );
    }
}
