<?php
/**
 * Core Function for theme
 *
 * Eventually, some of the functionality here could be replaced by core features.
 *
 * @author ThemeOO
 * @category HelperFunctions
 * @package ThemeOO\Core
 */

if ( ! defined( 'ABSPATH' ) ) {
	header( 'Status: 403 Forbidden' );
	header( 'HTTP/1.1 403 Forbidden' );
	die();
}

/**
 * @global string $themeoo_get_current_screen Themeoo Current Screen Name
 * @global array $themeoo_loaded_sidebar_position Themeoo Loaded Sidebar position for screens
 * @global array $themeoo_loaded_layout_options Themeoo Loaded loaded layout options for posts/pages/cpt etc.
 */
global
	$themeoo_screen,
	$themeoo_loaded_sidebar_position,
	$themeoo_loaded_layout_options;

/**
 * Combine base classes with extra.
 *
 * @param string[] $base base class names.
 * @param string|string[] $extra Space-separated string or array of extra class names to add to the class list.
 *
 * @return array
 */
function themeoo_class_attribute_helper( $base, $extra ) {
	if ( ! empty( $extra ) ) {
		if ( ! is_array( $extra ) ) {
			$extra = preg_split( '#\s+#', $extra );
		}
		$base = array_merge( $base, $extra ); // @phpstan-ignore-line
	} else {
		$extra = array();
	}

	return array( array_map( 'esc_attr', $base ), $extra );
}

/**
 * Check input value is not eqeqeq to 'default' && not empty.
 *
 * @param mixed $input input value to check.
 *
 * @return bool
 */
function themeoo_is_not_default_val( $input ) {
	return ( ! empty( $input ) && 'default' !== $input );
}

/**
 * Get Post Settings.
 *
 * @param string $option Option to get.
 * @param int|WP_Post|null $post Post id. Default null. If not set will use the current post id.
 *
 * @return array|string|int|false
 */
function themeoo_get_post_layout_options( $option = '', $post = null ) {
	global $themeoo_loaded_layout_options;

	$post = get_post( $post );

	if ( null === $themeoo_loaded_layout_options ) {
		$themeoo_loaded_layout_options = array();
	}

	$option   = strtolower( $option );
	$defaults = apply_filters(
		'themeoo_page_post_layout_defaults',
		array(
			'themeoo_display_header'   => 'default',
			'themeoo_secondary_header' => 'default',
			'themeoo_section_height'   => 0,
			'themeoo_site_layout'      => 'default',
			'themeoo_titlebar'         => 'default',
			'themeoo_page_title'       => 'default',
			'themeoo_content_layout'   => 'default',
			'themeoo_sidebar'          => 'default',
		)
	);

	// fx option name.
	if ( ! $option ) {
		$option = 'all';
	} else {
		$option = str_replace( 'themeoo_', '', $option );
	}

	if ( $post ) {

		if ( 'all' !== $option && has_filter( "themeoo_pre_get_post_{$option}_option" ) ) {
			// Eg. themeoo_pre_get_post_content_layout_option
			// Eg. themeoo_pre_get_post_display_header_option
			return apply_filters( "themeoo_pre_get_post_{$option}_option", $post );
		}

		if ( ! isset( $themeoo_loaded_layout_options[ $post->ID ] ) ) {
			$settings = (array) get_post_meta( $post->ID, 'themeoo', true );
			$settings = array_filter( $settings );
			$settings = wp_parse_args( $settings, $defaults );
			$settings = apply_filters( 'themeoo_post_layout_options', $settings, $post );
			// Store into cache.
			$themeoo_loaded_layout_options[ $post->ID ] = $settings;
		} else {
			// Read from cache.
			$settings = $themeoo_loaded_layout_options[ $post->ID ];
		}
	} else {
		// This function can be called from any archive pages...
		$settings = apply_filters( 'themeoo_post_layout_options', $defaults, null );
	}

	if ( 'all' === $option ) {
		return $settings;
	}

	if ( isset( $settings[ $option ] ) ) {
		return $settings[ $option ];
	}

	if ( isset( $settings[ 'themeoo_' . $option ] ) ) {
		return $settings[ 'themeoo_' . $option ];
	}

	_doing_it_wrong(
		__FUNCTION__,
		sprintf(
			/* translators: %s: Option name. */
			esc_html__( 'Option %s is not registered within current theme', 'ayyash' ),
			'<code>' . esc_html( $option ) . '</code>'
		),
		'1.0.0'
	);

	return false;
}

/**
 * Determine the current view.
 *
 * @return string The string representing the current view.
 */
function themeoo_get_current_screen() {
	global $themeoo_screen;

	if ( isset( $themeoo_screen ) ) {
		return $themeoo_screen;
	}

	// Post types.
	$post_types   = get_post_types(
		array(
			'public'   => true,
			'_builtin' => false,
		)
	);
	$post_types[] = 'post';

	// Post parent.
	$parent_post_type = '';
	if ( is_attachment() ) {
		$attachment       = get_post();
		$parent_post_type = $attachment ? get_post_type( $attachment->post_parent ) : '';
	}

	$themeoo_screen = 'post';

	if ( is_home() ) {
		$themeoo_screen = 'blog'; // Blog.
	} elseif ( is_archive() && ! is_post_type_archive( 'product' ) ) {
		$themeoo_screen = 'archive'; // Archives.
	} elseif ( is_search() ) {
		$themeoo_screen = 'search'; // Search results.
		// @phpstan-ignore-next-line
	} elseif ( is_singular( $post_types ) || ( is_attachment() && in_array( $parent_post_type, $post_types, true ) ) ) {
		$themeoo_screen = 'post'; // Posts and public custom post types.
	} elseif ( is_page() || ( is_attachment() && 'page' === $parent_post_type ) ) {
		$themeoo_screen = 'page'; // Pages.
	}

	return apply_filters( 'themeoo_current_screen', $themeoo_screen );
}

/**
 * Get Sidebar Position.
 *
 * @param string $screen current view.
 *
 * @return string
 */
function themeoo_get_sidebar_position( $screen = '' ) {
	global $themeoo_loaded_sidebar_position;

	if ( ! $screen ) {
		$screen = themeoo_get_current_screen();
	}

	if ( null === $themeoo_loaded_sidebar_position ) {
		$themeoo_loaded_sidebar_position = array();
	}

	if ( isset( $themeoo_loaded_sidebar_position[ $screen ] ) ) {
		return $themeoo_loaded_sidebar_position[ $screen ];
	}

	if ( class_exists( 'WooCommerce' ) && ( is_post_type_archive( 'product' ) ) ) {
		$position = themeoo_get_mod( 'woocommerce_shop_archive_layout' );
	} elseif ( class_exists( 'WooCommerce' ) && is_product() ) {
		$position = themeoo_get_mod( 'woocommerce_single_layout' );
	} elseif ( class_exists( 'WooCommerce' ) && is_cart() ) {
		$position = themeoo_get_mod( 'woocommerce_cart_sidebar_layout' );
	} elseif ( class_exists( 'WooCommerce' ) && is_checkout() ) {
		$position = themeoo_get_mod( 'woocommerce_checkout_sidebar_layout' );
	} elseif ( class_exists( 'WooCommerce' ) && is_account_page() ) {
		$position = themeoo_get_mod( 'woocommerce_myaccount_sidebar_layout' );
	} elseif ( class_exists( 'WooCommerce' ) && is_product_category() ) {
		$position = themeoo_get_mod( 'woocommerce_product_catalog_sidebar_layout' );
	} else {
		/**
		 * @var string $single_sidebar_position
		 */
		$single_sidebar_position = themeoo_get_post_layout_options( 'content_layout' );
		if ( 'default' !== $single_sidebar_position && $single_sidebar_position ) {
			$position = $single_sidebar_position;
		} else {
			$position = themeoo_get_mod( 'layout_' . $screen . '_sidebar' );
			// In case current screen is modified and not found in default values.
			if ( ! $position ) {
				$position = 'none';
			}
		}
	}

	$themeoo_loaded_sidebar_position[ $screen ] = apply_filters( 'themeoo_sidebar_position', $position, $screen );

	return $themeoo_loaded_sidebar_position[ $screen ];
}

/**
 * Checks if lazy-loading images is enabled.
 *
 * @return bool
 */
function themeoo_layzload_enabled() {
	return (bool) themeoo_get_mod( 's_config_lazyload_enable' );
}

/**
 * Themeoo rest api request
 *
 * @return false|mixed|void
 */
function themeoo_doing_rest() {
	if ( empty( $_SERVER['REQUEST_URI'] ) ) {
		return false;
	}

	$rest_prefix         = trailingslashit( rest_get_url_prefix() );
	$is_rest_api_request = ( false !== strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) ); // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

	return apply_filters( 'themeoo_is_rest_api_request', $is_rest_api_request );
}

/**
 * Themeoo lazyload post thumbnail
 *
 * @return mixed|void
 */
function themeoo_maybe_lazyload_post_thumbnail() {
	return apply_filters(
		'themeoo_lazyload_post_thumbnail',
		(
			themeoo_layzload_enabled() &&
			! is_admin() &&
			! wp_doing_ajax() &&
			! themeoo_doing_rest()
		)
	);
}

if ( ! function_exists( 'themeoo_search_menu_icon' ) ) {
	/**
	 * Mobile search icon
	 *
	 * @param string $items nav items.
	 * @param object $args  nav args.
	 *
	 * @return string
	 */
	function themeoo_search_menu_icon( $items, $args ) {
		if ( themeoo_get_mod( 'layout_header_search' ) && isset( $args->theme_location ) && 'primary' === $args->theme_location ) {
			// @phpstan-ignore-next-line
			$items .= '<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children dropdown" id="menu-item-search">
            	<a href="#" class="themeoo-link"><i class="ti-search"></i></a>
                <ul class="dropdown-menu"><li>' . get_search_form( array( 'echo' => false ) ) . '</li></ul>
            </li>';
		}

		return $items;
	}
}

if ( ! function_exists( 'themeoo_mobile_icon' ) ) {
	/**
	 * Mobile Menu Icon.
	 *
	 * @return void
	 */
	function themeoo_mobile_icon() {
		$mobile_icon_grid = themeoo_get_mod( 'layout_header_menu_mobileshow' );

		switch ( $mobile_icon_grid ) {
			case 'sm':
				$mobile_icon_grid = ' d-block d-md-none';
				break;
			case 'md':
				$mobile_icon_grid = ' d-block d-lg-none';
				break;
			case 'lg':
				$mobile_icon_grid = ' d-block d-xl-none';
				break;
			case 'xl':
				$mobile_icon_grid = ' d-block';
				break;
			default:
				$mobile_icon_grid = ' d-block d-xl-none';
		}
		?>
		<a href="#" id="themeoo-mobile-toggle" class="<?php echo esc_attr( $mobile_icon_grid ); ?>" role="button" aria-controls="navigation-mobile">
			<i class="ti-menu" aria-hidden="true"></i>
		</a>
		<?php
	}
}

if ( ! function_exists( 'themeoo_get_mobile_menu' ) ) {
	/**
	 * Get Mobile Menu
	 *
	 * @return void
	 */
	function themeoo_get_mobile_menu() {
		if ( has_nav_menu( 'mobile' ) ) {
			wp_nav_menu( array( 'theme_location' => 'mobile' ) );
		} else {
			wp_nav_menu(
				array(
					'theme_location' => 'primary',
					'mobile'         => true,
				)
			);
		}
	}
}

if ( ! function_exists( 'themeoo_header_user_account_info' ) ) {
	/**
	 * Right Nav Panel.
	 *
	 * @return void
	 */
	function themeoo_header_user_account_info() {
		$stat  = is_user_logged_in();
		$label = $stat ? __( 'My Account', 'ayyash' ) : __( 'Sign Up / Log In', 'ayyash' );
		$title = $stat ? __( 'My Account', 'ayyash' ) : __( 'Login', 'ayyash' );
		/** @noinspection HtmlUnknownTarget */
		printf(
			'<a class="themeoo-signup hidden-xs" href="%s" title="%s"> <i class="ti-user" aria-hidden="true"></i> %s</a>',
			esc_url( get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ) ), // @phpstan-ignore-line
			esc_attr( $title ),
			esc_html( $label )
		);
	}
}

if ( ! function_exists( 'themeoo_wp_page_menu' ) ) {

	/**
	 * Display or retrieve list of pages with optional home link.
	 *
	 * This function is copied from WP wp_page_menu function to add an extra class as
	 * the default WP function has no inbuilt way to achieve this without using hacks
	 *
	 * @param array $args args.
	 *
	 * @return string html menu
	 */
	function themeoo_wp_page_menu( $args = array() ) {
		$defaults = array(
			'sort_column' => 'menu_order, post_title',
			'menu_class'  => 'menu',
			'echo'        => true,
			'link_before' => '',
			'link_after'  => '',
		);
		$args     = wp_parse_args( $args, $defaults );

		/**
		 * Filter the arguments used to generate a page-based menu.
		 *
		 * @see wp_page_menu()
		 *
		 * @param array $args An array of page menu arguments.
		 */
		$args = apply_filters( 'wp_page_menu_args', $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound,WPThemeReview.CoreFunctionality.PrefixAllGlobals.NonPrefixedHooknameFound

		$menu = '';

		$list_args = $args;

		// Show Home in the menu.
		if ( ! empty( $args['show_home'] ) ) {
			if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] ) {
				$text = __( 'Home', 'ayyash' );
			} else {
				$text = $args['show_home'];
			}
			$class = '';
			if ( is_front_page() && ! is_paged() ) {
				$class = 'class="current_page_item"';
			}
			$menu .= '<li ' . $class . '><a href="' . home_url( '/' ) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';

			// If the front page is a page, add it to the exclude list.
			if ( 'page' === get_option( 'show_on_front' ) ) {
				if ( ! empty( $list_args['exclude'] ) ) {
					$list_args['exclude'] .= ',';
				} else {
					$list_args['exclude'] = ''; // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude
				}
				$list_args['exclude'] .= get_option( 'page_on_front' );
			}
		}

		$list_args['echo']     = false;
		$list_args['depth']    = 1;
		$list_args['title_li'] = '';
		$menu                 .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages( $list_args ) ); // @phpstan-ignore-line

		if ( $menu ) {
			$menu = '<ul class="nav navbar-nav">' . $menu . '</ul>';
		}

		$menu = '<div class="' . esc_attr( $args['menu_class'] ) . '">' . $menu . "</div>\n";

		/**
		 * Filter the HTML output of a page-based menu.
		 *
		 * @see wp_page_menu()
		 *
		 * @param string $menu The HTML output.
		 * @param array $args An array of arguments.
		 */
		$menu = apply_filters( 'wp_page_menu', $menu, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound,WPThemeReview.CoreFunctionality.PrefixAllGlobals.NonPrefixedHooknameFound

		if ( $args['echo'] ) {
			echo $menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}
		return $menu;
	}
}

if ( class_exists( 'WooCommerce' ) ) {
	/**
	 * CPT notice.
	 *
	 * @return void
	 */
	function themeoo_show_cpt_archive_notice() {
		global $post;
		$shop_page_id = wc_get_page_id( 'shop' );
		if ( $post && absint( $shop_page_id ) === absint( $post->ID ) ) {
			?>
			<div class="notice notice-warning">
				<p><?php esc_html_e( 'If you are in shop page which is selected as WooCommerce archive page then page option will not work. You have to select settings from Customizer', 'ayyash' ); ?></p>
			</div>
			<?php
		}
	}

	add_action( 'admin_notices', 'themeoo_show_cpt_archive_notice', 100 );
}

if ( ! function_exists( 'themeoo_get_product_discount' ) ) {
	/**
	 * Display Product Discount Tag.
	 *
	 * @param int  $product_id  Product ID.
	 * @param int  $precision   Numeric round precision.
	 *
	 * @return void
	 */
	function themeoo_get_product_discount( $product_id = null, $precision = 0 ) {

		$product_id = ! $product_id ? get_the_ID() : $product_id;
		$product    = wc_get_product( $product_id );
		$discount   = 0;

		if ( $product instanceof WC_Product ) {
			$sale_price    = $product->get_sale_price();
			$regular_price = $product->get_regular_price();

			if ( ! empty( $sale_price ) && $regular_price > $sale_price ) {
				$discount = ( ( (float) $regular_price - (float) $sale_price ) / (float) $regular_price ) * 100;
				$discount = round( $discount, $precision );
			}
		}

		if ( $discount > 0 ) {
			printf( '<span class="product-discount">%1$s%%</span>', (float) $discount );
		}
	}
}

if ( ! function_exists( 'themeoo_get_product_badge' ) ) {

	/**
	 * Get product badge.
	 *
	 * @param int   $product_id Product ID.
	 * @param array $check check.
	 *
	 * @return void
	 */
	function themeoo_get_product_badge( $product_id = null, $check = array() ) {

		$product_id = ! $product_id ? get_the_ID() : $product_id;
		$product    = wc_get_product( $product_id );

		if ( ! $product ) {
			return;
		}

		$product_tags = array_map(
			function ( $tag_id ) use ( $check ) {
				$term = get_term_by( 'id', $tag_id, 'product_tag' );

				// @phpstan-ignore-next-line
				if ( ! $term || is_wp_error( $term ) ) {
					return null;
				}

				/**
				 * @var WP_Term $term
				 */
				if ( ! empty( $check ) && ! in_array( $term->slug, $check ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
					return null;
				}

				return sprintf( '<span class="product-badge badge-%s">%s</span>', esc_attr( $term->slug ), esc_html( $term->name ) );
			},
			$product->get_tag_ids()
		);

		$product_tags = array_filter( $product_tags );

		if ( ! empty( $product_tags ) ) {
			echo implode( '', $product_tags ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}
	}
}

/**
 * Get Layout for a view.
 *
 * @param string $view View.
 *
 * @return string
 */
function themeoo_get_content_layout( $view = '' ) {
	if ( '' === $view ) {
		$view = themeoo_get_current_screen();
	}

	$layout = wp_cache_get( 'layout_' . $view . '_style' );

	if ( false === $layout ) {
		$layout = themeoo_get_mod( 'layout_' . $view . '_style' );
		wp_cache_set( 'layout_' . $view . '_style', $layout );
	}

	return apply_filters( 'themeoo_content_layout', $layout, $view );
}

/**
 * Get post format content class for layout.
 *
 * @param string $layout
 * @param string $class
 *
 * @return void
 */
function themeoo_get_post_format_classes( $layout = 'normal', $class = '' ) {

	$map = [ 'grid', 'normal', 'medium' ];

	if ( ! in_array( $layout, $map, true ) ) {
		$layout = 'normal';
	}

	$format  = get_post_format();
	$classes = [
		'blog-' . $layout,
		'post-' . $format,
		'entry-' . $format . '-post-format',
		$format,
	];

	if ( 'medium' === $layout ) {
		$classes[] = 'medium-left';
	}

	if ( 'gallery' === $format ) {
		$classes[] = 'carousel';
		$classes[] = 'slide';
		$classes[] = 'blog-gallery-slider';
	}

	// Animations
	$classes[] = 'effect';
	$classes[] = 'slide-top';

	if ( ! empty( $class ) ) {
		if ( is_string( $class ) ) {
			$class = preg_split( '#\s+#', $class );
		}

		if ( is_array( $class ) ) {
			$classes = array_merge( $classes, $class );
		}
	}

	if ( ! is_array( $class ) ) {
		// Ensure that we always coerce class to being an array.
		$class = array();
	}

	/**
	 * Filters the list of CSS post-format class names for the current post in the loop.
	 *
	 * @param string[] $classes An array of body class names.
	 * @param string[] $class   An array of additional class names added to the body.
	 */
	$classes = apply_filters( 'themeoo_post_format_class', $classes, $class );

	$classes = array_map( 'esc_attr', $classes );

	echo 'class="' . esc_attr( implode( ' ', array_unique( $classes ) ) ) . '"';
}

/**
 * Render oEmbed content.
 *
 * @param string $src Link to render.
 * @param bool $echo display or return content.
 *                       Default is true (display)
 *
 * @return void|string|false|true return embed html or false, true if displayed.
 *
 * @see WP_Embed::shortcode()
 * WP Embed uses current (global) post's id (meta) to cache the oEmbed api responses.
 */
function themeoo_render_embedded( $src, $echo = true ) {
	global $wp_embed;

	if ( ! strpos( $src, '://' ) ) {
		$src = ( is_ssl() ? 'http' : 'https' ) . '://' . $src;
	}

	$src = esc_url_raw( $src );
	if ( ! $src ) {
		return;
	}

	$embedded = $wp_embed->run_shortcode( '[embed]' . $src . '[/embed]' );

	$embedded = apply_filters( 'themeoo_render_embedded', $embedded, $src );

	if ( ! $echo ) {
		return $embedded;
	}

	if ( $embedded ) {
		echo $embedded; // phpcs:ignore WordPress.Security.EscapeOutput
		return true;
	}
	return false;
}

/**
 * Gets the first instance of a block in the content, and then break away.
 *
 * Scrapped from Twenty Twenty-One 1.0
 *
 * @param string      $block_name The full block type name, or a partial match.
 *                                Example: `core/image`, `core-embed/*`.
 * @param string|null $content    The content to search in. Use null for get_the_content().
 * @param int         $instances  How many instances of the block will be printed (max). Defaults to 1.
 *
 * @return bool Returns true if a block was located & printed, otherwise false.
 */
function themeoo_get_first_instance_of_block( $block_name, $content = null, $instances = 1 ) {

	if ( ! $content ) {
		$content = get_the_content();
	}

	// Parse blocks in the content.
	$blocks = parse_blocks( $content );

	$instances_count = 0;
	$blocks_content  = '';

	// Loop blocks.
	foreach ( $blocks as $block ) {

		// Sanity check.
		if ( ! isset( $block['blockName'] ) ) {
			continue;
		}

		// Check if this the block matches the $block_name.
		// If the block ends with *, try to match the first portion.
		/** @noinspection PhpLanguageLevelInspection */
		if ( '*' === $block_name[-1] ) {
			$is_matching_block = 0 === strpos( $block['blockName'], rtrim( $block_name, '*' ) );
		} else {
			$is_matching_block = $block_name === $block['blockName'];
		}

		if ( $is_matching_block ) {

			// Add the block HTML.
			$blocks_content .= render_block( $block );

			// Increment count.
			$instances_count++;

			// Break the loop if the $instances count was reached.
			if ( $instances_count >= $instances ) {
				break;
			}
		}
	}

	if ( $blocks_content ) {
		return apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound,WPThemeReview.CoreFunctionality.PrefixAllGlobals.NonPrefixedHooknameFound
	}

	return false;
}

/**
 * Print the first instance of a block in the content, and then break away.
 *
 * Scrapped from Twenty Twenty-One 1.0
 *
 * @param string      $block_name The full block type name, or a partial match.
 *                                Example: `core/image`, `core-embed/*`.
 * @param string|null $content    The content to search in. Use null for get_the_content().
 * @param int         $instances  How many instances of the block will be printed (max). Defaults to 1.
 *
 * @return void
 */
function themeoo_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) {
	echo themeoo_get_first_instance_of_block( $block_name, $content, $instances ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
