<?php
/**
 * TOC Runtime anchor settings functions.
 *
 * @package AnchorKit_TOC
 */

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

if ( ! function_exists( 'anchorkit_get_runtime_anchor_settings' ) ) {
	/**
	 * Retrieve per-instance anchor overrides (used by Gutenberg/Elementor blocks).
	 *
	 * @return array|null
	 */
	function anchorkit_get_runtime_anchor_settings() {
		if (
			isset( $GLOBALS['anchorkit_runtime_anchor_settings'] ) &&
			is_array( $GLOBALS['anchorkit_runtime_anchor_settings'] ) &&
			! empty( $GLOBALS['anchorkit_runtime_anchor_settings'] )
		) {
			return $GLOBALS['anchorkit_runtime_anchor_settings'];
		}

		return null;
	}
}

if ( ! function_exists( 'anchorkit_set_runtime_anchor_settings' ) ) {
	/**
	 * Persist anchor overrides for the current request.
	 * Subsequent calls only overwrite unset or "auto" values unless $force is true.
	 *
	 * @param string|null $anchor_format  The anchor format.
	 * @param string|null $anchor_prefix  The anchor prefix.
	 * @param array|null  $heading_levels The heading levels.
	 * @param bool        $force          Whether to force overwrite.
	 * @return array|null Previous settings (for reference only).
	 */
	function anchorkit_set_runtime_anchor_settings( $anchor_format = null, $anchor_prefix = null, $heading_levels = null, $force = false ) {
		$previous = anchorkit_get_runtime_anchor_settings();
		$current  = is_array( $previous ) ? $previous : array();
		$updated  = false;

		if ( null !== $anchor_format ) {
			$anchor_format = sanitize_key( $anchor_format );
			if ( ! in_array( $anchor_format, array( 'auto', 'sequential', 'prefixed' ), true ) ) {
				$anchor_format = 'auto';
			}

			if (
				$force ||
				! isset( $current['anchor_format'] ) ||
				'auto' === $current['anchor_format']
			) {
				$current['anchor_format'] = $anchor_format;
				$updated                  = true;
			}
		}

		if ( null !== $anchor_prefix && '' !== $anchor_prefix ) {
			$sanitized_prefix = sanitize_title_with_dashes( $anchor_prefix );
			if ( '' !== $sanitized_prefix ) {
				if ( $force || empty( $current['anchor_prefix'] ) ) {
					$current['anchor_prefix'] = $sanitized_prefix;
					$updated                  = true;
				}
			}
		}

		if ( is_array( $heading_levels ) && ! empty( $heading_levels ) ) {
			$clean_levels = array();
			foreach ( $heading_levels as $level ) {
				$level = strtolower( trim( (string) $level ) );
				if ( preg_match( '/^h[1-6]$/', $level ) ) {
					$clean_levels[] = $level;
				}
			}
			$clean_levels = array_values( array_unique( $clean_levels ) );

			if ( ! empty( $clean_levels ) ) {
				if ( $force || empty( $current['heading_levels'] ) ) {
					$current['heading_levels'] = $clean_levels;
					$updated                   = true;
				}
			}
		}

		if ( $updated ) {
			$GLOBALS['anchorkit_runtime_anchor_settings'] = $current;
		}

		return $previous;
	}
}

if ( ! function_exists( 'anchorkit_find_block_anchor_settings' ) ) {
	/**
	 * Locate the first AnchorKit block inside parsed blocks and return its anchor settings.
	 *
	 * @param array $blocks Parsed block array from parse_blocks().
	 * @return array|null
	 */
	function anchorkit_find_block_anchor_settings( $blocks ) {
		if ( empty( $blocks ) || ! is_array( $blocks ) ) {
			return null;
		}

		foreach ( $blocks as $block ) {
			if ( ! is_array( $block ) ) {
				continue;
			}

			$block_name = isset( $block['blockName'] ) ? $block['blockName'] : '';
			if ( 'anchorkit/table-of-contents' === $block_name ) {
				$attrs          = isset( $block['attrs'] ) && is_array( $block['attrs'] ) ? $block['attrs'] : array();
				$format         = isset( $attrs['anchorFormat'] ) ? $attrs['anchorFormat'] : null;
				$prefix         = isset( $attrs['anchorPrefix'] ) ? $attrs['anchorPrefix'] : null;
				$heading_levels = isset( $attrs['headingLevels'] ) ? $attrs['headingLevels'] : null;

				// If heading levels not in attrs, use block default (WordPress doesn't save default values).
				if ( empty( $heading_levels ) || ! is_array( $heading_levels ) ) {
					$heading_levels = array( 'h2', 'h3', 'h4' ); // Block default from registration.
				}

				$has_custom_format = null !== $format && '' !== $format && 'auto' !== $format;
				$has_custom_prefix = null !== $prefix && '' !== $prefix;

				// IMPORTANT: Always return settings if ANY custom value is set, OR if we have a block.
				// This ensures heading levels are always passed to ID injection.
				$result = array();

				// Add anchor format if custom.
				if ( $has_custom_format ) {
					$result['anchor_format'] = $format;
				}

				// Add prefix if custom.
				if ( $has_custom_prefix ) {
					$result['anchor_prefix'] = $prefix;
				}

				// ALWAYS include heading levels (either from attrs or default).
				// This ensures ID injection uses the same levels as the TOC.
				$result['heading_levels'] = $heading_levels;

				return $result;
			}

			if ( ! empty( $block['innerBlocks'] ) ) {
				$found = anchorkit_find_block_anchor_settings( $block['innerBlocks'] );
				if ( $found ) {
					return $found;
				}
			}
		}

		return null;
	}
}

if ( ! function_exists( 'anchorkit_extract_block_anchor_settings_from_content' ) ) {
	/**
	 * Parse post content and extract anchor settings from the first AnchorKit block.
	 *
	 * @param string $content The post content.
	 * @return array|null
	 */
	function anchorkit_extract_block_anchor_settings_from_content( $content ) {
		if ( empty( $content ) || ! function_exists( 'has_blocks' ) || ! has_blocks( $content ) ) {
			return null;
		}

		if ( ! function_exists( 'parse_blocks' ) ) {
			return null;
		}

		$blocks = parse_blocks( $content );
		return anchorkit_find_block_anchor_settings( $blocks );
	}
}
