<?php
/**
 * Inventory Sync Handler
 *
 * @package FKWCSQ\Sync
 */

namespace FKWCSQ\Includes\Sync;

use FKWCSQ\Includes\Traits\Instance;
use WC_Product;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Handles inventory synchronization between WooCommerce and Square
 */
class Inventory {
	use Instance;

	/**
	 * Square API instance
	 *
	 * @var \FKWCSQ\Includes\API
	 */
	private $api;

	/**
	 * Constructor
	 */
	private function __construct() {
		$this->api = \FKWCSQ\Includes\API::get_instance();
	}



	/**
	 * Sync inventory from WooCommerce to Square
	 *
	 * @param WC_Product $product WooCommerce product
	 * @return bool Success status
	 * @throws \Exception When syncing with Square API fails
	 */
	public function sync_inventory_to_square( $product ) {
		try {
			// Check if product should sync with Square
			if ( ! \FKWCSQ\Square::should_sync_product_with_square( $product->get_id() ) ) {
				return false;
			}

			$square_id = get_post_meta( $product->get_id(), '_square_variation_id', true );

			if ( ! $square_id ) {
				return false;
			}
			if ( ! $product->managing_stock() ) {
				return false;
			}

			$inventory_data = array(
				'quantity'    => $product->get_stock_quantity(),
				'location_id' => $this->api->get_location_id(),
			);

			$response = $this->api->update_inventory( $square_id, $inventory_data );
			if ( is_wp_error( $response ) ) {
				throw new \Exception( $response->get_error_message() );
			}

			do_action( 'fkwcsq_inventory_synced_to_square', $product->get_id(), $square_id );
			return true;
		} catch ( \Exception $e ) {
			return false;
		}
	}

	/**
	 * Sync inventory from Square to WooCommerce
	 *
	 * @param array $square_data Square inventory data
	 * @return bool Success status
	 */
	public function sync_inventory_from_square( $square_data ) {
		try {
			$product_id = $this->find_product_by_square_id( $square_data['variation_id'] );
			if ( ! $product_id ) {
				return false;
			}

			$product = wc_get_product( $product_id );
			if ( ! $product ) {
				return false;
			}
			if ( ! $product->managing_stock() ) {
				return false;
			}

			$product->set_stock_quantity( $square_data['quantity'] );
			$product->save();

			do_action( 'fkwcsq_inventory_synced_from_square', $product_id, $square_data );
			return true;
		} catch ( \Exception $e ) {
			return false;
		}
	}

	/**
	 * Find WooCommerce product by Square variation ID
	 *
	 * @param string $square_variation_id Square variation ID
	 *
	 * @return int|false Product ID or false if not found
	 */
	private function find_product_by_square_id( $square_variation_id ) {
		$args = array(
			'post_type'      => array( 'product', 'product_variation' ),
			'post_status'    => 'publish',
			'meta_key'       => '_square_id', //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Necessary for Square integration lookup
			'meta_value'     => $square_variation_id, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Necessary for Square integration lookup
			'fields'         => 'ids',
			'posts_per_page' => 1,
		);

		$products = get_posts( $args );

		return ! empty( $products ) ? $products[0] : false;
	}
	/**
	 * Schedule batch sync of all inventory
	 *
	 * @return array Summary of sync results
	 */
	public function schedule_batch_sync() {
		try {
			$total_products = 0;
			$success_count  = 0;
			$failed_count   = 0;
			$success_ids    = array();
			$failed_ids     = array();
			$errors         = array();

			// Get all products with Square IDs and sync enabled
			$products = wc_get_products(
				array(
					'status'     => 'publish',
					'limit'      => -1,
					'return'     => 'ids',
					'meta_query' => array( //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Necessary for Square integration batch sync
						array(
							'key'     => '_square_id',
							'compare' => 'EXISTS',
						),
						array(
							'key'     => '_wc_square_synced',
							'value'   => 'yes',
							'compare' => '=',
						),
					),
				)
			);

			$total_products = is_array( $products ) ? count( $products ) : 0;

			if ( empty( $products ) ) {
				return array(
					'total'       => 0,
					'success'     => 0,
					'failed'      => 0,
					'success_ids' => array(),
					'failed_ids'  => array(),
					'errors'      => array(),
				);
			}

			// Process each product
			foreach ( $products as $product_id ) {
				try {
					$product = wc_get_product( $product_id );
					if ( $product && $this->sync_inventory_to_square( $product ) ) {
						++$success_count;
						$success_ids[] = $product_id;
					} else {
						++$failed_count;
						$failed_ids[] = $product_id;
						$errors[]     = sprintf( 'Product #%d: inventory sync failed', $product_id );
					}
				} catch ( \Exception $e ) {
					++$failed_count;
					$failed_ids[] = $product_id;
					$errors[]     = sprintf( 'Product #%d: %s', $product_id, $e->getMessage() );
				}

				// Add a small delay to avoid API rate limits
				usleep( 200000 ); // 200ms pause between products
			}

			return array(
				'total'       => $total_products,
				'success'     => $success_count,
				'failed'      => $failed_count,
				'success_ids' => $success_ids,
				'failed_ids'  => $failed_ids,
				'errors'      => $errors,
			);

		} catch ( \Exception $e ) {
			return array(
				'total'       => 0,
				'success'     => 0,
				'failed'      => 0,
				'success_ids' => array(),
				'failed_ids'  => array(),
				'errors'      => array( $e->getMessage() ),
			);
		}
	}
}
