<?php
/**
 * MonoFrame Theme Functions
 *
 * @package MonoFrame
 * @since 1.0.0
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Theme Setup and Support
 *
 * Sets up theme defaults and registers support for various WordPress features.
 *
 * @since 1.0.0
 * @return void
 */
function monoframe_theme_support() {
	// Add support for Post thumbnails
	add_theme_support( 'post-thumbnails' );

	// Add support for responsive embedded content
	add_theme_support( 'responsive-embeds' );

	// Add support for Block Styles
	add_theme_support( 'wp-block-styles' );

	// Add support for Editor Styles
	add_theme_support( 'editor-styles' );

	// Enqueue Editor Styles
	add_editor_style( 'assets/css/main.css' );

	// Add support for custom logo
	add_theme_support(
		'custom-logo',
		array(
			'height'      => 50,
			'width'       => 50,
			'flex-height' => true,
			'flex-width'  => true,
		)
	);

	// Add support for HTML5 markup
	add_theme_support(
		'html5',
		array(
			'search-form',
			'comment-form',
			'comment-list',
			'gallery',
			'caption',
			'style',
			'script',
		)
	);

	// Add support for title tag
	add_theme_support( 'title-tag' );

	// Add support for automatic feed links
	add_theme_support( 'automatic-feed-links' );
}
add_action( 'after_setup_theme', 'monoframe_theme_support' );

/**
 * Disable Block Directory
 *
 * Removes the Block Directory functionality from the editor.
 *
 * @link https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/filters/editor-filters.md#block-directory
 *
 * @since 1.0.0
 * @return void
 */
function monoframe_disable_block_directory() {
	remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
	remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
}
add_action( 'init', 'monoframe_disable_block_directory' );

/**
 * Register Custom Template Part Area
 *
 * Adds a custom 'query' area for template parts.
 *
 * @since 1.0.0
 * @param array $areas Template part areas.
 * @return array Modified template part areas.
 */
function monoframe_custom_template_part_area( $areas ) {
	$areas[] = array(
		'area'        => 'query',
		'label'       => esc_html__( 'Query (The Loop)', 'monoframe' ),
		'description' => esc_html__( 'Custom query area for displaying posts and content loops', 'monoframe' ),
		'icon'        => 'layout',
		'area_tag'    => 'div',
	);

	return $areas;
}
add_filter( 'default_wp_template_part_areas', 'monoframe_custom_template_part_area' );

/**
 * Enqueue Theme Assets
 *
 * Loads CSS stylesheets and JavaScript files for the theme.
 *
 * @since 1.0.0
 * @return void
 */
function monoframe_load_scripts() {
	$theme_version = wp_get_theme()->get( 'Version' );

	// Enqueue main stylesheet
	wp_enqueue_style( 'monoframe-style', get_stylesheet_uri(), array(), $theme_version );

	// Enqueue compiled main styles (if using build process)
	wp_enqueue_style( 'monoframe-main', get_theme_file_uri( 'assets/css/main.css' ), array(), $theme_version, 'all' );
}
add_action( 'wp_enqueue_scripts', 'monoframe_load_scripts' );

/**
 * Add Custom Image Sizes
 *
 * Registers custom image sizes for the theme.
 *
 * @since 1.0.0
 * @return void
 */
function monoframe_add_image_sizes() {
	add_image_size( 'monoframe-featured', 1200, 600, true );
	add_image_size( 'monoframe-thumbnail', 400, 300, true );
}
add_action( 'after_setup_theme', 'monoframe_add_image_sizes' );

/**
 * Customize Excerpt Length
 *
 * Modifies the default excerpt length.
 *
 * @since 1.0.0
 * @param int $length Default excerpt length.
 * @return int Modified excerpt length.
 */
function monoframe_excerpt_length( $length ) {
	return 65;
}
add_filter( 'excerpt_length', 'monoframe_excerpt_length' );

/**
 * Filter the Related Articles Query Loop.
 *
 * On single posts, the related-articles pattern prioritizes posts that share
 * tags with the current post. If the post has no tags, shared categories are
 * used instead. The current post is always excluded.
 *
 * @since 1.0.4
 *
 * @param array    $query Query arguments generated by the Query Loop block.
 * @param WP_Block $block Query Loop block instance.
 * @return array Modified query arguments.
 */
function monoframe_related_articles_query( $query, $block ) {
	if ( ! is_singular( 'post' ) ) {
		return $query;
	}

	$post_id = get_queried_object_id();

	if ( ! $post_id ) {
		return $query;
	}

	$query['post__not_in']       = array_unique(
		array_merge(
			isset( $query['post__not_in'] ) ? (array) $query['post__not_in'] : array(),
			array( $post_id )
		)
	);
	$query['ignore_sticky_posts'] = true;
	$has_related_terms            = false;

	$tag_ids = wp_get_post_terms( $post_id, 'post_tag', array( 'fields' => 'ids' ) );

	if ( ! is_wp_error( $tag_ids ) && $tag_ids ) {
		$query['tag__in']  = array_map( 'absint', $tag_ids );
		$has_related_terms = true;
	} else {
		$category_ids = wp_get_post_terms( $post_id, 'category', array( 'fields' => 'ids' ) );

		if ( ! is_wp_error( $category_ids ) && $category_ids ) {
			$query['category__in'] = array_map( 'absint', $category_ids );
			$has_related_terms      = true;
		}
	}

	$has_related_posts = false;

	if ( $has_related_terms ) {
		$related_query_args                   = $query;
		$related_query_args['fields']         = 'ids';
		$related_query_args['posts_per_page'] = 1;
		$related_query_args['no_found_rows']  = true;

		$related_query     = new WP_Query( $related_query_args );
		$has_related_posts = $related_query->have_posts();
	}

	$GLOBALS['monoframe_related_articles_fallback'] = ! $has_related_posts;

	if ( ! $has_related_posts ) {
		unset( $query['tag__in'], $query['category__in'] );
		$query['orderby'] = 'rand';
	}

	return $query;
}

/**
 * Enable the related-articles query filter for its namespaced Query block.
 *
 * @since 1.0.4
 *
 * @param string|null $pre_render   The pre-rendered content, or null.
 * @param array       $parsed_block The block being rendered.
 * @return string|null Unmodified pre-rendered content.
 */
function monoframe_enable_related_articles_query( $pre_render, $parsed_block ) {
	$namespace = $parsed_block['attrs']['namespace'] ?? '';

	if ( 'core/query' === $parsed_block['blockName'] && 'monoframe/related-articles' === $namespace ) {
		$GLOBALS['monoframe_related_articles_fallback'] = false;
		add_filter( 'query_loop_block_query_vars', 'monoframe_related_articles_query', 10, 2 );
	}

	return $pre_render;
}
add_filter( 'pre_render_block', 'monoframe_enable_related_articles_query', 10, 2 );

/**
 * Disable the related-articles query filter after its Query block renders.
 *
 * @since 1.0.4
 *
 * @param string $block_content Rendered Query block content.
 * @param array  $block         Parsed Query block.
 * @return string Unmodified rendered content.
 */
function monoframe_disable_related_articles_query( $block_content, $block ) {
	$namespace = $block['attrs']['namespace'] ?? '';

	if ( 'monoframe/related-articles' === $namespace ) {
		remove_filter( 'query_loop_block_query_vars', 'monoframe_related_articles_query', 10 );
	}

	return $block_content;
}
add_filter( 'render_block_core/query', 'monoframe_disable_related_articles_query', 10, 2 );

/**
 * Add context when Related Articles falls back to random posts.
 *
 * @since 1.0.4
 *
 * @param string $block_content Rendered Group block content.
 * @param array  $block         Parsed Group block.
 * @return string Modified rendered content.
 */
function monoframe_render_related_articles_message( $block_content, $block ) {
	$class_name = $block['attrs']['className'] ?? '';

	if ( ! str_contains( $class_name, 'monoframe-related-articles' ) ) {
		return $block_content;
	}

	$replacement = '';

	if ( ! empty( $GLOBALS['monoframe_related_articles_fallback'] ) ) {
		$replacement = sprintf(
			'<p class="monoframe-related-articles-description">%s</p>',
			esc_html__( 'No closely related articles were found. Explore some other articles below.', 'monoframe' )
		);
	}

	$block_content = preg_replace(
		'/<p(?=[^>]*\bmonoframe-related-articles-description\b)[^>]*>.*?<\/p>/',
		$replacement,
		$block_content,
		1
	);

	unset( $GLOBALS['monoframe_related_articles_fallback'] );

	return $block_content;
}
add_filter( 'render_block_core/group', 'monoframe_render_related_articles_message', 10, 2 );

/**
 * Register Block Pattern Category
 *
 * Registers a custom block pattern category for the theme.
 *
 * @since 1.0.0
 * @return void
 */
function monoframe_register_block_pattern_category() {
	register_block_pattern_category(
		'monoframe',
		array( 'label' => esc_attr( 'MonoFrame' ) )
	);
}
add_action( 'init', 'monoframe_register_block_pattern_category' );

/**
 * Register Block Patterns
 *
 * Registers custom block patterns for enhanced editor experience.
 *
 * @since 1.0.0
 * @return void
 */
function monoframe_register_block_patterns() {
	/**
	 * Spacer Pattern
	 *
	 * Standard spacing between content for the entire theme
	 *
	 * @since 1.0.0
	 * @return void
	 */
	register_block_pattern(
		'monoframe/spacer',
		array(
			'title'       => __( 'Spacer', 'monoframe' ),
			'description' => __( 'A simple spacer block for adding vertical space between content.', 'monoframe' ),
			'categories'  => array( 'monoframe' ),
			'content'     => '<!-- wp:spacer {"height":24} -->
				<div style="height:24px" aria-hidden="true" class="wp-block-spacer"></div>
				<!-- /wp:spacer -->

				<!-- wp:separator {"color":"alabaster"} -->
				<hr class="wp-block-separator has-alpha-channel-opacity has-alabaster-color"/>
				<!-- /wp:separator -->

				<!-- wp:spacer {"height":24} -->
				<div style="height:24px" aria-hidden="true" class="wp-block-spacer"></div>',
		)
	);
}
add_action( 'init', 'monoframe_register_block_patterns' );
