<?php
/**
 * AnchorKit ACF Integration
 *
 * This file provides integration with the Advanced Custom Fields (ACF) plugin.
 * It does NOT include or bundle any library - it only uses ACF's public API
 * functions (get_field, get_fields) when ACF is installed and active.
 *
 * @package AnchorKit_TOC
 * @since 1.0.0
 */

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

/**
 * Extract content from ACF fields (Pro feature).
 *
 * @param int         $post_id              Post ID.
 * @param string|null $override_field_names Optional comma-separated list of ACF field names.
 * @return string Extracted ACF content as HTML.
 */
if ( ! function_exists( 'anchorkit_extract_acf_content' ) ) {
	function anchorkit_extract_acf_content( $post_id, $override_field_names = null ) {
		$acf_content = '';

		// Check if ACF is active.
		if ( ! function_exists( 'get_field' ) || ! function_exists( 'get_fields' ) ) {
			return $acf_content;
		}

		// Get ACF settings.
		// If override_field_names is explicitly set (even to empty), use it to override global settings.
		// If override_field_names is null/empty and not explicitly set, use global settings.
		$acf_field_names     = null !== $override_field_names ? $override_field_names : anchorkit_get_option( 'anchorkit_toc_acf_field_names', '' );
		$fields_to_scan      = array();
		$explicitly_disabled = false;

		if ( '' !== $acf_field_names && ! empty( $acf_field_names ) ) {
			// User specified field names (not empty).
			$fields_to_scan = array_map( 'trim', explode( ',', $acf_field_names ) );
			$fields_to_scan = array_filter( $fields_to_scan );
		} elseif ( null !== $override_field_names && '' === $acf_field_names ) {
			// CRITICAL FIX: User explicitly cleared the field names in widget settings.
			// This means they want NO ACF fields, not ALL ACF fields.
			$explicitly_disabled = true;
		}

		// If ACF was explicitly disabled by clearing field names, return empty content.
		if ( $explicitly_disabled ) {
			return $acf_content;
		}

		// If specific fields are requested, fetch them individually (more robust in AJAX/Editor).
		if ( ! empty( $fields_to_scan ) ) {
			foreach ( $fields_to_scan as $field_name ) {
				$field_value = get_field( $field_name, $post_id );

				if ( empty( $field_value ) ) {
					continue;
				}

				// Handle different field types.
				if ( is_string( $field_value ) ) {
					// WYSIWYG, textarea, or text fields.
					// Only include if it contains HTML headings.
					if ( preg_match( '/<h[1-6][^>]*>/i', $field_value ) ) {
						$acf_content .= $field_value . "\n\n";
					}
				} elseif ( is_array( $field_value ) ) {
					// Handle flexible content, repeater, etc.
					$acf_content .= anchorkit_extract_acf_array_content( $field_value );
				}
			}

			return $acf_content;
		}

		// Fallback: Get all ACF fields for this post if no specific fields requested.
		$all_fields = get_fields( $post_id );

		if ( empty( $all_fields ) ) {
			return $acf_content;
		}

		foreach ( $all_fields as $field_name => $field_value ) {
			// Skip empty values.
			if ( empty( $field_value ) ) {
				continue;
			}

			// Handle different field types.
			if ( is_string( $field_value ) ) {
				// WYSIWYG, textarea, or text fields.
				// Only include if it contains HTML headings.
				if ( preg_match( '/<h[1-6][^>]*>/i', $field_value ) ) {
					$acf_content .= $field_value . "\n\n";
				}
			} elseif ( is_array( $field_value ) ) {
				// Handle flexible content, repeater, etc.
				$acf_content .= anchorkit_extract_acf_array_content( $field_value );
			}
		}

		return $acf_content;
	}
}

/**
 * Recursively extract content from ACF array fields (flexible content, repeater, etc.).
 *
 * @param array $array ACF field array.
 * @return string Extracted content.
 */
if ( ! function_exists( 'anchorkit_extract_acf_array_content' ) ) {
	function anchorkit_extract_acf_array_content( $array ) {
		$content = '';

		foreach ( $array as $item ) {
			if ( is_string( $item ) && preg_match( '/<h[1-6][^>]*>/i', $item ) ) {
				$content .= $item . "\n\n";
			} elseif ( is_array( $item ) ) {
				$content .= anchorkit_extract_acf_array_content( $item );
			}
		}

		return $content;
	}
}

/**
 * Inject extracted ACF content into the rendered post so anchor targets exist on the page.
 * Runs before heading IDs are added to ensure the new markup is processed like normal content.
 *
 * @param string $content The post content.
 * @return string The merged content.
 */
if ( ! function_exists( 'anchorkit_merge_acf_content_into_display' ) ) {
	function anchorkit_merge_acf_content_into_display( $content ) {
		// Only run on real frontend requests for singular entries.
		if ( ! is_string( $content ) || '' === $content ) {
			return $content;
		}

		if ( is_admin() || wp_doing_ajax() || wp_doing_cron() ) {
			return $content;
		}

		if ( ! is_singular() || ! in_the_loop() || ! is_main_query() ) {
			return $content;
		}

		$post_types = anchorkit_get_option( 'anchorkit_toc_post_types', array( 'post', 'page' ) );
		if ( ! in_array( get_post_type(), $post_types, true ) ) {
			return $content;
		}

		if ( false !== strpos( $content, 'data-anchorkit-acf-content' ) ) {
			return $content;
		}

		global $post;
		if ( ! $post || ! $post->ID ) {
			return $content;
		}

		if ( ! anchorkit_get_option( 'anchorkit_toc_enabled', false ) ) {
			return $content;
		}

		// ACF integration is a pro feature - this block is stripped by Freemius.
		if ( anchorkit_fs() && anchorkit_fs()->is__premium_only() ) {
			if ( ! anchorkit_fs()->can_use_premium_code() || ! anchorkit_get_option( 'anchorkit_toc_acf_enabled', false ) ) {
				return $content;
			}
		} else {
			return $content;
		}

		$original_content = $content;

		// Extract configured ACF content.
		$acf_content = anchorkit_extract_acf_content( $post->ID );
		if ( empty( $acf_content ) ) {
			return $content;
		}

		$acf_merge_mode    = anchorkit_get_option( 'anchorkit_toc_acf_merge_mode', 'after' );
		$valid_merge_modes = array( 'before', 'after', 'replace' );
		if ( ! in_array( $acf_merge_mode, $valid_merge_modes, true ) ) {
			$acf_merge_mode = 'after';
		}

		// Wrap injected markup so downstream filters can detect it.
		$wrapped_acf_content = '<div class="anchorkit-acf-content" data-anchorkit-acf-content="1">' . $acf_content . '</div>';

		$manual_toc_placeholders = '';
		if ( 'replace' === $acf_merge_mode ) {
			$manual_toc_placeholders = anchorkit_extract_manual_toc_placeholders( $original_content );
		}

		switch ( $acf_merge_mode ) {
			case 'before':
				$merged_content = $wrapped_acf_content . "\n\n" . $content;
				break;
			case 'replace':
				// For display purposes, show BOTH main content and ACF content.
				// The "replace" mode only affects which headings are extracted for TOC.
				$merged_content = $content . "\n\n" . $wrapped_acf_content;
				break;
			case 'after':
			default:
				$merged_content = $content . "\n\n" . $wrapped_acf_content;
				break;
		}

		if ( 'replace' === $acf_merge_mode && '' !== $manual_toc_placeholders ) {
			$merged_content .= "\n\n" . $manual_toc_placeholders;
		}

		// Store merge state so later filters (auto insert) don't duplicate the content.
		$GLOBALS['anchorkit_acf_merge_state'] = array(
			'did_merge' => true,
			'post_id'   => (int) $post->ID,
			'mode'      => $acf_merge_mode,
		);

		return $merged_content;
	}
}

if ( function_exists( 'add_filter' ) && ! has_filter( 'the_content', 'anchorkit_merge_acf_content_into_display' ) ) {
	add_filter( 'the_content', 'anchorkit_merge_acf_content_into_display', 4 );
}
