<?php
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

/**
 * Class for an appointment product's staff type
 */
class WC_Product_Appointment_Staff {

	private $staff;
	private $product;

	/**
	 * Constructor
	 *
	 * @since 1.0.0
	 *
	 * @param int|WP_User $user    User ID or object.
	 * @param WC_Product  $product Product object.
	 */
	public function __construct( $user, $product = false ) {
		if ( $user && is_numeric( $user ) ) {
			// Remove duplicate calls, by only one call per page load.
			$staff_cache = wp_cache_get( 'read_staff_object_' . $user, 'read_staff_object' );

			if ( ! $staff_cache ) {
				$staff_cache = get_user_by( 'id', $user );

				// Delete cache.
				wp_cache_delete( 'read_staff_object_' .  $user, 'read_staff_object' );

				// Set new cache.
				wp_cache_set( 'read_staff_object_' .  $user, $staff_cache, 'read_staff_object' );
			}
			$this->staff = $staff_cache;
		} elseif ( $user instanceof WP_User ) {
			$this->staff = $user;
		} else {
			$this->staff = new WP_User( $user );
		}

		#error_log( var_export( $this->staff->ID, true ) );

		$this->product = is_wc_appointment_product( $product ) ? $product : false;
	}

	/**
     * __isset function.
     *
     * @access public
     * @param string $key Key to check.
     * @return bool
     */
    public function __isset( string $key ) {
		return isset( $this->staff->$key );
	}

	/**
     * __get function.
     *
     * @access public
     * @param string $key Key to get.
     * @return string
     */
    public function __get( string $key ) {
		return $this->staff->$key;
	}

	/**
	 * Return the ID
	 *
	 * @since 1.0.0
	 *
	 * @return int
	 */
	public function get_id() {
		return $this->staff->ID ?? 0;
	}

	/**
	 * Get the display name of the staff member.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public function get_display_name() {
		$display_name = $this->get_id() ? $this->staff->display_name : '';
		return apply_filters( 'wc_appointments_staff_display_name', $display_name, $this );
	}

	/**
     * Get the full name of the staff
     *
     * @since 1.0.0
     *
     * @return string
     */
    public function get_full_name(): string {
		return $this->get_id() ? trim( $this->staff->user_firstname . ' ' . $this->staff->user_lastname ) : '';
	}

	/**
	 * Get the email of the staff
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public function get_email() {
		return $this->get_id() ? $this->staff->user_email : '';
	}

	/**
     * Return the base cost
     *
     * @since 1.0.0
     *
     * @return float
     */
    public function get_base_cost(): float {
		$cost = 0;

		if ( $this->get_id() && $this->product ) {
			$costs = $this->product->get_staff_base_costs();
			$cost  = $costs[ $this->get_id() ] ?? 0;
		}

		return (float) $cost;
	}

	/**
     * Return the capacity of the staff
     *
     * @since 1.0.0
     *
     * @return float
     */
    public function get_qty(): float {
		$qty = 0;

		if ( $this->get_id() && $this->product ) {
			$qtys = $this->product->get_staff_qtys();
			$qty  = $qtys[ $this->get_id() ] ?? 0;
		}

		// Default to product qty, when staff capacity not set on product level.
		if ( ! $qty && $this->product ) {
			$qty = $this->product->get_qty();
		}

		return (float) $qty;
	}

	/**
	 * Return the availability rules
	 *
	 * @since 1.0.0
	 *
	 * @param bool $skip_filters Whether to skip filters.
	 *
	 * @return array
	 */
	public function get_availability( $skip_filters = false ) {
		if ( ! $this->get_id() ) {
			return [];
		}

		$user_availability = WC_Data_Store::load( 'appointments-availability' )->get_all_as_array(
		    [
				[
					'key'     => 'kind',
					'compare' => '=',
					'value'   => 'availability#staff',
				],
				[
					'key'     => 'kind_id',
					'compare' => '=',
					'value'   => $this->get_id(),
				],
			],
		);

		// Skip filters.
		if ( $skip_filters ) {
			return $user_availability;
		}

		return apply_filters( 'wc_appointments_staff_availability', $user_availability, $this, $skip_filters );
	}

	/**
	 * Return the products assigned to staff.
	 *
	 * @since 1.0.0
	 *
	 * @param bool $skip_filters Whether to skip filters.
	 *
	 * @return array
	 */
	public function get_product_ids( $skip_filters = false ) {
		if ( ! $this->get_id() ) {
			return [];
		}

		$user_product_ids = WC_Data_Store::load( 'product-appointment' )->get_appointable_product_ids_for_staff( $this->get_id() );

		if ( ! $user_product_ids ) {
			return [];
		}

		// Skip filters.
		if ( $skip_filters ) {
			return $user_product_ids;
		}

		return apply_filters( 'wc_appointments_staff_products', $user_product_ids, $this, $skip_filters );
	}

}
