<?php
/**
 * Reusable template helpers.
 *
 * @package Gustavo_Portfolio
 */

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

/**
 * Resolve an image source, preferring an existing format and falling back safely.
 *
 * @param string $basename  File basename without extension.
 * @param string $preferred Preferred extension.
 * @return string
 */
function gustavoo_portfolio_get_image_source( $basename, $preferred = 'webp' ) {
	$basename  = preg_replace( '/[^a-z0-9-]/', '', strtolower( (string) $basename ) );
	$preferred = in_array( $preferred, array( 'webp', 'png' ), true ) ? $preferred : 'webp';
	$formats   = array_unique( array( $preferred, 'webp', 'png' ) );

	if ( ! $basename ) {
		return '';
	}

	foreach ( $formats as $format ) {
		$relative_path = '/assets/images/' . $basename . '.' . $format;

		if ( file_exists( get_theme_file_path( $relative_path ) ) ) {
			return get_theme_file_uri( $relative_path );
		}
	}

	// Keep a deterministic URI while assets are being provisioned by deployment.
	return get_theme_file_uri( '/assets/images/' . $basename . '.' . $preferred );
}

/**
 * Return image URLs for a picture element.
 *
 * @param string $basename File basename without extension.
 * @return array{webp:string,png:string,fallback:string}
 */
function gustavoo_portfolio_get_picture_sources( $basename ) {
	$webp_path = '/assets/images/' . $basename . '.webp';
	$png_path  = '/assets/images/' . $basename . '.png';
	$has_webp  = file_exists( get_theme_file_path( $webp_path ) );
	$has_png   = file_exists( get_theme_file_path( $png_path ) );

	return array(
		'webp'     => $has_webp ? get_theme_file_uri( $webp_path ) : '',
		'png'      => $has_png ? get_theme_file_uri( $png_path ) : '',
		'fallback' => $has_png ? get_theme_file_uri( $png_path ) : get_theme_file_uri( $webp_path ),
	);
}

/**
 * Print the configured logo or the bundled brand mark.
 *
 * @return void
 */
function gustavoo_portfolio_the_brand() {
	$site_name = get_bloginfo( 'name' );

	if ( has_custom_logo() ) {
		echo get_custom_logo(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Core-generated custom logo markup.
		return;
	}

	$sources = gustavoo_portfolio_get_picture_sources( 'logo-mark' );
	?>
	<a class="custom-logo-link" href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
		<picture>
			<?php if ( $sources['webp'] ) : ?>
				<source srcset="<?php echo esc_url( $sources['webp'] ); ?>" type="image/webp">
			<?php endif; ?>
			<img class="custom-logo" src="<?php echo esc_url( $sources['fallback'] ); ?>" width="64" height="64" alt="<?php echo esc_attr( $site_name ); ?>">
		</picture>
	</a>
	<?php
}

/**
 * Return the appropriate URL for a front-page section.
 *
 * @param string $section_id Section anchor without hash.
 * @return string
 */
function gustavoo_portfolio_section_url( $section_id ) {
	$section_id = sanitize_html_class( $section_id );

	if ( is_front_page() ) {
		return '#' . $section_id;
	}

	return home_url( '/#' . $section_id );
}

/**
 * Return the configured posts-page URL.
 *
 * @return string
 */
function gustavoo_portfolio_get_blog_url() {
	$posts_page_id = absint( get_option( 'page_for_posts' ) );

	if ( $posts_page_id ) {
		$url = get_permalink( $posts_page_id );

		if ( $url ) {
			return $url;
		}
	}

	return home_url( '/blog/' );
}

/** Render the editorial category navigation used on news pages. */
function gustavoo_portfolio_news_category_menu() {
	if ( has_nav_menu( 'news_categories' ) ) {
		?>
		<nav class="news-category-nav" aria-label="<?php esc_attr_e( 'Categorias de notícias', 'gustavoo-portfolio' ); ?>">
			<div class="news-category-nav__inner site-shell">
				<?php
				wp_nav_menu(
					array(
						'theme_location' => 'news_categories',
						'menu_class'     => 'news-category-nav__list',
						'container'      => false,
						'fallback_cb'    => false,
						'depth'          => 1,
					)
				);
				?>
			</div>
		</nav>
		<?php
		return;
	}

	$categories = get_categories(
		array(
			'hide_empty' => true,
			'exclude'    => array( absint( get_option( 'default_category' ) ) ),
			'orderby'    => 'name',
			'order'      => 'ASC',
		)
	);

	if ( empty( $categories ) ) {
		return;
	}

	$current_category_id = is_category() ? (int) get_queried_object_id() : 0;
	?>
	<nav class="news-category-nav" aria-label="<?php esc_attr_e( 'Categorias de notícias', 'gustavoo-portfolio' ); ?>">
		<div class="news-category-nav__inner site-shell">
			<a class="news-category-nav__link<?php echo is_home() ? ' is-current' : ''; ?>" href="<?php echo esc_url( gustavoo_portfolio_get_blog_url() ); ?>"><?php esc_html_e( 'Últimas notícias', 'gustavoo-portfolio' ); ?></a>
			<?php foreach ( $categories as $category ) : ?>
				<a class="news-category-nav__link<?php echo $current_category_id === (int) $category->term_id ? ' is-current' : ''; ?>" href="<?php echo esc_url( get_category_link( $category ) ); ?>"><?php echo esc_html( $category->name ); ?></a>
			<?php endforeach; ?>
		</div>
	</nav>
	<?php
}

/** Print editorial categories inside the mobile hamburger panel. */
function gustavoo_portfolio_mobile_news_category_menu() {
	if ( has_nav_menu( 'news_categories' ) ) {
		?>
		<div class="mobile-news-categories">
			<p class="mobile-news-categories__title"><?php esc_html_e( 'Categorias', 'gustavoo-portfolio' ); ?></p>
			<?php
			wp_nav_menu(
				array(
					'theme_location' => 'news_categories',
					'menu_class'     => 'mobile-news-categories__list',
					'container'      => false,
					'fallback_cb'    => false,
					'depth'          => 1,
				)
			);
			?>
		</div>
		<?php
		return;
	}

	$categories = get_categories(
		array(
			'hide_empty' => true,
			'exclude'    => array( absint( get_option( 'default_category' ) ) ),
			'orderby'    => 'name',
			'order'      => 'ASC',
		)
	);

	if ( empty( $categories ) ) {
		return;
	}

	$current_category_id = is_category() ? (int) get_queried_object_id() : 0;
	?>
	<div class="mobile-news-categories">
		<p class="mobile-news-categories__title"><?php esc_html_e( 'Categorias', 'gustavoo-portfolio' ); ?></p>
		<ul class="mobile-news-categories__list">
			<li><a class="<?php echo is_home() ? 'is-current' : ''; ?>" href="<?php echo esc_url( gustavoo_portfolio_get_blog_url() ); ?>"><?php esc_html_e( 'Últimas notícias', 'gustavoo-portfolio' ); ?></a></li>
			<?php foreach ( $categories as $category ) : ?>
				<li><a class="<?php echo $current_category_id === (int) $category->term_id ? 'is-current' : ''; ?>" href="<?php echo esc_url( get_category_link( $category ) ); ?>"><?php echo esc_html( $category->name ); ?></a></li>
			<?php endforeach; ?>
		</ul>
	</div>
	<?php
}

/**
 * Resolve the image used by an editorial card.
 *
 * Seeded demo posts use a local theme image until an editor assigns a
 * featured image in WordPress.
 *
 * @param int $post_id Post ID.
 * @param string $size Registered image size.
 * @return string
 */
function gustavoo_portfolio_get_news_image_url( $post_id = 0, $size = 'gustavoo-post-card' ) {
	$post_id = $post_id ? absint( $post_id ) : get_the_ID();
	$image   = get_the_post_thumbnail_url( $post_id, $size );

	if ( $image ) {
		return $image;
	}

	return (string) get_post_meta( $post_id, '_gso_news_image', true );
}

/**
 * Accessible fallback menu for a site that has not assigned a WordPress menu yet.
 *
 * @return void
 */
function gustavoo_portfolio_primary_menu_fallback() {
	?>
	<ul id="primary-menu" class="primary-menu">
		<li class="menu-item"><a href="<?php echo esc_url( gustavoo_portfolio_section_url( 'sobre' ) ); ?>"><?php esc_html_e( 'Sobre', 'gustavoo-portfolio' ); ?></a></li>
		<li class="menu-item"><a href="<?php echo esc_url( gustavoo_portfolio_section_url( 'servicos' ) ); ?>"><?php esc_html_e( 'Serviços', 'gustavoo-portfolio' ); ?></a></li>
		<li class="menu-item"><a href="<?php echo esc_url( gustavoo_portfolio_section_url( 'projetos' ) ); ?>"><?php esc_html_e( 'Projetos', 'gustavoo-portfolio' ); ?></a></li>
		<li class="menu-item"><a href="<?php echo esc_url( gustavoo_portfolio_get_blog_url() ); ?>"><?php esc_html_e( 'Blog', 'gustavoo-portfolio' ); ?></a></li>
		<li class="menu-item"><a href="<?php echo esc_url( gustavoo_portfolio_section_url( 'contato' ) ); ?>"><?php esc_html_e( 'Contato', 'gustavoo-portfolio' ); ?></a></li>
	</ul>
	<?php
}

/**
 * Return supported social profile links.
 *
 * @return array<string, array{label:string,url:string}>
 */
function gustavoo_portfolio_get_social_links() {
	$profiles = array(
		'linkedin'  => array(
			'label' => __( 'LinkedIn', 'gustavoo-portfolio' ),
			'url'   => (string) gustavoo_portfolio_get_setting( 'linkedin_url' ),
		),
		'instagram' => array(
			'label' => __( 'Instagram', 'gustavoo-portfolio' ),
			'url'   => (string) gustavoo_portfolio_get_setting( 'instagram_url' ),
		),
	);

	return array_filter(
		$profiles,
		static function ( $profile ) {
			return ! empty( $profile['url'] );
		}
	);
}

/**
 * Print social links with explicit new-window text for assistive technology.
 *
 * @param string $class Optional list class.
 * @return void
 */
function gustavoo_portfolio_social_links( $class = 'social-links' ) {
	$profiles = gustavoo_portfolio_get_social_links();

	if ( empty( $profiles ) ) {
		return;
	}

	printf( '<ul class="%s">', esc_attr( $class ) );

	foreach ( $profiles as $slug => $profile ) {
		printf(
			'<li class="social-links__item social-links__item--%1$s"><a href="%2$s" target="_blank" rel="noopener noreferrer external"><span>%3$s</span><span class="screen-reader-text"> %4$s</span></a></li>',
			esc_attr( $slug ),
			esc_url( $profile['url'] ),
			esc_html( $profile['label'] ),
			esc_html__( '(abre em uma nova guia)', 'gustavoo-portfolio' )
		);
	}

	echo '</ul>';
}

/**
 * Print share links for a blog post using inline brand SVG icons.
 *
 * @param string $class Optional wrapper class.
 * @return void
 */
function gustavoo_portfolio_post_share_links( $class = 'entry-share' ) {
	$share_url   = rawurlencode( get_permalink() );
	$share_title = rawurlencode( get_the_title() );
	$links       = array(
		'WhatsApp' => array(
			'url' => 'https://api.whatsapp.com/send?text=' . $share_title . '%20' . $share_url,
			'icon' => '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M20.5 3.5A11.8 11.8 0 0 0 12.1 0C5.6 0 .3 5.3.3 11.8c0 2.1.5 4.1 1.6 5.9L.2 23.8l6.3-1.7a11.8 11.8 0 0 0 5.6 1.4h.1c6.5 0 11.8-5.3 11.8-11.8 0-3.1-1.2-6-3.5-8.2Zm-8.4 17.9c-1.8 0-3.5-.5-5-1.4l-.4-.2-3.7 1 1-3.6-.2-.4a9.6 9.6 0 1 1 8.3 4.6Zm5.3-7.2c-.3-.2-1.7-.8-2-.9-.3-.1-.5-.2-.7.2-.2.3-.8.9-.9 1.1-.2.2-.3.2-.6.1-1.7-.8-2.8-1.5-3.9-3.4-.3-.5.3-.5.8-1.7.1-.2 0-.4 0-.6l-.9-2.1c-.2-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.4s1 2.8 1.1 3c.1.2 2 3.1 4.9 4.4 1.8.8 2.5.9 3.4.8.5-.1 1.7-.7 1.9-1.4.2-.7.2-1.3.1-1.4-.1-.2-.3-.3-.6-.4Z" fill="currentColor"/></svg>',
		),
		'Facebook' => array(
			'url' => 'https://www.facebook.com/sharer/sharer.php?u=' . $share_url,
			'icon' => '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M13.5 22v-8h2.7l.4-3h-3.1V9.1c0-.9.3-1.5 1.6-1.5h1.7V4.9c-.3 0-1.3-.1-2.5-.1-2.5 0-4.2 1.5-4.2 4.3V11H7.3v3h2.8v8h3.4Z" fill="currentColor"/></svg>',
		),
		'X' => array(
			'url' => 'https://twitter.com/intent/tweet?text=' . $share_title . '&url=' . $share_url,
			'icon' => '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M18.9 2h3.7l-8.1 9.3L24 22h-7.4l-5.8-7.6L4.2 22H.5l8.4-9.7L0 2h7.6l5.2 6.9L18.9 2Zm-1.3 17.9h2.1L6.4 4H4.1l13.5 15.9Z" fill="currentColor"/></svg>',
		),
		'LinkedIn' => array(
			'url' => 'https://www.linkedin.com/sharing/share-offsite/?url=' . $share_url,
			'icon' => '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M5.2 3.4A2.2 2.2 0 1 1 .8 3.4a2.2 2.2 0 0 1 4.4 0ZM1.1 7h4.2v13.5H1.1V7Zm6.8 0h4v1.8h.1c.6-1.1 2-2.2 4.1-2.2 4.4 0 5.2 2.9 5.2 6.7v7.2h-4.2v-6.4c0-1.5 0-3.5-2.1-3.5s-2.4 1.7-2.4 3.4v6.5H7.9V7Z" fill="currentColor"/></svg>',
		),
	);

	printf( '<div class="%1$s" aria-label="%2$s">', esc_attr( $class ), esc_attr__( 'Compartilhar postagem', 'gustavoo-portfolio' ) );

	foreach ( $links as $label => $link ) {
		printf(
			'<a href="%1$s" target="_blank" rel="noopener noreferrer" aria-label="%2$s">%3$s<span class="screen-reader-text">%2$s</span></a>',
			esc_url( $link['url'] ),
			esc_attr( $label ),
			$link['icon'] // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static SVG markup.
		);
	}

	echo '</div>';
}

/**
 * Convert a configured phone number to a WhatsApp URL.
 *
 * @param string $phone   Raw phone number.
 * @param string $message Optional pre-filled conversation message.
 * @return string
 */
function gustavoo_portfolio_get_whatsapp_url( $phone, $message = '' ) {
	$digits = preg_replace( '/\D+/', '', (string) $phone );

	if ( ! $digits ) {
		return '';
	}

	if ( in_array( strlen( $digits ), array( 10, 11 ), true ) ) {
		$digits = '55' . $digits;
	}

	$url     = 'https://wa.me/' . $digits;
	$message = trim( wp_strip_all_tags( (string) $message ) );

	if ( '' !== $message ) {
		$url .= '?text=' . rawurlencode( $message );
	}

	return $url;
}

/** Print the configured floating WhatsApp contact link. */
function gustavoo_portfolio_the_whatsapp_float() {
	$phone   = (string) gustavoo_portfolio_get_setting( 'whatsapp' );
	$message = (string) gustavoo_portfolio_get_setting( 'whatsapp_message' );
	$url     = gustavoo_portfolio_get_whatsapp_url( $phone, $message );

	if ( ! $url ) {
		return;
	}
	?>
	<div class="whatsapp-float-wrap"<?php echo is_customize_preview() ? ' data-customize-partial-id="gustavoo_portfolio_whatsapp_shortcut"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static attribute. ?>>
		<a class="whatsapp-float" href="<?php echo esc_url( $url ); ?>" target="_blank" rel="noopener noreferrer external" aria-label="<?php esc_attr_e( 'Conversar pelo WhatsApp (abre em uma nova guia)', 'gustavoo-portfolio' ); ?>">
			<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path fill="currentColor" d="M20.5 3.5A11.8 11.8 0 0 0 12.1 0C5.6 0 .3 5.3.3 11.8c0 2.1.5 4.1 1.6 5.9L.2 23.8l6.3-1.7a11.8 11.8 0 0 0 5.6 1.4h.1c6.5 0 11.8-5.3 11.8-11.8 0-3.1-1.2-6-3.5-8.2ZM12.1 21.4c-1.8 0-3.5-.5-5-1.4l-.4-.2-3.7 1 1-3.6-.2-.4a9.6 9.6 0 1 1 8.3 4.6Zm5.3-7.2c-.3-.2-1.7-.8-2-.9-.3-.1-.5-.2-.7.2-.2.3-.8.9-.9 1.1-.2.2-.3.2-.6.1-1.7-.8-2.8-1.5-3.9-3.4-.3-.5.3-.5.8-1.7.1-.2 0-.4 0-.6l-.9-2.1c-.2-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.4s1 2.8 1.1 3c.1.2 2 3.1 4.9 4.4 1.8.8 2.5.9 3.4.8.5-.1 1.7-.7 1.9-1.4.2-.7.2-1.3.1-1.4-.1-.2-.3-.3-.6-.4Z"/></svg>
		</a>
	</div>
	<?php
}

/**
 * Validate an external project URL without making a network request.
 *
 * @param string $url Candidate URL.
 * @return string Empty string when invalid.
 */
function gustavoo_portfolio_validate_project_url( $url ) {
	$url    = esc_url_raw( (string) $url, array( 'http', 'https' ) );
	$scheme = wp_parse_url( $url, PHP_URL_SCHEME );
	$host   = wp_parse_url( $url, PHP_URL_HOST );

	if ( ! $url || ! $host || ! in_array( strtolower( (string) $scheme ), array( 'http', 'https' ), true ) ) {
		return '';
	}

	return $url;
}

/**
 * Return featured projects first, then fill the requested limit by menu order.
 *
 * @param int $limit Maximum number of projects.
 * @return WP_Post[]
 */
function gustavoo_portfolio_get_home_projects( $limit = 6 ) {
	$limit = max( 1, min( 24, absint( $limit ) ) );

	if ( ! post_type_exists( 'gso_project' ) ) {
		return array();
	}

	$base_args = array(
		'post_type'              => 'gso_project',
		'post_status'            => 'publish',
		'posts_per_page'         => $limit * 3,
		'orderby'                => array(
			'menu_order' => 'ASC',
			'date'       => 'DESC',
		),
		'ignore_sticky_posts'    => true,
		'no_found_rows'          => true,
		'update_post_term_cache' => true,
	);

	$featured_args               = $base_args;
	$featured_args['meta_query'] = array(
		array(
			'key'     => '_gso_project_featured',
			'value'   => array( '1', 'yes', 'on', 'true' ),
			'compare' => 'IN',
		),
	);

	$featured = get_posts( $featured_args );
	$others   = get_posts( $base_args );
	$projects = array();
	$seen     = array();

	foreach ( array_merge( $featured, $others ) as $project ) {
		if ( isset( $seen[ $project->ID ] ) ) {
			continue;
		}

		$url = gustavoo_portfolio_validate_project_url( get_post_meta( $project->ID, '_gso_project_url', true ) );

		if ( ! $url ) {
			continue;
		}

		$seen[ $project->ID ] = true;
		$projects[]           = $project;

		if ( count( $projects ) >= $limit ) {
			break;
		}
	}

	return $projects;
}

/**
 * Print post publication metadata.
 *
 * @return void
 */
function gustavoo_portfolio_posted_on() {
	$published = sprintf(
		'<time class="entry-date published" datetime="%1$s">%2$s</time>',
		esc_attr( get_the_date( DATE_W3C ) ),
		esc_html( get_the_date() )
	);

	printf(
		'<span class="posted-on"><span class="screen-reader-text">%1$s </span>%2$s</span>',
		esc_html__( 'Publicado em', 'gustavoo-portfolio' ),
		$published // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped immediately above.
	);
}

/**
 * Print the post author link.
 *
 * @return void
 */
function gustavoo_portfolio_posted_by() {
	printf(
		'<span class="byline"><span class="screen-reader-text">%1$s </span><a class="url fn n" href="%2$s">%3$s</a></span>',
		esc_html__( 'Por', 'gustavoo-portfolio' ),
		esc_url( get_author_posts_url( (int) get_the_author_meta( 'ID' ) ) ),
		esc_html( get_the_author() )
	);
}

/**
 * Estimate reading time from the current post content.
 *
 * @param int|null $post_id Optional post ID.
 * @return string
 */
function gustavoo_portfolio_reading_time( $post_id = null ) {
	$post_id = $post_id ? absint( $post_id ) : get_the_ID();
	$content = wp_strip_all_tags( strip_shortcodes( (string) get_post_field( 'post_content', $post_id ) ) );
	$words   = preg_split( '/\s+/u', trim( $content ), -1, PREG_SPLIT_NO_EMPTY );
	$minutes = max( 1, (int) ceil( count( is_array( $words ) ? $words : array() ) / 220 ) );

	return sprintf(
		/* translators: %d: reading time in minutes. */
		_n( '%d min de leitura', '%d min de leitura', $minutes, 'gustavoo-portfolio' ),
		$minutes
	);
}

/**
 * Print category and tag links for a post.
 *
 * @return void
 */
function gustavoo_portfolio_entry_terms() {
	$categories = get_the_category_list( esc_html_x( ', ', 'category list separator', 'gustavoo-portfolio' ) );
	$tags       = get_the_tag_list( '', esc_html_x( ', ', 'tag list separator', 'gustavoo-portfolio' ) );

	if ( $categories ) {
		printf(
			'<div class="entry-terms entry-terms--categories"><span>%1$s</span> %2$s</div>',
			esc_html__( 'Categorias:', 'gustavoo-portfolio' ),
			wp_kses_post( $categories )
		);
	}

	if ( $tags ) {
		printf(
			'<div class="entry-terms entry-terms--tags"><span>%1$s</span> %2$s</div>',
			esc_html__( 'Tags:', 'gustavoo-portfolio' ),
			wp_kses_post( $tags )
		);
	}
}

/**
 * Print main-query pagination with accessible labels.
 *
 * @return void
 */
function gustavoo_portfolio_pagination() {
	the_posts_pagination(
		array(
			'mid_size'           => 1,
			'prev_text'          => sprintf( '<span aria-hidden="true">←</span> %s', esc_html__( 'Anteriores', 'gustavoo-portfolio' ) ),
			'next_text'          => sprintf( '%s <span aria-hidden="true">→</span>', esc_html__( 'Próximos', 'gustavoo-portfolio' ) ),
			'screen_reader_text' => __( 'Navegação entre páginas', 'gustavoo-portfolio' ),
		)
	);
}
