<?php
/**
 * EnablePublishProductDirectly class.
 *
 * @package DokanKits\Features\Vendor
 * @since   3.0.0
 */

namespace DokanKits\Features\Vendor;

use DokanKits\Features\Feature;

/**
 * Enable Publish Product Directly Feature
 *
 * Allows vendors to publish products directly without needing admin approval.
 * This feature is useful for vendors who want to manage their own product listings
 * without waiting for admin review, streamlining the product creation process.
 * By default, Dokan may require admin approval for vendor products, which this
 * feature overrides when enabled.
 *
 * @since   3.0.0
 * @package DokanKits\Features\Vendor
 */
class EnablePublishProductDirectly extends Feature {

	/**
	 * Feature option key for enabling/disabling this feature
	 *
	 * @since 3.0.0
	 * @var string
	 */
	protected string $option_key = 'enable_publish_product_directly_checkbox';

	/**
	 * Feature settings group for admin UI organization
	 *
	 * @since 3.0.0
	 * @var string
	 */
	protected string $settings_group = 'vendor';

	/**
	 * Feature settings section within the group
	 *
	 * @since 3.0.0
	 * @var string
	 */
	protected string $settings_section = 'capabilities';

	/**
	 * Number of sub-features contained in this feature
	 *
	 * @since 3.0.0
	 * @var int
	 */
	protected int $total_features = 1;

	/**
	 * Register hooks with WordPress
	 *
	 * Sets up filters to modify the default product status and
	 * available post statuses for vendors.
	 *
	 * @since 3.0.0
	 * @return void
	 */
	public function register_hooks(): void {
		add_filter( 'dokan_get_default_product_status', array( $this, 'allow_direct_publish' ), 10, 3 );
		add_filter( 'dokan_post_status', array( $this, 'get_available_post_status' ), 99999, 2 );
		add_filter( 'dokan_post_edit_default_status', array( $this, 'set_default_edit_status' ), 99999, 2 );
	}

	/**
	 * Allow vendors to publish products directly
	 *
	 * Changes the default product status to 'publish' for non-trusted vendors
	 * when this feature is enabled, bypassing the normal approval process.
	 *
	 * @since 3.0.0
	 * @param string $status     Current product status.
	 * @param int    $seller_id  Seller ID.
	 * @param bool   $is_trusted Whether the user is a trusted vendor.
	 *
	 * @return string Modified product status.
	 */
	public function allow_direct_publish( string $status, int $seller_id, bool $is_trusted ): string {
		// Don't override if user is already trusted or feature is disabled.
		if ( $is_trusted || ! $this->is_enabled() ) {
			return $status;
		}

		// If the user is a vendor, allow direct publish.
		if ( dokan_is_user_seller( $seller_id ) ) {
			return 'publish';
		}

		return $status; // For other users, return the original status
	}

	/**
	 * Get available post statuses for vendors
	 *
	 * Modifies the available post status options for vendors when
	 * editing their products, ensuring 'publish' is included.
	 *
	 * @since 3.0.0
	 * @param array $post_statuses Current post statuses.
	 *
	 * @return array Modified post statuses.
	 */
	public function get_available_post_status( array $post_statuses ): array {
		if ( ! $this->is_enabled() ) {
			return $post_statuses;
		}

		// Allow vendors to publish products directly.
		if ( dokan_is_user_seller( dokan_get_current_user_id() ) ) {
			// Remove 'pending' statuses if they exists.
			unset( $post_statuses['pending'] );

			// Add 'publish' status if not already present.
			$post_statuses['publish'] = dokan_get_post_status( 'publish' );
		}

		/**
		 * Filter the available post statuses for vendors.
		 *
		 * @since 3.0.0
		 *
		 * @param array $post_statuses Available post statuses.
		 * @param bool  $is_enabled    Whether the feature is enabled.
		 */
		return apply_filters( 'dokan_kits_vendor_post_statuses', $post_statuses, $this->is_enabled() );
	}

	/**
	 * Force publish status in Dokan's product editor when enabled.
	 *
	 * @since 3.1.4
	 *
	 * @param string   $status  Current product status.
	 * @param \WC_Product|null $product Product object when editing.
	 *
	 * @return string
	 */
	public function set_default_edit_status( string $status, $product = null ): string {
		if ( ! $this->is_enabled() ) {
			return $status;
		}

		if ( ! dokan_is_user_seller( dokan_get_current_user_id() ) ) {
			return $status;
		}

		return 'publish';
	}
}
