<?php
/**
 * Portfolio Utils Class.
 *
 * @package Divi
 * @since ??
 */

namespace ET\Builder\Packages\ModuleUtils;

if ( ! defined( 'ABSPATH' ) ) {
	die( 'Direct access forbidden.' );
}

/**
 * ImageUtils class.
 *
 * This class provides utility methods for grid-based modules with flexbox layouts.
 * Used by Portfolio, Filterable Portfolio, Blog, and Gallery modules.
 *
 * @since ??
 */
class ImageUtils {

	/**
	 * Parse flexType value to extract column fraction.
	 *
	 * This utility function is used by Blog, Gallery, Portfolio and Filterable Portfolio modules
	 * to determine the column fraction from flexType values like "12_24", "6_24", "24_24".
	 *
	 * @since ??
	 *
	 * @param string $flex_type FlexType value like "12_24", "6_24", "24_24".
	 *
	 * @return float Column fraction (0.0 to 1.0). Returns 1.0 on failure.
	 *
	 * @example:
	 * ```php
	 * $fraction = PortfolioUtils::parse_flex_type('12_24');
	 * // Returns: 0.5 (50% width)
	 *
	 * $fraction = PortfolioUtils::parse_flex_type('6_24');
	 * // Returns: 0.25 (25% width)
	 *
	 * $fraction = PortfolioUtils::parse_flex_type('invalid');
	 * // Returns: 1.0 (fallback to full width)
	 * ```
	 */
	public static function parse_flex_type( string $flex_type ): float {
		// Handle empty or invalid input.
		if ( empty( $flex_type ) || ! is_string( $flex_type ) ) {
			return 1.0;
		}

		// Parse flexType format: "numerator_denominator".
		if ( preg_match( '/^(\d+)_(\d+)$/', $flex_type, $matches ) ) {
			$numerator   = (int) $matches[1];
			$denominator = (int) $matches[2];

			// Prevent division by zero.
			if ( 0 === $denominator ) {
				return 1.0;
			}

			// Calculate and clamp fraction between 0.0 and 1.0.
			$fraction = $numerator / $denominator;
			return max( 0.0, min( 1.0, $fraction ) );
		}

		// Return full width for unrecognized formats.
		return 1.0;
	}

	/**
	 * Select optimal image size based on layout and responsive column configuration.
	 *
	 * This utility function determines the best WordPress image size to use for grid-based modules
	 * based on layout type (fullwidth vs grid) and responsive column settings.
	 *
	 * The logic prioritizes image quality by using large images if tablet or desktop need them,
	 * and only uses small images when both tablet and desktop have sufficiently small columns.
	 * Mobile phones always use small images since the screen size makes them sufficient.
	 *
	 * @since ??
	 *
	 * @param array  $attrs           Module attributes containing layout and flexType configuration.
	 * @param string $layout          Layout type ('fullwidth' or 'grid').
	 * @param string $grid_attr_path  Grid attribute path (e.g., 'portfolioGrid' or 'blogGrid').
	 *
	 * @return string WordPress image size name to use.
	 */
	public static function select_optimal_image_size( array $attrs, string $layout, string $grid_attr_path = 'portfolioGrid' ): string {
		// Fullwidth layout uses original aspect ratio.
		if ( 'fullwidth' === $layout ) {
			return 'et-pb-portfolio-image-single'; // 1080×9999.
		}

		// If no attributes provided, use default grid image.
		if ( empty( $attrs ) ) {
			return 'et-pb-portfolio-image'; // 400×284.
		}

		// Grid layout - check all breakpoints with device-specific thresholds.
		$flex_type_attr = $attrs[ $grid_attr_path ]['advanced']['flexType'] ?? [];

		// Device-specific thresholds for large image usage.
		// Note: We skip phone breakpoint since small images are sufficient on mobile regardless of columns.
		$breakpoint_thresholds = [
			'tablet'  => 0.5, // Use large image if column > 1/2 (2/3, 1/1).
			'desktop' => 0.34, // Use large image if column > 1/3 (1/2, 2/3, 1/1).
		];

		// Check tablet and desktop breakpoints - use large image if any needs it.
		foreach ( [ 'tablet', 'desktop' ] as $breakpoint ) {
			$flex_type = $flex_type_attr[ $breakpoint ]['value'] ?? '';
			if ( ! empty( $flex_type ) ) {
				$column_fraction = self::parse_flex_type( $flex_type );
				$threshold       = $breakpoint_thresholds[ $breakpoint ];

				// If column fraction is greater than or equal to threshold, use large image.
				if ( $column_fraction > $threshold ) {
					return 'et-pb-post-main-image-fullwidth'; // 1080×675.
				}
			}
		}

		// Use small image only if both tablet and desktop have many small columns.
		return 'et-pb-portfolio-image'; // 400×284.
	}
}
