<?php
/**
 * lib.php Fonctions partagées par tous les blocs
 * @since 2.4.7
 */

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

/** Définir si c'est un block theme */
add_filter( 'body_class', function ( $classes ) {
	if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) {
		$classes[] = 'eac-block-theme';
	}
	return $classes;
}, 1000 );

/**
 * Crée la route REST pour les tailles d'images disponibles dans WP
 *
 * @return void
 */
add_action( 'rest_api_init', function () {
	register_rest_route(
		'eac-blocks/v1',
		'/image-sizes',
		array(
			'methods'             => WP_REST_Server::READABLE, // GET
			'callback'            => 'eac_rest_get_image_sizes',
			'permission_callback' => function () {
				return current_user_can( 'edit_posts' );
			},
		)
	);
}, 25 );

/**
 * eac_get_registered_image_size
 *
 * @return array
 */
if ( ! function_exists( 'eac_get_registered_image_size' ) ) {
	function eac_get_registered_image_size(): array {
		$sizes = array(
			'thumbnail'    => esc_html__( 'Thumbnail', 'eac-components' ),
			'medium'       => esc_html__( 'Medium', 'eac-components' ),
			'medium_large' => esc_html__( 'Medium-large', 'eac-components' ),
			'large'        => esc_html__( 'Large', 'eac-components' ),
		);

		// Tailles additionnelles via WP core helper (WP 4.7+)
		$additional = wp_get_additional_image_sizes(); // retourne array size_name => [width,height,crop]

		if ( is_array( $additional ) && ! empty( $additional ) ) {
			foreach ( $additional as $name => $props ) {
				$label = apply_filters( 'wp_image_size_label_' . $name, null );
				if ( ! $label ) {
					/* translators: %s = image size name */
					$label = sprintf( esc_html__( 'Custom: %s', 'eac-components' ), esc_html( $name ) );
				}
				$sizes[ esc_html( $name ) ] = esc_html( $label );
			}
		}

		return $sizes;
	}
}

/**
 * eac_rest_get_image_sizes
 *
 * @param WP_REST_Request $request
 *
 * @return WP_REST_Response
 */
if ( ! function_exists( 'eac_rest_get_image_sizes' ) ) {
	function eac_rest_get_image_sizes( WP_REST_Request $request ): WP_REST_Response { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
		/** unset( $request ); */ // pour éviter l'erreur de paramètre non utilisé

		$sizes = eac_get_registered_image_size();

		if ( is_wp_error( $sizes ) ) {
			return rest_ensure_response( $sizes );
		}

		if ( empty( $sizes ) || ! is_array( $sizes ) ) {
			return rest_ensure_response( array() );
		}

		return rest_ensure_response( (array) $sizes );
	}
}

/**
 * eac_get_attachment_data
 * Les information globales d'une image jointe (attachment)
 *
 * @param string $id ID de l'attachment
 * @param string $attachment_size la taille de l'image (thumbnail, medium, large, full, etc.)
 * @param int $nb_words nombre de mots du champ description
 *
 * @return array
 */
if ( ! function_exists( 'eac_get_attachment_data' ) ) {
	function eac_get_attachment_data( string $id, string $attachment_size, int $nb_words = 40 ): array {
		$attachment_array = array();
		$attachment_id    = absint( $id );
		$attachment       = get_post( $attachment_id );

		if ( 0 === $attachment_id || ! $attachment || ! wp_attachment_is_image( $attachment_id ) ) {
			return $attachment_array;
		}

		$srcset      = wp_get_attachment_image_srcset( $attachment_id, $attachment_size );
		$srcsize     = wp_get_attachment_image_sizes( $attachment_id, $attachment_size );
		$image_data  = wp_get_attachment_image_src( $attachment_id, $attachment_size );
		$image_url   = wp_get_attachment_image_url( $attachment_id, $attachment_size );
		$width       = $image_data ? $image_data[1] : 300;
		$height      = $image_data ? $image_data[2] : 300;
		$target_url  = '';
		$attach_alt  = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ? get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) : $attachment->post_title;
		$parent_id   = ! empty( $attachment->post_parent ) && 0 !== $attachment->post_parent ? $attachment->post_parent : false;
		$description = ! empty( $attachment->post_content ) ? wp_trim_words( $attachment->post_content, $nb_words, '...' ) : '';
		$title       = $attachment->post_title;
		$caption     = $attachment->post_excerpt;

		/** Le parent existe colonne 'Uploaded to' de la vue des médias */
		if ( $parent_id ) {
			$post_parent = get_post( $parent_id );
			if ( $post_parent ) {
				$target_url = get_permalink( $parent_id );
				if ( 'product' === get_post_type( $post_parent ) && function_exists( 'wc_get_product' ) ) {
					$product = wc_get_product( $parent_id );
					if ( $product && is_a( $product, 'WC_Product' ) ) {
						$target_url  = $product->get_permalink();
					}
				}
				$excerpt     = eac_get_post_excerpt( $parent_id, $nb_words );
				$description = ! empty( $excerpt ) ? $excerpt : $description;
			}
			/** Pas de parent, on cherche les publications où l'image est utilisée */
		} elseif ( ! $parent_id ) {
			$posts = get_posts(
				array(
					'post_type'      => array( 'product', 'post', 'page' ),
					'post_status'    => 'publish',
					'meta_key'       => '_thumbnail_id',
					'meta_value'     => $attachment_id,
					'posts_per_page' => 1,
				)
			);
			if ( ! is_wp_error( $posts ) && is_array( $posts ) && isset( $posts[0]->ID ) ) {
				$post_parent    = $posts[0];
				$post_parent_id = $post_parent->ID;
				if ( 'product' === get_post_type( $post_parent_id ) && function_exists( 'wc_get_product' ) ) {
					$product = wc_get_product( absint( $post_parent_id ) );
					if ( $product && is_a( $product, 'WC_Product' ) ) {
						$target_url  = $product->get_permalink();
					}
				} else {
					$target_url  = get_permalink( $post_parent_id );
				}
				$excerpt     = eac_get_post_excerpt( $post_parent_id, $nb_words );
				$description = ! empty( $excerpt ) ? $excerpt : $description;
			}
		}

		/** Un champ ACF URL ajouté dans les médias images ? */
		$url = eac_get_acf_url( $attachment_id );
		$target_url = ! empty( $url ) ? $url : $target_url;

		$attachment_array = array(
			'src'         => wp_get_attachment_url( $attachment_id ),
			'srcset'      => $srcset,
			'srcsize'     => $srcsize,
			'alt'         => $attach_alt,
			'caption'     => $caption,
			'description' => $description,
			'image_url'   => $image_url,
			'title'       => $title,
			'width'       => $width,
			'height'      => $height,
			'media_url'   => $target_url,
		);

		return $attachment_array;
	}
}

/** Début gestion du contenu des blocks */

/**
 * eac_get_post_excerpt
 *
 * @param int $post_id
 * @param int $excerpt_length
 *
 * @return string
 */
function eac_get_post_excerpt( int $post_id, int $excerpt_length ): string {
	$the_post      = get_post( $post_id );
	$the_excerpt   = '';
	$the_post_type = $the_post->post_type;

	if ( 'product' === $the_post_type && function_exists( 'wc_get_product' ) ) {
		$product     = wc_get_product( $post_id );
		$the_excerpt = ! empty( $product->get_description() ) ? $product->get_description() : $product->get_short_description();
		return $the_excerpt;
	} elseif ( $the_post ) {
		$the_excerpt = eac_get_gutenberg_content( $the_post );
		if ( empty( $the_excerpt ) ) {
			return '';
		}
		// On supprime tous les shortcode du contenu
		$the_excerpt = strip_shortcodes( $the_excerpt );
		return wp_trim_words( $the_excerpt, $excerpt_length, '...' ); // wp_trim_words fait un strip_all_tags en interne
	}

	return '';
}

/**
 * eac_get_gutenberg_content
 * Extraction du résumé ou du contenu d'un article standard ou Gutenberg
 *
 * @param \WP_post $post
 *
 * @return string
 */
function eac_get_gutenberg_content( \WP_post $post ): string {
	$blocks  = parse_blocks( $post->post_content );
	$excerpt = $post->post_excerpt;
	if ( ! empty( $excerpt ) ) {
		return $excerpt;
	}

	// C'est pas une page gutenberg
	if ( 1 === count( $blocks ) && null === $blocks[0]['blockName'] ) {
		return $post->post_content;
	} else {
		$the_excerpt = eac_get_block_recursively( $blocks, 'core/paragraph' );
		return is_array( $the_excerpt ) && ! empty( $the_excerpt ) ? implode( ' ', $the_excerpt ) : '';
	}
}

/**
 * eac_get_block_recursively
 * Extraction du contenu du block_name avec recherche récursive pour les types de block group
 *
 * @param array $blocks
 * @param string $block_name
 *
 * @return array
 */
function eac_get_block_recursively( array $blocks, string $block_name ): array {
	$block_content = array();
	foreach ( $blocks as $block ) {
		if ( isset( $block['blockName'] ) && $block_name === $block['blockName'] ) {
			$block_content[] = $block['innerHTML'];
		} elseif ( is_array( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) ) {
			$block_content = array_merge( $block_content, eac_get_block_recursively( $block['innerBlocks'], $block_name ) );
		}
	}

	return $block_content;
}
/** Fin gestion du contenu des blocks */

/**
 * eac_get_acf_url
 *
 * @param string $attachment_id
 *
 * @return string
 */
if ( ! function_exists( 'eac_get_acf_url' ) ) {
	function eac_get_acf_url( string $attachment_id = '' ): string {
		$field_value = '';
		if ( empty( $attachment_id ) ) {
			return $field_value;
		}

		$values = get_fields( $attachment_id );

		if ( $values && is_array( $values ) ) {
			foreach ( $values as $name => $value ) {
				$field = get_field_object( $name, $attachment_id );
				if ( ! $field ) {
					continue;
				}

				if ( in_array( $field['type'], array( 'url', 'link', 'page_link' ), true ) ) {
					$val = $field['value'];

					if ( in_array( $field['type'], array( 'url', 'page_link' ), true ) ) {
						// url ou page_link : si tableau, prendre le premier élément
						$field_value = is_array( $val ) ? reset( $val ) : $val;
					} else { // link
						$field_value = is_array( $val ) && isset( $val['url'] ) ? $val['url'] : ( is_string( $val ) ? $val : '' );
					}

					if ( ! empty( $field_value ) ) {
						return (string) $field_value;
					}
				}
			}
		}

		return $field_value;
	}
}

/**
 * eac_is_supported_field_type
 *
 * @param String $type
 *
 * @return bool
 */
if ( ! function_exists( 'eac_is_supported_field_type' ) ) {
	function eac_is_supported_field_type( string $type ): bool {
		if ( empty( $type ) ) {
			return false;
		}
		$supported = array(
			'image',
			'text',
			'textarea',
			'email',
			'url',
			'link',
			'page_link',
			'select',
			'number',
			'date_picker',
			'file',
		);

		return in_array( $type, $supported, true );
	}
}

/**
 * eac_normalize_field_by_type
 *
 * @param array|null $field_obj
 *
 * @return string
 */
if ( ! function_exists( 'eac_normalize_field_by_type' ) ) {
	function eac_normalize_field_by_type( ?array $field_obj = null ): string {
		if ( ! is_array( $field_obj ) || empty( $field_obj['type'] ) ) {
			return $field_value;
		}
		$field_value   = $field_obj['value'];
		$field_type    = $field_obj['type'];
		$return_format = isset( $field_obj['return_format'] ) ? $field_obj['return_format'] : '';
		$prepend       = isset( $field_obj['prepend'] ) ? $field_obj['prepend'] : '';
		$append        = isset( $field_obj['append'] ) ? $field_obj['append'] : '';

		switch ( $field_type ) {
			case 'image':
				switch ( $return_format ) {
					case 'array':
						$field_value = $field_obj['value']['ID'] ?? $field_value;
						break;
					case 'url':
						$field_value = attachment_url_to_postid( $field_obj['value'] ) ? attachment_url_to_postid( $field_obj['value'] ) : $field_value;
						break;
				}
				break;
			case 'text':
			case 'number':
				$field_value = trim( sprintf( '%1$s %2$s %3$s', $prepend ?? '', is_scalar( $field_value ) ? $field_value : '', $append ?? '' ) );
				break;
			case 'select':
				$values = array();
				foreach ( (array) $field_value as $value ) {
					if ( 'array' === $return_format && is_array( $value ) ) {
						$values[] = $value['value'] ?? ( is_scalar( $value ) ? $value : '' );
					} else {
						$values[] = is_scalar( $value ) ? $value : '';
					}
				}
				$field_value = implode( ', ', $values );
				break;
			case 'url':
			case 'page_link':
			case 'link':
				if ( in_array( $field_type, array( 'url', 'page_link' ), true ) ) {
					$field_value = is_array( $field_value ) ? reset( $field_value ) : $field_value;
				} else { // link
					$field_value = is_array( $field_value ) && isset( $field_obj['value']['url'] ) ? $field_obj['value']['url'] : $field_value;
				}
				break;
			case 'file':
				switch ( $return_format ) {
					case 'array':
						$field_value = $field_value['url'] ?? $field_value;
						break;
					case 'id':
						$field_value = wp_get_attachment_url( $field_value ) ? wp_get_attachment_url( $field_value ) : $field_value;
						break;
				}
				break;
			case 'email':
				$email = sanitize_email( $field_value );
				$field_value = ( false !== strpos( $email, '@' ) ) ? sprintf( '%1$s#actus.%2$s', strstr( $email, '@', true ), ltrim( strstr( $email, '@' ), '@' ) ) : '';
				break;
		}
		return $field_value;
	}
}

/**
 * eac_validate_html_tag
 *
 * @param string $tag
 *
 * @return string
 */
if ( ! function_exists( 'eac_validate_html_tag' ) ) {
	function eac_validate_html_tag( string $tag ): string {
		$allowed_html_tags = array(
			'a',
			'article',
			'aside',
			'button',
			'div',
			'footer',
			'h1',
			'h2',
			'h3',
			'h4',
			'h5',
			'h6',
			'header',
			'main',
			'nav',
			'p',
			'section',
			'span',
		);

		return $tag && in_array( strtolower( $tag ), $allowed_html_tags, true ) ? $tag : 'div';
	}
}

/**
 * eac_array_to_html_attrs
 *
 * @param array $attrs
 *
 * @return string
 */
if ( ! function_exists( 'eac_array_to_html_attrs' ) ) {
	function eac_array_to_html_attrs( array $attrs ): string {
		$parts = array();
		foreach ( $attrs as $key => $value ) {
			if ( null === $value || false === $value ) {
				continue;
			}
			// Pour les attributs booléens HTML5 (ex: disabled) on pourrait gérer différemment si nécessaire.
			$parts[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
		}

		return implode( ' ', $parts );
	}
}

/** Icône svg pour le repeater FAQ */
if ( ! function_exists( 'eac_get_svg_icon_arrow' ) ) {
	function eac_get_svg_icon_arrow(): string {
		return '<svg aria-hidden="true" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z"></path></svg>';
	}
}

/**
 * eac_get_prefered_fluid_font
 *
 * Génère l'expression responsive (offset en rem + slope * vw) et la clamp complète.
 * L'offset est converti en rem (via $baseFontSize) ; la pente est exprimée en vw.
 *
 * @param string|float|int $min           Valeur min (ex: '0.9rem' ou 0.9).
 * @param string|float|int $max           Valeur max (ex: '1.3rem' ou 1.3).
 *
 * @return array{middle: string, clamp: string}
 */
if ( ! function_exists( 'eac_get_prefered_fluid_font' ) ) {
	function eac_get_prefered_fluid_font( string $min, string $max ): array {
		$vp_min = 320; // viewport min et max
		$vp_max = 1200;
		$base_font_size = 16.0;
		$precision = 4;
		$trim = static fn( $s ) => trim( (string) $s );

		$min_val = $trim( $min );
		$max_val = $trim( $max );

		if ( '' === $min_val || '' === $max_val ) {
			return array(
				'middle' => '',
				'clamp' => '',
			);
		}

		if ( ! is_numeric( $min_val ) || ! is_numeric( $max_val ) ) {
			return array(
				'middle' => '',
				'clamp' => '',
			);
		}

		$min_num = (float) $min_val; // en rem
		$max_num = (float) $max_val; // en rem

		// convertir en px pour les calculs
		$min_px = $min_num * $base_font_size;
		$max_px = $max_num * $base_font_size;

		$delta_vp = (float) $vp_max - (float) $vp_min;
		if ( 0.0 === $delta_vp ) {
			return array(
				'middle' => '',
				'clamp' => '',
			);
		}

		$slope_per_px = ( $max_px - $min_px ) / $delta_vp;
		$slope_vw = $slope_per_px * 100.0;

		// offset en px pour que à vp_min la formule donne min_px
		$offset_px = $min_px - ( $slope_per_px * (float) $vp_min );

		// convertir offset px en rem
		$offset_rem = $offset_px / $base_font_size;

		$fmt = static function ( $n ) use ( $precision ) {
			$s = number_format( (float) $n, $precision, '.', '' );
			return rtrim( rtrim( $s, '0' ), '.' );
		};

		$offset_str = $fmt( $offset_rem ) . 'rem';
		$slope_str  = $fmt( $slope_vw ) . 'vw';
		$middle     = $offset_str . ' + ' . $slope_str;

		$fmt_rem = static function ( $n ) use ( $precision ) {
			$s = number_format( (float) $n, $precision, '.', '' );
			$s = rtrim( rtrim( $s, '0' ), '.' );
			return $s . 'rem';
		};

		$min_str = $fmt_rem( $min_num );
		$max_str = $fmt_rem( $max_num );

		$clamp = 'clamp(' . $min_str . ', ' . $middle . ', ' . $max_str . ')';

		return array(
			'middle' => $middle,
			'clamp' => $clamp,
		);
	}
}
