<?php
/**
 * Theme functions for Wuppi block theme.
 *
 * @package wuppi
 */

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

define( 'WUPPI_VERSION', '1.0.5' );
define( 'WUPPI_GLOBAL_STYLES_MIGRATION_VERSION', 1 );

require_once get_template_directory() . '/inc/theme-settings.php';
require_once get_template_directory() . '/inc/theme-help.php';
require_once get_template_directory() . '/inc/site-branding-visibility.php';

if ( ! function_exists( 'wuppi_setup' ) ) {
	/**
	 * Register theme supports and i18n.
	 */
	function wuppi_setup() {
		load_theme_textdomain( 'wuppi', get_template_directory() . '/languages' );

		add_theme_support( 'woocommerce' );
		add_theme_support( 'editor-styles' );
		add_theme_support( 'wp-block-styles' );
		add_theme_support( 'responsive-embeds' );
		add_theme_support( 'align-wide' );
		add_theme_support( 'automatic-feed-links' );
		add_theme_support( 'post-thumbnails' );
		add_theme_support( 'title-tag' );
		add_theme_support(
			'custom-logo',
			array(
				'flex-height' => true,
				'flex-width'  => true,
			)
		);
	}
}
add_action( 'after_setup_theme', 'wuppi_setup' );

/**
 * Register custom pattern categories.
 */
function wuppi_register_pattern_categories() {
	if ( ! function_exists( 'register_block_pattern_category' ) ) {
		return;
	}

	register_block_pattern_category(
		'wuppi_page',
		array(
			'label'       => esc_html__( 'Pages', 'wuppi' ),
			'description' => esc_html__( 'A collection of full page starter layouts.', 'wuppi' ),
		)
	);
}
add_action( 'init', 'wuppi_register_pattern_categories' );

/**
 * Remove stale heading block typography saved from older theme defaults.
 *
 * Older Wuppi builds stored heading defaults under styles.blocks.core/heading,
 * which overrides the per-heading font controls in the editor once the values
 * are written into the wp_global_styles post.
 */
function wuppi_maybe_migrate_global_styles_heading_typography() {
	$migration_version = (int) get_option( 'wuppi_global_styles_migration_version', 0 );

	if ( $migration_version >= WUPPI_GLOBAL_STYLES_MIGRATION_VERSION ) {
		return;
	}

	if ( ! current_user_can( 'edit_theme_options' ) && ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
		return;
	}

	$styles_posts = get_posts(
		array(
			'post_type'        => 'wp_global_styles',
			'name'             => 'wp-global-styles-' . get_stylesheet(),
			'post_status'      => 'publish',
			'numberposts'      => 1,
			'suppress_filters' => true,
		)
	);

	if ( empty( $styles_posts ) || ! $styles_posts[0] instanceof WP_Post ) {
		return;
	}

	$styles_post = $styles_posts[0];
	$theme_json  = json_decode( $styles_post->post_content, true );

	if ( ! is_array( $theme_json ) ) {
		return;
	}

	if ( ! wuppi_strip_legacy_heading_block_typography( $theme_json ) ) {
		update_option( 'wuppi_global_styles_migration_version', WUPPI_GLOBAL_STYLES_MIGRATION_VERSION, false );
		return;
	}

	$updated = wp_update_post(
		array(
			'ID'           => $styles_post->ID,
			'post_content' => wp_json_encode( $theme_json, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ),
		),
		true
	);

	if ( is_wp_error( $updated ) ) {
		return;
	}

	clean_post_cache( $styles_post->ID );

	if ( class_exists( 'WP_Theme_JSON_Resolver' ) && is_callable( array( 'WP_Theme_JSON_Resolver', 'clean_cached_data' ) ) ) {
		WP_Theme_JSON_Resolver::clean_cached_data();
	}

	update_option( 'wuppi_global_styles_migration_version', WUPPI_GLOBAL_STYLES_MIGRATION_VERSION, false );
}
add_action( 'admin_init', 'wuppi_maybe_migrate_global_styles_heading_typography' );

/**
 * Strip legacy block-level heading typography without touching other settings.
 *
 * @param array $theme_json Decoded wp_global_styles JSON.
 * @return bool
 */
function wuppi_strip_legacy_heading_block_typography( array &$theme_json ) {
	if ( ! isset( $theme_json['styles']['blocks']['core/heading']['typography'] ) || ! is_array( $theme_json['styles']['blocks']['core/heading']['typography'] ) ) {
		return false;
	}

	$typography  = $theme_json['styles']['blocks']['core/heading']['typography'];
	$font_family = isset( $typography['fontFamily'] ) ? trim( (string) $typography['fontFamily'] ) : '';
	$legacy_fonts = array(
		'var(--wp--preset--font-family--playfair-display)',
		'var(--wp--preset--font-family--montserrat)',
		'var(--wp--preset--font-family--nunito-sans)',
		'var(--wp--preset--font-family--cormorant-garamond)',
		'var:preset|font-family|playfair-display',
		'var:preset|font-family|montserrat',
		'var:preset|font-family|nunito-sans',
		'var:preset|font-family|cormorant-garamond',
	);

	if ( '' === $font_family || ! in_array( $font_family, $legacy_fonts, true ) ) {
		return false;
	}

	$changed = false;

	foreach ( array( 'fontFamily', 'fontWeight', 'fontStyle', 'lineHeight' ) as $key ) {
		if ( array_key_exists( $key, $theme_json['styles']['blocks']['core/heading']['typography'] ) ) {
			unset( $theme_json['styles']['blocks']['core/heading']['typography'][ $key ] );
			$changed = true;
		}
	}

	if ( empty( $theme_json['styles']['blocks']['core/heading']['typography'] ) ) {
		unset( $theme_json['styles']['blocks']['core/heading']['typography'] );
	}

	if ( empty( $theme_json['styles']['blocks']['core/heading'] ) ) {
		unset( $theme_json['styles']['blocks']['core/heading'] );
	}

	if ( empty( $theme_json['styles']['blocks'] ) ) {
		unset( $theme_json['styles']['blocks'] );
	}

	return $changed;
}

/**
 * Enqueue shared front-end and editor styles.
 */
function wuppi_enqueue_block_assets() {
	$theme_uri = get_template_directory_uri();
	$theme_dir = get_template_directory();

	$style_path = $theme_dir . '/assets/css/theme.css';
	$style_ver  = file_exists( $style_path ) ? (string) filemtime( $style_path ) : WUPPI_VERSION;

	wp_enqueue_style(
		'wuppi-theme',
		$theme_uri . '/assets/css/theme.css',
		array( 'wp-block-library' ),
		$style_ver
	);

	// Enqueue header behavior JS only on the front-end (not in the block editor).
	if ( ! is_admin() ) {
		$script_path = $theme_dir . '/assets/js/header-behavior.js';
		$script_ver  = file_exists( $script_path ) ? (string) filemtime( $script_path ) : WUPPI_VERSION;

		wp_enqueue_script(
			'wuppi-header-behavior',
			$theme_uri . '/assets/js/header-behavior.js',
			array(),
			$script_ver,
			true
		);

	}

	if ( function_exists( 'wuppi_get_settings' ) ) {
		$settings        = wuppi_get_settings();
		$density         = isset( $settings['header_nav_density'] ) ? (string) $settings['header_nav_density'] : 'compact';
		$nav_gap         = isset( $settings['header_nav_gap'] ) ? max( 0, min( 48, (int) $settings['header_nav_gap'] ) ) : 14;
		$auto_hide_delay = isset( $settings['header_auto_hide_delay'] ) ? (int) $settings['header_auto_hide_delay'] : 900;

		if ( ! in_array( $auto_hide_delay, array( 600, 900, 1400 ), true ) ) {
			$auto_hide_delay = 900;
		}

		$nav_gap_value = $nav_gap . 'px';
		$nav_font_size = '1.125rem';

		if ( 'comfortable' === $density ) {
			$nav_font_size = '1.1875rem';
		}

		$inline_css = sprintf(
			':root{--calm-header-height:%1$dpx;--calm-nav-gap:%2$s;--calm-nav-font-size:%3$s;}',
			(int) $settings['header_height'],
			esc_html( $nav_gap_value ),
			esc_html( $nav_font_size )
		);

		wp_add_inline_style( 'wuppi-theme', $inline_css );

		// Enqueue back to top script only on the front-end when setting is enabled.
		if ( ! is_admin() && ! empty( $settings['back_to_top'] ) ) {
			$btt_path = $theme_dir . '/assets/js/back-to-top.js';
			$btt_ver  = file_exists( $btt_path ) ? (string) filemtime( $btt_path ) : WUPPI_VERSION;

			wp_enqueue_script(
				'wuppi-back-to-top',
				$theme_uri . '/assets/js/back-to-top.js',
				array(),
				$btt_ver,
				true
			);
		}

		// Pass settings to the header behavior script only on the front-end.
		if ( ! is_admin() ) {
			wp_add_inline_script(
				'wuppi-header-behavior',
				'window.wuppiHeaderSettings=' . wp_json_encode(
					array(
						'autoHideDelay' => $auto_hide_delay,
					)
				) . ';',
				'before'
			);
		}
	}

	/**
	 * Allow child themes or plugins to enqueue extra shared assets.
	 *
	 * @param string $theme_uri Theme URI.
	 * @param string $theme_dir Theme dir path.
	 */
	do_action( 'wuppi_after_enqueue_assets', $theme_uri, $theme_dir );
}
add_action( 'enqueue_block_assets', 'wuppi_enqueue_block_assets' );

/**
 * Add editor-specific tweaks.
 */
function wuppi_enqueue_editor_assets() {
	$editor_path = get_template_directory() . '/assets/css/editor.css';
	$editor_ver  = file_exists( $editor_path ) ? (string) filemtime( $editor_path ) : WUPPI_VERSION;
	$script_path = get_template_directory() . '/assets/js/site-branding-visibility.js';
	$script_ver  = file_exists( $script_path ) ? (string) filemtime( $script_path ) : WUPPI_VERSION;

	wp_enqueue_style(
		'wuppi-editor',
		get_template_directory_uri() . '/assets/css/editor.css',
		array( 'wuppi-theme' ),
		$editor_ver
	);

	wp_enqueue_script(
		'wuppi-site-branding-visibility',
		get_template_directory_uri() . '/assets/js/site-branding-visibility.js',
		array( 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n' ),
		$script_ver,
		true
	);

	wp_set_script_translations(
		'wuppi-site-branding-visibility',
		'wuppi',
		get_template_directory() . '/languages'
	);
}
add_action( 'enqueue_block_editor_assets', 'wuppi_enqueue_editor_assets' );

/**
 * Register custom block styles.
 */
function wuppi_register_block_styles() {
	if ( ! function_exists( 'register_block_style' ) ) {
		return;
	}

	register_block_style(
		'core/social-links',
		array(
			'name'         => 'wuppi-minimal',
			'label'        => esc_html__( 'Wuppi Minimal', 'wuppi' ),
			'inline_style' => '.wp-block-social-links.is-style-wuppi-minimal{color:inherit}.wp-block-social-links.is-style-wuppi-minimal .wp-social-link{background:transparent}.wp-block-social-links.is-style-wuppi-minimal .wp-block-social-link-anchor{color:currentColor}',
		)
	);

	register_block_style(
		'core/group',
		array(
			'name'  => 'card',
			'label' => esc_html__( 'Card', 'wuppi' ),
		)
	);
}
add_action( 'init', 'wuppi_register_block_styles' );

// Skip link is handled natively by WordPress block themes (wp-block-template-skip-link).

/**
 * Output the back to top button when the setting is enabled.
 */
function wuppi_back_to_top_button() {
	if ( ! function_exists( 'wuppi_get_settings' ) ) {
		return;
	}

	$settings = wuppi_get_settings();

	if ( empty( $settings['back_to_top'] ) ) {
		return;
	}

	echo '<button class="wuppi-back-to-top" aria-label="' . esc_attr__( 'Back to top', 'wuppi' ) . '" hidden>';
	echo '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><polyline points="18 15 12 9 6 15"></polyline></svg>';
	echo '</button>';
}
add_action( 'wp_body_open', 'wuppi_back_to_top_button' );

/**
 * Filterable body classes.
 *
 * @param array $classes Current classes.
 * @return array
 */
function wuppi_body_class( $classes ) {
	$classes[] = 'wuppi-theme';

	if ( function_exists( 'wuppi_get_settings' ) ) {
		$settings        = wuppi_get_settings();
		$behavior        = isset( $settings['header_desktop_behavior'] ) ? sanitize_html_class( (string) $settings['header_desktop_behavior'] ) : 'scroll';
		$mobile_behavior = isset( $settings['header_mobile_behavior'] ) ? (string) $settings['header_mobile_behavior'] : 'sticky-glass';

		if ( ! in_array( $mobile_behavior, array( 'sticky-glass', 'static' ), true ) ) {
			$mobile_behavior = 'sticky-glass';
		}

		$classes[] = 'calm-header-mode-' . $behavior;
		$classes[] = 'calm-header-mobile-' . sanitize_html_class( $mobile_behavior );
	}

	return apply_filters( 'wuppi_body_classes', $classes );
}
add_filter( 'body_class', 'wuppi_body_class' );

/**
 * Exclude the current post from the post-sidebar query loop.
 *
 * @param array    $query Query vars for the loop.
 * @param WP_Block $block Block instance.
 * @param int      $page  Current query page.
 * @return array
 */
function wuppi_exclude_current_post_from_post_sidebar_query( $query, $block, $page ) {
	unset( $page );

	if ( is_admin() || ! is_singular( 'post' ) || ! $block instanceof WP_Block ) {
		return $query;
	}

	$attrs = isset( $block->parsed_block['attrs'] ) && is_array( $block->parsed_block['attrs'] ) ? $block->parsed_block['attrs'] : array();

	if ( empty( $attrs['namespace'] ) || 'wuppi/post-sidebar' !== $attrs['namespace'] ) {
		return $query;
	}

	$current_post_id = (int) get_queried_object_id();

	if ( $current_post_id <= 0 ) {
		return $query;
	}

	$excluded_posts = isset( $query['post__not_in'] ) ? array_map( 'intval', (array) $query['post__not_in'] ) : array();
	$excluded_posts[] = $current_post_id;

	$query['post__not_in'] = array_values( array_unique( array_filter( $excluded_posts ) ) );

	return $query;
}
add_filter( 'query_loop_block_query_vars', 'wuppi_exclude_current_post_from_post_sidebar_query', 10, 3 );
