<?php
/**
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
 *
 * This source code is licensed under the license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @package FacebookCommerce
 */

namespace SkyVerge\WooCommerce\Facebook\Products;

defined( 'ABSPATH' ) or exit;

use SkyVerge\WooCommerce\Facebook\Products;

/**
 * The product stock handler.
 *
 * @since 2.0.5
 */
class Stock {


	/**
	 * Stock constructor.
	 *
	 * @since 2.0.5
	 */
	public function __construct() {

		$this->add_hooks();
	}


	/**
	 * Adds needed hooks to keep product stock in sync.
	 *
	 * @since 2.0.5
	 */
	private function add_hooks() {

		add_action( 'woocommerce_variation_set_stock', [ $this, 'set_product_stock' ] );
		add_action( 'woocommerce_product_set_stock',   [ $this, 'set_product_stock' ] );
	}


	/**
	 * Attempts to sync a product when its stock changes.
	 *
	 * @internal
	 *
	 * @since 2.0.5
	 *
	 * @param \WC_Product $product the product that was updated
	 */
	public function set_product_stock( $product ) {

		if ( ! $product instanceof \WC_Product ) {
			return;
		}

		foreach ( $this->get_products_to_sync( $product ) as $item ) {
			$this->maybe_sync_product_stock_status( $item );
		}
	}


	/**
	 * Gets an array of product objects that could be synced using the Batch API.
	 *
	 * This method returns the product variations of variable products, or the product itself for other product types.
	 * Variable products cannot be synced through the Batch API as they are represented as Product Groups instead of Product Items on Facebook.
	 *
	 * @since 2.0.5
	 *
	 * @param \WC_Product $product a product object
	 * @return \WC_Product[]
	 */
	private function get_products_to_sync( \WC_Product $product ) {

		if ( $product->is_type( 'variable' ) ) {

			return array_filter( array_map( 'wc_get_product', $product->get_children() ), function ( $item ) {
				return $item instanceof \WC_Product;
			} );
		}

		return [ $product ];
	}


	/**
	 * Schedules a product sync to update the product's stock status.
	 *
	 * The product is removed from Facebook if it is out of stock and the plugin is configured to remove out of stock products from the catalog.
	 *
	 * @since 2.0.5
	 *
	 * @param \WC_Product $product a product object
	 */
	private function maybe_sync_product_stock_status( \WC_Product $product ) {

		if ( Products::product_should_be_deleted( $product ) ) {

			facebook_for_woocommerce()->get_products_sync_handler()->delete_products( [ \WC_Facebookcommerce_Utils::get_fb_retailer_id( $product ) ] );
			return;
		}

		facebook_for_woocommerce()->get_products_sync_handler()->create_or_update_products( [ $product->get_id() ] );
	}


}
