<?php

namespace TotalTheme\Helpers;

defined( 'ABSPATH' ) || exit;

/**
 * Gradient Parser Helper.
 *
 * Provides methods to parse a gradient string into a structured array and
 * build CSS gradient values for linear and radial gradients. Supports
 * late escaping and position sanitization.
 *
 * Usage:
 * ```
 * $gradient = 'type:linear-gradient|c1:#ff0000|c1p:0%|c2:#0000ff|c2p:100%|angle:90';
 * $parsed   = Gradient_Parser::parse( $gradient );
 * $css      = Gradient_Parser::render_css( $gradient );
 * ```
 *
 * @package TotalTheme\Helpers
 * @since 6.6
 */
final class Gradient_Parser {

	/**
     * Parse gradient string into an associative array.
     *
     * @param string|array $value Gradient string or array.
     * @return array Parsed gradient values as associative array.
     */
	public static function parse( $value ): array {
		if ( is_array( $value ) ) {
			return $value;
		}

		if ( ! is_string( $value ) || ! str_contains( $value, '|' ) ) {
			return [];
		}

		$result = [];

		foreach ( explode( '|', $value ) as $part ) {
			[ $key, $val ] = array_pad( explode( ':', $part, 2 ), 2, '' );
			if ( $key !== '' ) {
				$result[ $key ] = $val;
			}
		}

		return $result;
	}

	/**
     * Build CSS gradient string from parsed gradient.
     *
     * @param string|array $gradient Gradient string or parsed array.
     * @param array        $palette Optional palette of colors (not used currently).
     * @return string CSS gradient value, or empty string if invalid.
     */
	public static function render_css( $gradient, array $palette = [] ): string {
		$gradient = self::parse( $gradient );

		if ( empty( $gradient['c1'] ) || empty( $gradient['c2'] ) ) {
			return '';
		}

		$color1 = wpex_parse_color( $gradient['c1'] );
		$color2 = wpex_parse_color( $gradient['c2'] );

		if ( ! $color1 || ! $color2 ) {
			return '';
		}

		$c1p   = self::sanitize_position( $gradient['c1p'] ?? '', '0%' );
		$c2p   = self::sanitize_position( $gradient['c2p'] ?? '', '100%' );
		$type  = ( $gradient['type'] ?? 'linear-gradient' ) === 'radial-gradient' ? 'radial' : 'linear';
		$type  = $type === 'radial' ? 'radial' : 'linear';
		$angle = ( 'linear' === $type && isset( $gradient['angle'] ) ) ? absint( $gradient['angle'] ) : 180;

		if ( 'radial' === $type ) {
			return "radial-gradient({$color1} {$c1p}, {$color2} {$c2p})";
		}

		return "linear-gradient({$angle}deg, {$color1} {$c1p}, {$color2} {$c2p})";
	}

	/**
	 * Sanitize a gradient position value.
	 *
	 * Ensures the value is numeric and returns a percentage string.
	 * Falls back to the default if empty or invalid.
	 *
	 * @param string|int $pos Position value to sanitize.
	 * @param string     $default Default value, e.g. '0%' or '100%'.
	 * @return string    Sanitized position with percent sign.
	 */
	private static function sanitize_position( $pos, string $default = '' ) : string {
		if ( empty( $pos ) ) {
			return $default;
		}
		$pos = (string) $pos;
		$numeric = rtrim( $pos, '%' );
		if ( ! is_numeric( $numeric ) ) {
			return $default;
		}
		$numeric = max( 0, min( 100, intval( $numeric ) ) );
		return "{$numeric}%";
	}

}
