<?php
/**
 * Theme helper functions.
 *
 * @package Eronex
 * @since   0.0.1
 */

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

/**
 * Checks whether a haystack string contains any of the given needles.
 *
 * @since 0.0.1
 *
 * @param string          $haystack The string to search in.
 * @param string|string[] $needles  Needle or array of needles passed to strpos().
 * @param int             $offset   Optional. Character offset to start the search. Default 0.
 * @return bool True if any needle is found in the haystack, otherwise false.
 */
function eronex_strposa( $haystack, $needles, $offset = 0 ) {

	if ( ! is_array( $needles ) ) {
		$needles = array( $needles );
	}

	foreach ( $needles as $query ) {
		if ( strpos( $haystack, $query, $offset ) !== false ) {
			// stop on first true result
			return true;
		}
	}

	return false;
}

/**
 * Retrieves a theme mod option value, filterable per option key.
 *
 * @since 0.0.1
 *
 * @param string $option Option key to retrieve.
 * @param mixed  $value  Optional. Default value if the option is not set. Default empty string.
 * @return mixed The option value after filtering, or the default if the key is invalid.
 */
function eronex_option( $option, $value = '' ) {

	if ( ! is_string( $option ) || empty( $option ) ) {
		return $value;
	}

	$value = get_theme_mod( $option, $value );

	/**
	 * Filters a theme option value for a specific option key.
	 *
	 * The dynamic portion of the hook name, `$option`, refers to the theme mod key.
	 *
	 * @since 0.0.1
	 *
	 * @param mixed  $value  The theme mod value.
	 * @param string $option The option key.
	 * @param mixed  $value  The theme mod value (second pass of the same value).
	 */
	return apply_filters( "eronex_theme_option_{$option}", $value, $option, $value );
}

/**
 * Converts a hex color code to an RGB or RGBA string.
 *
 * @since 0.0.1
 *
 * @param string     $hex     Hex color code (e.g. `#ff0000` or `f00`).
 * @param bool       $rgb     Optional. Whether to return `rgb(...)` format. Default true.
 * @param int|float  $opacity Optional. Alpha channel value. Default 1.
 * @return string Escaped RGB/RGBA color string.
 */
function eronex_hex_to_rgb( $hex, $rgb = true, $opacity = 1 ) {
	// Remove '#' if present
	$hex = ltrim( $hex, '#' );

	// Ensure hex is 6 characters
	if ( 3 === strlen( $hex ) ) {
		$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
	}

	// Convert hex to decimal
	$r = hexdec( substr( $hex, 0, 2 ) );
	$g = hexdec( substr( $hex, 2, 2 ) );
	$b = hexdec( substr( $hex, 4, 2 ) );

	if ( $rgb ) {
		return esc_html( "rgb($r, $g, $b, $opacity)" );
	}

	if ( empty( $opacity ) ) {
		return esc_html( "$r, $g, $b" );
	}

	return esc_html( "$r, $g, $b, $opacity" );
}

/**
 * Whether the current view is a WooCommerce product archive.
 *
 * @since 0.0.1
 *
 * @return bool True when viewing the shop or a product taxonomy archive.
 */
function eronex_is_woocommerce_archive() {
	return function_exists( 'is_shop' ) && ( is_shop() || is_product_taxonomy() );
}

/**
 * Whether the current view is a single WooCommerce product.
 *
 * @since 0.0.1
 *
 * @return bool True when viewing a single product.
 */
function eronex_is_woocommerce_single() {
	return function_exists( 'is_product' ) && is_product();
}

/**
 * Returns the banner title for the current query context.
 *
 * Resolves a title for product, shop, taxonomy, archive, search, 404,
 * blog, or singular views.
 *
 * @since 0.0.1
 *
 * @return string The filtered banner title for the current context.
 */
function eronex_banner_title() {

	if ( eronex_is_woocommerce_single() ) {
		$title = get_the_title();
	} elseif ( function_exists( 'is_shop' ) && is_shop() ) {
		$shop_title = get_the_title( wc_get_page_id( 'shop' ) );
		$title      = $shop_title ? $shop_title : esc_html__( 'Shop', 'eronex' );
	} elseif ( function_exists( 'is_product_taxonomy' ) && is_product_taxonomy() ) {
		$title = single_term_title( '', false );
	} elseif ( is_category() || is_tag() ) {
		$title = single_term_title( '', false );
	} elseif ( is_author() ) {
		$title = get_the_author();
	} elseif ( is_year() ) {
		$title = get_the_date( _x( 'Y', 'yearly archives date format', 'eronex' ) );
	} elseif ( is_month() ) {
		$title = get_the_date( _x( 'F Y', 'monthly archives date format', 'eronex' ) );
	} elseif ( is_day() ) {
		$title = get_the_date( _x( 'F j, Y', 'daily archives date format', 'eronex' ) );
	} elseif ( is_search() ) {
		$title = esc_html__( 'Search results for: ', 'eronex' ) . '"' . get_search_query() . '"';
	} elseif ( is_404() ) {
		$title = esc_html__( 'Not found', 'eronex' );
	} elseif ( is_home() ) {
		$title = get_option( 'page_for_posts' ) ? get_the_title( get_option( 'page_for_posts' ) ) : esc_html__( 'Blog', 'eronex' );
	} elseif ( is_archive() ) {
		$title = get_the_archive_title();
	} else {
		$title = get_the_title();
	}

	/**
	 * Filters the banner title for the current view.
	 *
	 * @since 0.0.1
	 *
	 * @param string $title The banner title with HTML tags stripped.
	 */
	return apply_filters( 'eronex_banner_title', wp_strip_all_tags( $title ) );
}

/**
 * Builds the breadcrumb trail for the current query context.
 *
 * @since 0.0.1
 *
 * @return array[] List of breadcrumb items. Each item may include `url`, `title`, and `class`.
 */
function eronex_breadcrumbs_list() {

	$home_title = esc_html__( 'Home', 'eronex' );
	$home_url   = esc_url( home_url() );

	$breadcrumbs = array(
		array(
			'url'   => $home_url,
			'title' => $home_title,
			'class' => 'breadcrumb-home',
		),
	);

	if ( is_home() ) {

		$breadcrumbs[] = array(
			'title' => get_option( 'page_for_posts' ) ? get_the_title( get_option( 'page_for_posts' ) ) : esc_html__( 'Blog', 'eronex' ),
		);

	} elseif ( is_category() ) {

		$category = get_queried_object();

		$breadcrumbs[] = array(
			'title' => esc_html(
				sprintf(
				/* translators: %s: Category */
					__( 'Category: %s', 'eronex' ),
					$category->name
				)
			),
		);

	} elseif ( eronex_is_woocommerce_single() ) {

		$shop_page_id = wc_get_page_id( 'shop' );

		if ( $shop_page_id > 0 ) {
			$breadcrumbs[] = array(
				'url'   => esc_url( get_permalink( $shop_page_id ) ),
				'title' => esc_html( get_the_title( $shop_page_id ) ),
			);
		}

		$terms = get_the_terms( get_the_ID(), 'product_cat' );

		if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
			$term      = $terms[0];
			$ancestors = array_reverse( get_ancestors( $term->term_id, 'product_cat', 'taxonomy' ) );

			foreach ( $ancestors as $ancestor_id ) {
				$ancestor = get_term( $ancestor_id, 'product_cat' );

				if ( $ancestor && ! is_wp_error( $ancestor ) ) {
					$breadcrumbs[] = array(
						'url'   => esc_url( get_term_link( $ancestor ) ),
						'title' => esc_html( $ancestor->name ),
					);
				}
			}

			$breadcrumbs[] = array(
				'url'   => esc_url( get_term_link( $term ) ),
				'title' => esc_html( $term->name ),
			);
		}

		$breadcrumbs[] = array(
			'title' => esc_html( get_the_title() ),
		);

	} elseif ( is_single() ) {

		$categories = get_the_category();

		if ( ! empty( $categories ) ) {
			$category = $categories[0];

			$breadcrumbs[] = array(
				'url'   => esc_url( get_category_link( $category->term_id ) ),
				'title' => esc_html( $category->name ),
			);
		}

		$breadcrumbs[] = array(
			'title' => esc_html( get_the_title() ),
		);

	} elseif ( is_page() ) {

		$current_post = get_post();

		if ( $current_post->post_parent ) {
			$parent_id = $current_post->post_parent;

			while ( $parent_id ) {
				$page_item = get_post( $parent_id );

				$breadcrumbs[] = array(
					'url'   => esc_url( get_permalink( $page_item->ID ) ),
					'title' => esc_html( get_the_title( $page_item->ID ) ),
				);

				$parent_id = $page_item->post_parent;
			}
		}

		$breadcrumbs[] = array(
			'title' => esc_html( get_the_title() ),
		);

	} elseif ( function_exists( 'is_product_taxonomy' ) && is_product_taxonomy() ) {

		$shop_page_id = wc_get_page_id( 'shop' );

		if ( $shop_page_id > 0 ) {
			$breadcrumbs[] = array(
				'url'   => esc_url( get_permalink( $shop_page_id ) ),
				'title' => esc_html( get_the_title( $shop_page_id ) ),
			);
		}

		$term = get_queried_object();

		if ( $term && ! is_wp_error( $term ) ) {
			$ancestors = array_reverse( get_ancestors( $term->term_id, $term->taxonomy, 'taxonomy' ) );

			foreach ( $ancestors as $ancestor_id ) {
				$ancestor = get_term( $ancestor_id, $term->taxonomy );

				if ( $ancestor && ! is_wp_error( $ancestor ) ) {
					$breadcrumbs[] = array(
						'url'   => esc_url( get_term_link( $ancestor ) ),
						'title' => esc_html( $ancestor->name ),
					);
				}
			}

			$breadcrumbs[] = array(
				'title' => esc_html( $term->name ),
			);
		}

	} elseif ( function_exists( 'is_shop' ) && is_shop() ) {

		$breadcrumbs[] = array(
			'title' => esc_html( get_the_title( wc_get_page_id( 'shop' ) ) ?: esc_html__( 'Shop', 'eronex' ) ),
		);

	} elseif ( is_tag() ) {

		$breadcrumbs[] = array(
			'title' => esc_html(
				sprintf(
				/* translators: %s: Tag */
					__( 'Tag: %s', 'eronex' ),
					single_tag_title( '', false )
				)
			),
		);

	} elseif ( is_author() ) {

		$author = get_queried_object();

		$breadcrumbs[] = array(
			'title' => esc_html(
				sprintf(
				/* translators: %s: Author name */
					__( 'Author: %s', 'eronex' ),
					$author->display_name
				)
			),
		);

	} elseif ( is_post_type_archive() ) {

		$breadcrumbs[] = array(
			'title' => esc_html( post_type_archive_title( '', false ) ),
		);

	} elseif ( is_archive() ) {

		$breadcrumbs[] = array(
			'title' => esc_html( get_the_archive_title() ),
		);

	} elseif ( is_search() ) {

		$search_title = sprintf(
		/* translators: %s: Search query */
			__( 'Search Results for "%s"', 'eronex' ),
			get_search_query()
		);

		$breadcrumbs[] = array(
			'title' => esc_html( $search_title ),
		);

	} elseif ( is_404() ) {

		$breadcrumbs[] = array(
			'title' => esc_html__( 'Not found', 'eronex' ),
		);

	}

	/**
	 * Filters the breadcrumb trail items for the current view.
	 *
	 * @since 0.0.1
	 *
	 * @param array[] $breadcrumbs List of breadcrumb items.
	 */
	return apply_filters( 'eronex_breadcrumb_list', $breadcrumbs );
}

/**
 * Echoes the post excerpt, optionally truncated to a word limit.
 *
 * @since 0.0.1
 *
 * @param int|null $limit Optional. Maximum number of words. Null for the full excerpt.
 * @return void
 */
function eronex_excerpt( $limit = null ) {

	$limit = ! empty( $limit ) ? absint( $limit ) : null;

	$excerpt = wp_strip_all_tags( get_the_excerpt() );

	if ( null !== $limit && $limit > 0 ) {
		$words = preg_split( '/\s+/', $excerpt );

		if ( count( $words ) > $limit ) {
			$excerpt = implode( ' ', array_slice( $words, 0, $limit ) ) . '...';
		}
	}

	echo esc_html( $excerpt );
}
