<?php
/** Exact provider contract for the bounded Kadence Count Up writer. */

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

/** @param array<string,mixed> $attributes @return array<string,mixed> */
function wpagent_builder_block_kadence_countup_normalize_attributes( array $attributes ): array {
	$type    = WP_Block_Type_Registry::get_instance()->get_registered( 'kadence/countup' );
	$schemas = $type instanceof WP_Block_Type ? $type->get_attributes() : array();
	$defaults = array();
	foreach ( array( 'start', 'end', 'duration', 'prefix', 'suffix', 'separator', 'decimal', 'decimalSpaces' ) as $field ) {
		if ( isset( $schemas[ $field ] ) && is_array( $schemas[ $field ] ) && array_key_exists( 'default', $schemas[ $field ] ) ) {
			$defaults[ $field ] = $schemas[ $field ]['default'];
		}
	}
	return array_merge( $defaults, $attributes );
}

/** @param array<string,mixed> $attributes @return string|WP_Error */
function wpagent_builder_block_kadence_countup_markup( array $attributes ) {
	$attributes = wpagent_builder_block_kadence_countup_normalize_attributes( $attributes );
	$unique_id = is_string( $attributes['uniqueID'] ?? null ) ? $attributes['uniqueID'] : '';
	$type      = WP_Block_Type_Registry::get_instance()->get_registered( 'kadence/countup' );
	$callback  = $type instanceof WP_Block_Type ? $type->render_callback : null;
	if ( ! $type instanceof WP_Block_Type || ! is_array( $callback ) || 2 !== count( $callback )
		|| ! isset( $callback[0] ) || ! $callback[0] instanceof Kadence_Blocks_Countup_Block
		|| 'render_css' !== ( $callback[1] ?? null ) || ! is_callable( $callback ) ) {
		return new WP_Error( 'wpagent_builder_block_countup_provider', __( 'Der Kadence-Count-Up-Block stimmt nicht mit dem eng geprüften Serververtrag überein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$force_static = static fn(): bool => true;
	add_filter( 'kadence-blocks-countup-static', $force_static, PHP_INT_MAX );
	try {
		$markup = $callback[0]->build_html( $attributes, $unique_id, '', null );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_builder_block_countup_markup', $error->getMessage(), array( 'status' => 409 ) );
	} finally {
		remove_filter( 'kadence-blocks-countup-static', $force_static, PHP_INT_MAX );
	}
	if ( ! is_string( $markup ) || '' === $markup || strlen( $markup ) > 8192 ) {
		return new WP_Error( 'wpagent_builder_block_countup_markup', __( 'Der Kadence-Count-Up-Provider erzeugte kein begrenztes kanonisches Markup.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return $markup;
}

/** @param array<string,mixed> $block */
function wpagent_builder_block_kadence_countup_valid( array $block ): bool {
	$name          = is_string( $block['blockName'] ?? null ) ? $block['blockName'] : '';
	$type          = WP_Block_Type_Registry::get_instance()->get_registered( $name );
	$callback      = $type instanceof WP_Block_Type ? $type->render_callback : null;
	$schemas       = $type instanceof WP_Block_Type ? $type->get_attributes() : array();
	$stored_attrs  = is_array( $block['attrs'] ?? null ) ? $block['attrs'] : array();
	$attrs         = wpagent_builder_block_kadence_countup_normalize_attributes( $stored_attrs );
	$allowed_attrs = array( 'uniqueID', 'start', 'end', 'duration', 'prefix', 'suffix', 'separator', 'decimal', 'decimalSpaces', 'numberColor' );
	$unique_id     = is_string( $attrs['uniqueID'] ?? null ) ? $attrs['uniqueID'] : '';
	foreach ( array( 'start', 'end', 'duration' ) as $field ) {
		$value = $attrs[ $field ] ?? null;
		if ( ( ! is_int( $value ) && ! is_float( $value ) ) || ! is_finite( (float) $value ) || abs( (float) $value ) > 1000000 ) {
			return false;
		}
	}
	if ( (float) $attrs['duration'] < 0.1 || (float) $attrs['duration'] > 60 ) {
		return false;
	}
	foreach ( array( 'prefix', 'suffix' ) as $field ) {
		$schema = $schemas[ $field ] ?? null;
		if ( ! is_string( $attrs[ $field ] ?? null ) || ! is_array( $schema )
			|| 1 !== preg_match( '/\A[^\x00-\x1F\x7F<>{}]{0,40}\z/uD', $attrs[ $field ] )
			|| is_wp_error( wpagent_native_block_validate_patch_value( $field, $attrs[ $field ], $schema ) ) ) {
			return false;
		}
	}
	if ( ! in_array( $attrs['separator'] ?? null, array( '', ',', '.', ' ' ), true )
		|| ! in_array( $attrs['decimal'] ?? null, array( '', '.', ',' ), true )
		|| ! is_int( $attrs['decimalSpaces'] ?? null ) || $attrs['decimalSpaces'] < 0 || $attrs['decimalSpaces'] > 6
		|| ( array_key_exists( 'numberColor', $attrs ) && ( ! is_string( $attrs['numberColor'] ) || 1 !== preg_match( '/^#[a-f0-9]{6}$/Di', $attrs['numberColor'] ) ) ) ) {
		return false;
	}
	$expected_markup = wpagent_builder_block_kadence_countup_markup( $attrs );
	return 'kadence/countup' === $name
		&& $type instanceof WP_Block_Type
		&& is_array( $callback ) && 2 === count( $callback )
		&& isset( $callback[0] ) && $callback[0] instanceof Kadence_Blocks_Countup_Block
		&& 'render_css' === ( $callback[1] ?? null ) && is_callable( $callback )
		&& ! array_diff( array_keys( $stored_attrs ), $allowed_attrs )
		&& 1 === preg_match( '/^[A-Za-z0-9_-]{6,64}$/D', $unique_id )
		&& isset( $block['innerBlocks'] ) && array() === $block['innerBlocks']
		&& is_string( $expected_markup )
		&& $expected_markup === ( $block['innerHTML'] ?? null )
		&& array( $expected_markup ) === ( $block['innerContent'] ?? null );
}

/** @param array<string,mixed> $block @param array<string,mixed> $before @param array<string,mixed> $after @return true|WP_Error */
function wpagent_builder_block_sync_kadence_countup_markup( array &$block, array $before, array $after ) {
	$before_markup = wpagent_builder_block_kadence_countup_markup( $before );
	$after_markup  = wpagent_builder_block_kadence_countup_markup( $after );
	if ( is_wp_error( $before_markup ) || is_wp_error( $after_markup )
		|| $before_markup !== ( $block['innerHTML'] ?? null ) || array( $before_markup ) !== ( $block['innerContent'] ?? null ) ) {
		return new WP_Error( 'wpagent_builder_block_countup_markup', __( 'Das gespeicherte Kadence-Count-Up-Markup stimmt nicht mit dem eng geprüften Providerzustand überein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$block['innerHTML']    = $after_markup;
	$block['innerContent'] = array( $after_markup );
	return true;
}
