<?php
/**
 * Renderer class.
 *
 * Entry point for producing related-posts HTML. Actual markup lives in
 * templates/default.php (or a theme override at {theme}/igit-rpwt/template.php).
 *
 * @package IGIT_RPWT
 */

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

class IGIT_RPWT_Renderer {

	/**
	 * Render related posts for the given post ID.
	 *
	 * Variables passed to the template as $igit_rpwt_data:
	 *  post_id    — int
	 *  posts      — WP_Post[]
	 *  settings   — array  (full settings array)
	 *  layout     — string ('grid', 'list', or 'compact')
	 *  show_thumb — bool
	 *  show_title — bool
	 *  thumb_size — string
	 *
	 * @param int   $post_id
	 * @param array $args    Override settings for shortcode / block use.
	 * @return string HTML string.
	 */
	public static function render( $post_id, array $args = array() ) {
		$settings = IGIT_RPWT_Settings::get_all();

		// ── Per-post meta overrides ───────────────────────────────────────────
		$meta = class_exists( 'IGIT_RPWT_Metabox' )
			? IGIT_RPWT_Metabox::get_meta( $post_id )
			: array();

		// If this post has related posts disabled, return empty string immediately.
		if ( ! empty( $meta['disabled'] ) ) {
			return '';
		}

		// Resolve values: explicit $args win, then per-post meta, then global settings.
		$post_count = isset( $args['post_count'] ) && null !== $args['post_count']
			? absint( $args['post_count'] )
			: ( '' !== ( $meta['post_count'] ?? '' ) ? absint( $meta['post_count'] ) : absint( $settings['post_count'] ) );

		$layout = isset( $args['layout'] ) && null !== $args['layout']
			? sanitize_key( $args['layout'] )
			: ( ! empty( $meta['layout'] ) ? sanitize_key( $meta['layout'] ) : $settings['layout'] );

		$relate_by = isset( $args['relate_by'] ) && null !== $args['relate_by']
			? sanitize_key( $args['relate_by'] )
			: ( ! empty( $meta['relate_by'] ) ? $meta['relate_by'] : $settings['relate_by'] );

		$show_thumb = isset( $args['show_thumbnail'] ) ? (bool) $args['show_thumbnail'] : (bool) $settings['show_thumbnail'];
		$show_title = isset( $args['show_title'] )     ? (bool) $args['show_title']     : (bool) $settings['show_title'];
		$thumb_size = $settings['thumbnail_size'];

		// Allow callers (e.g. Elementor widget) to override show_excerpt per-instance.
		if ( isset( $args['show_excerpt'] ) ) {
			$settings['show_excerpt'] = (bool) $args['show_excerpt'];
		}

		$t0    = microtime( true );
		$posts = IGIT_RPWT_Query::get_related_posts( $post_id, array(
			'post_count' => $post_count,
			'relate_by'  => $relate_by,
		) );
		$query_time_ms = ( microtime( true ) - $t0 ) * 1000;

		// Prepend pinned posts (always shown first, regardless of query results).
		if ( ! empty( $meta['pinned_posts'] ) ) {
			$pinned_ids = array_map( 'absint', (array) $meta['pinned_posts'] );
			// Remove pinned IDs from the regular results to avoid duplicates.
			$posts = array_filter( $posts, function( $p ) use ( $pinned_ids ) {
				return ! in_array( (int) $p->ID, $pinned_ids, true );
			} );
			$pinned_objects = array_filter( array_map( 'get_post', $pinned_ids ) );
			$posts = array_merge( array_values( $pinned_objects ), array_values( $posts ) );
		}

		// Trim to the requested count.
		$posts = array_slice( $posts, 0, $post_count );

		// ── Template resolution ───────────────────────────────────────────────
		// Themes can override by placing a file at {theme}/igit-rpwt/template.php.
		$theme_tpl     = locate_template( array( 'igit-rpwt/template.php' ) );
		$template_file = $theme_tpl ? $theme_tpl : IGIT_RPWT_PLUGIN_DIR . 'templates/default.php';

		/**
		 * Filter the template file used to render related posts.
		 *
		 * @param string $template_file Absolute path to the template.
		 * @param int    $post_id       Current post ID.
		 */
		$template_file = apply_filters( 'igit_rpwt_template_file', $template_file, $post_id );

		// Data exposed to the template as $igit_rpwt_data.
		$igit_rpwt_data = array(
			'post_id'        => $post_id,
			'posts'          => $posts,
			'settings'       => $settings,
			'layout'         => $layout,
			'show_thumb'     => $show_thumb,
			'show_title'     => $show_title,
			'thumb_size'     => $thumb_size,
			'query_time_ms'  => $query_time_ms,
		);

		ob_start();
		include $template_file; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
		$output = ob_get_clean();

		/**
		 * Filter the complete related posts HTML output.
		 *
		 * @param string $output  The HTML string.
		 * @param int    $post_id Current post ID.
		 */
		return apply_filters( 'igit_rpwt_output', $output, $post_id );
	}
}
