<?php
/**
 * Stock helpers.
 *
 * @package WPDudeProducts
 */

declare(strict_types=1);

namespace WPDude\Products\Products;

/**
 * Stock validation and decrement.
 */
final class Stock_Service {

	/**
	 * Available stock for a line (standard or combination).
	 */
	public static function available( int $product_id, string $combination_key = '' ): int {
		if ( Product_Meta::TYPE_OPTIONS === Product_Meta::get_type( $product_id ) ) {
			foreach ( Product_Meta::get_combinations( $product_id ) as $combo ) {
				if ( (string) ( $combo['key'] ?? '' ) === $combination_key ) {
					return max( 0, (int) ( $combo['stock'] ?? 0 ) );
				}
			}
			return 0;
		}
		return max( 0, Product_Meta::get_stock( $product_id ) );
	}

	/**
	 * Unit price in minor units for a line.
	 */
	public static function unit_price_minor( int $product_id, string $combination_key = '' ): int {
		if ( Product_Meta::TYPE_OPTIONS === Product_Meta::get_type( $product_id ) ) {
			foreach ( Product_Meta::get_combinations( $product_id ) as $combo ) {
				if ( (string) ( $combo['key'] ?? '' ) === $combination_key ) {
					$price = max( 0, (int) ( $combo['price'] ?? 0 ) );
					$sale  = max( 0, (int) ( $combo['sale_price'] ?? 0 ) );
					if ( $sale > 0 && $sale < $price ) {
						return $sale;
					}
					return $price;
				}
			}
			return 0;
		}
		return Product_Meta::get_effective_price_minor( $product_id );
	}

	/**
	 * SKU for a line (combination SKU, else standard product SKU).
	 */
	public static function line_sku( int $product_id, string $combination_key = '' ): string {
		if ( '' !== $combination_key ) {
			foreach ( Product_Meta::get_combinations( $product_id ) as $combo ) {
				if ( (string) ( $combo['key'] ?? '' ) === $combination_key ) {
					return Product_Meta::normalize_sku( (string) ( $combo['sku'] ?? '' ) );
				}
			}
			return '';
		}
		return Product_Meta::normalize_sku( Product_Meta::get_sku( $product_id ) );
	}

	/**
	 * Combination image ID, else featured, else first gallery image.
	 */
	public static function line_image_id( int $product_id, string $combination_key = '' ): int {
		if ( '' !== $combination_key ) {
			foreach ( Product_Meta::get_combinations( $product_id ) as $combo ) {
				if ( (string) ( $combo['key'] ?? '' ) === $combination_key ) {
					$id = (int) ( $combo['image_id'] ?? 0 );
					if ( $id > 0 ) {
						return $id;
					}
					break;
				}
			}
		}

		$featured = (int) get_post_thumbnail_id( $product_id );
		if ( $featured > 0 ) {
			return $featured;
		}

		$gallery = Product_Meta::get_gallery( $product_id );
		if ( ! empty( $gallery[0] ) ) {
			return (int) $gallery[0];
		}

		return 0;
	}

	/**
	 * Absolute site image URL for a line (combination → featured → gallery).
	 *
	 * Prefer passing through Stripe_Provider::ensure_public_image_url() before
	 * sending to Checkout so Local hosts still display an image.
	 */
	public static function checkout_image_url( int $product_id, string $combination_key = '' ): string {
		$image_id = self::line_image_id( $product_id, $combination_key );
		if ( $image_id <= 0 ) {
			return '';
		}

		$url = wp_get_attachment_image_url( $image_id, 'full' );
		if ( ! is_string( $url ) || '' === $url ) {
			$url = wp_get_attachment_image_url( $image_id, 'large' );
		}
		if ( ! is_string( $url ) || '' === $url ) {
			$url = wp_get_attachment_url( $image_id );
		}
		if ( ! is_string( $url ) || '' === $url ) {
			return '';
		}

		// Ensure absolute URL.
		if ( 0 === strpos( $url, '//' ) ) {
			$url = ( is_ssl() ? 'https:' : 'http:' ) . $url;
		} elseif ( 0 === strpos( $url, '/' ) ) {
			$url = home_url( $url );
		}

		$url = esc_url_raw( $url );
		if ( '' === $url ) {
			return '';
		}

		/**
		 * Filter the product image URL sent to Stripe Checkout (site URL, before FileLink).
		 *
		 * @param string $url             Image URL.
		 * @param int    $product_id      Product ID.
		 * @param string $combination_key Combination key (empty for standard products).
		 */
		return (string) apply_filters( 'wpdude_dc_checkout_image_url', $url, $product_id, $combination_key );
	}

	/**
	 * Decrement stock once for an order line.
	 *
	 * @return true|\WP_Error
	 */
	public static function decrement( int $product_id, string $combination_key, int $qty ) {
		$qty = max( 1, $qty );

		if ( Product_Meta::TYPE_OPTIONS === Product_Meta::get_type( $product_id ) ) {
			$combinations = Product_Meta::get_combinations( $product_id );
			$found        = false;
			foreach ( $combinations as $i => $combo ) {
				if ( (string) ( $combo['key'] ?? '' ) !== $combination_key ) {
					continue;
				}
				$stock = max( 0, (int) ( $combo['stock'] ?? 0 ) );
				if ( $stock < $qty ) {
					return new \WP_Error( 'insufficient_stock', __( 'Insufficient stock.', 'dude-commerce' ) );
				}
				$combinations[ $i ]['stock'] = $stock - $qty;
				$found = true;
				break;
			}
			if ( ! $found ) {
				return new \WP_Error( 'invalid_combination', __( 'Invalid product combination.', 'dude-commerce' ) );
			}
			Product_Meta::update( $product_id, 'combinations', $combinations );
			return true;
		}

		$stock = Product_Meta::get_stock( $product_id );
		if ( $stock < $qty ) {
			return new \WP_Error( 'insufficient_stock', __( 'Insufficient stock.', 'dude-commerce' ) );
		}
		Product_Meta::update( $product_id, 'stock', $stock - $qty );
		return true;
	}
}
