<?php
/**
 * Product pricing helper utilities.
 *
 * @package FoodOrd
 */

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

/**
 * Class Foodord_Product_Pricing
 */
class Foodord_Product_Pricing {
	/**
	 * Maximum allowed price value.
	 */
	private const MAX_PRICE = 1000000;

	/**
	 * Update WooCommerce product pricing details.
	 *
	 * @param int   $product_id Product identifier.
	 * @param array $payload    Pricing payload.
	 *
	 * @return array|WP_Error Updated payload or error.
	 */
	public static function update_prices( int $product_id, array $payload ) {
		if ( ! function_exists( 'wc_get_product' ) ) {
			return new WP_Error(
				'woocommerce_inactive',
				__( 'WooCommerce is not active.', 'foodord' ),
				array( 'status' => 500 )
			);
		}

		if ( $product_id <= 0 ) {
			return new WP_Error(
				'invalid_product',
				__( 'Invalid product identifier.', 'foodord' ),
				array( 'status' => 400 )
			);
		}

		$product = wc_get_product( $product_id );
		if ( ! $product instanceof WC_Product ) {
			return new WP_Error(
				'product_not_found',
				__( 'Product not found.', 'foodord' ),
				array( 'status' => 404 )
			);
		}

		$variation_id = isset( $payload['variation_id'] ) ? absint( $payload['variation_id'] ) : 0;
		$target       = $product;
		$variation    = null;

		if ( $variation_id > 0 ) {
			$variation = wc_get_product( $variation_id );
			if ( ! $variation instanceof WC_Product_Variation ) {
				return new WP_Error(
					'variation_not_found',
					__( 'Variation not found.', 'foodord' ),
					array( 'status' => 404 )
				);
			}

			if ( $variation->get_parent_id() !== $product_id ) {
				return new WP_Error(
					'variation_mismatch',
					__( 'Variation does not belong to the selected product.', 'foodord' ),
					array( 'status' => 400 )
				);
			}

			$target = $variation;
		}

		$has_sale_input = array_key_exists( 'sale_price', $payload );

		$price_value = self::normalize_price_value( $payload['price'] ?? null, 'price' );
		if ( is_wp_error( $price_value ) ) {
			return $price_value;
		}

		$regular_value = self::normalize_price_value( $payload['regular_price'] ?? null, 'regular_price' );
		if ( is_wp_error( $regular_value ) ) {
			return $regular_value;
		}

		$sale_value = self::normalize_price_value( $payload['sale_price'] ?? null, 'sale_price', true );
		if ( is_wp_error( $sale_value ) ) {
			return $sale_value;
		}

		if ( null === $price_value && null === $regular_value && null === $sale_value ) {
			return new WP_Error(
				'missing_price',
				__( 'At least one price value must be provided.', 'foodord' ),
				array( 'status' => 400 )
			);
		}

		if ( null !== $regular_value && '' !== $regular_value && null !== $sale_value && '' !== $sale_value ) {
			if ( (float) $sale_value > (float) $regular_value ) {
				return new WP_Error(
					'invalid_sale_price',
					__( 'Sale price cannot exceed the regular price.', 'foodord' ),
					array( 'status' => 400 )
				);
			}
		}

		// Fallbacks to keep price consistent.
		if ( null === $regular_value && null !== $price_value ) {
			$regular_value = $price_value;
		}

		if ( null === $price_value ) {
			if ( null !== $sale_value && '' !== $sale_value ) {
				$price_value = $sale_value;
			} elseif ( null !== $regular_value ) {
				$price_value = $regular_value;
			}
		}

		if ( null !== $regular_value ) {
			$target->set_regular_price( $regular_value );
		}

		if ( null !== $sale_value ) {
			$target->set_sale_price( $sale_value );
			if ( '' === $sale_value && method_exists( $target, 'set_date_on_sale_from' ) ) {
				$target->set_date_on_sale_from( null );
			}
			if ( '' === $sale_value && method_exists( $target, 'set_date_on_sale_to' ) ) {
				$target->set_date_on_sale_to( null );
			}
		} elseif ( ! $has_sale_input && '' !== $target->get_sale_price() ) {
			$target->set_sale_price( '' );
			if ( method_exists( $target, 'set_date_on_sale_from' ) ) {
				$target->set_date_on_sale_from( null );
			}
			if ( method_exists( $target, 'set_date_on_sale_to' ) ) {
				$target->set_date_on_sale_to( null );
			}
		}

		if ( null !== $price_value ) {
			$target->set_price( $price_value );
		}

		$target->save();

		if ( $variation instanceof WC_Product_Variation ) {
			wc_delete_product_transients( $variation_id );
			clean_post_cache( $variation_id );
			if ( function_exists( 'wc_update_product_lookup_tables' ) ) {
				wc_update_product_lookup_tables( $variation_id );
			}
			if ( class_exists( 'WC_Product_Variable' ) ) {
				WC_Product_Variable::sync( $product_id );
			}
		}

		$fresh_product = wc_get_product( $product_id );
		if ( ! $fresh_product instanceof WC_Product ) {
			$fresh_product = $product;
		}

		wc_delete_product_transients( $product_id );
		clean_post_cache( $product_id );
		wp_cache_delete( $product_id, 'post_meta' );
		if ( function_exists( 'wc_update_product_lookup_tables' ) ) {
			wc_update_product_lookup_tables( $product_id );
		}
		if ( class_exists( 'WC_Cache_Helper' ) ) {
			WC_Cache_Helper::invalidate_cache_group( 'products' );
			WC_Cache_Helper::invalidate_cache_group( 'product_query' );
		}

		$currency       = get_woocommerce_currency();
		$prices_payload = array(
			'price'         => $target->get_price(),
			'regular_price' => $target->get_regular_price(),
			'sale_price'    => $target->get_sale_price(),
			'currency'      => $currency,
			'price_html'    => $target->get_price_html(),
		);

		$response = array(
			'id'      => $product_id,
			'prices'  => $prices_payload,
			'product' => Foodord_Product_Availability::build_rest_payload( $fresh_product ),
		);

		if ( $variation_id > 0 ) {
			$response['variation_id'] = $variation_id;
		}

		return $response;
	}

	/**
	 * Normalize price value from payload.
	 *
	 * @param mixed  $value       Raw value.
	 * @param string $field       Field name for errors.
	 * @param bool   $allow_empty Allow empty string (for sale price reset).
	 *
	 * @return string|null|WP_Error Normalized decimal string, null if omitted or error on failure.
	 */
	private static function normalize_price_value( $value, string $field, bool $allow_empty = false ) {
		if ( null === $value ) {
			return null;
		}

		if ( is_string( $value ) ) {
			$value = trim( $value );
			if ( '' === $value ) {
				return $allow_empty ? '' : null;
			}
		}

		if ( is_bool( $value ) || is_array( $value ) || is_object( $value ) ) {
			return new WP_Error(
				'invalid_price_format',
				// translators: %s: field name (e.g. price, regular_price, sale_price).
				sprintf( __( 'Invalid %s value. Provide a numeric amount.', 'foodord' ), $field ),
				array( 'status' => 400 )
			);
		}

		$scalar = (string) $value;
		$scalar = preg_replace( '/[^0-9,\.\-]/', '', $scalar );
		$scalar = str_replace( ',', '.', $scalar );

		if ( '' === $scalar ) {
			return $allow_empty ? '' : null;
		}

		if ( ! is_numeric( $scalar ) ) {
			return new WP_Error(
				'invalid_price_format',
				// translators: %s: field name (e.g. price, regular_price, sale_price).
				sprintf( __( 'Invalid %s value. Provide a numeric amount.', 'foodord' ), $field ),
				array( 'status' => 400 )
			);
		}

		$decimal = wc_format_decimal( $scalar, wc_get_price_decimals() );
		if ( '' === $decimal ) {
			$decimal = '0';
		}

		$value_float = (float) $decimal;
		if ( $value_float < 0 ) {
			return new WP_Error(
				'invalid_price_negative',
				// translators: %s: field name (e.g. price, regular_price, sale_price).
				sprintf( __( '%s cannot be negative.', 'foodord' ), $field ),
				array( 'status' => 400 )
			);
		}

		if ( $value_float > self::MAX_PRICE ) {
			return new WP_Error(
				'invalid_price_range',
				// translators: %s: field name (e.g. price, regular_price, sale_price).
				sprintf( __( '%s exceeds the allowed range.', 'foodord' ), $field ),
				array( 'status' => 400 )
			);
		}

		return $decimal;
	}
}
