<?php
/**
 * Classic Widget class.
 *
 * Displays related posts inside any widgetised area on single-post views.
 *
 * Usage: drag "Related Posts" from Appearance → Widgets to any sidebar.
 * Fields: widget title, post count, layout.
 * When placed on a non-singular page it outputs nothing.
 *
 * @package IGIT_RPWT
 */

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

class IGIT_RPWT_Widget extends WP_Widget {

	/**
	 * Register the widget with WordPress.
	 */
	public function __construct() {
		parent::__construct(
			'igit_rpwt_widget',
			__( 'Related Posts', 'igit-related-posts-with-thumb-images-after-posts' ),
			array(
				'description' => __( 'Displays related posts for the current single post/page.', 'igit-related-posts-with-thumb-images-after-posts' ),
				'classname'   => 'igit-rpwt-widget',
			)
		);
	}

	// ── Front-end output ─────────────────────────────────────────────────────

	/**
	 * Output the widget content.
	 *
	 * @param array $args     Widget area before/after markup.
	 * @param array $instance Saved widget settings.
	 */
	public function widget( $args, $instance ) {
		// Only render on singular views — the related-posts concept requires a source post.
		if ( ! is_singular() ) {
			return;
		}

		$post_id = get_queried_object_id();
		if ( ! $post_id ) {
			return;
		}

		// Build override args; omit keys so the renderer falls back to global settings.
		$render_args = array();

		if ( ! empty( $instance['post_count'] ) ) {
			$render_args['post_count'] = absint( $instance['post_count'] );
		}

		if ( ! empty( $instance['layout'] ) ) {
			$render_args['layout'] = sanitize_key( $instance['layout'] );
		}

		$html = IGIT_RPWT_Renderer::render( $post_id, $render_args );

		if ( '' === $html ) {
			return; // renderer returned nothing (no posts / disabled on this post).
		}

		// Widget wrapper — use theme-supplied markup.
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $args['before_widget'];

		$title = ! empty( $instance['title'] )
			? apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base )
			: '';

		if ( $title ) {
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $args['before_title'] . esc_html( $title ) . $args['after_title'];
		}

		// The renderer produces sanitised plugin HTML — safe to echo directly.
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $html;

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $args['after_widget'];
	}

	// ── Back-end form ────────────────────────────────────────────────────────

	/**
	 * Backend widget settings form.
	 *
	 * @param array $instance Previously saved settings.
	 * @return void
	 */
	public function form( $instance ) {
		$title      = ! empty( $instance['title'] )      ? $instance['title']               : '';
		$post_count = isset( $instance['post_count'] )   ? absint( $instance['post_count'] ) : (int) IGIT_RPWT_Settings::get( 'post_count' );
		$layout     = ! empty( $instance['layout'] )     ? $instance['layout']               : IGIT_RPWT_Settings::get( 'layout' );
		?>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
				<?php esc_html_e( 'Widget Title:', 'igit-related-posts-with-thumb-images-after-posts' ); ?>
			</label>
			<input
				class="widefat"
				type="text"
				id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>"
				value="<?php echo esc_attr( $title ); ?>">
			<small><?php esc_html_e( 'Leave blank to hide the widget heading.', 'igit-related-posts-with-thumb-images-after-posts' ); ?></small>
		</p>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'post_count' ) ); ?>">
				<?php esc_html_e( 'Number of posts (1–20):', 'igit-related-posts-with-thumb-images-after-posts' ); ?>
			</label>
			<input
				class="tiny-text"
				type="number"
				min="1"
				max="20"
				id="<?php echo esc_attr( $this->get_field_id( 'post_count' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'post_count' ) ); ?>"
				value="<?php echo esc_attr( $post_count ); ?>">
		</p>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'layout' ) ); ?>">
				<?php esc_html_e( 'Layout:', 'igit-related-posts-with-thumb-images-after-posts' ); ?>
			</label>
			<select
				class="widefat"
				id="<?php echo esc_attr( $this->get_field_id( 'layout' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'layout' ) ); ?>">
				<?php
				$layouts = array(
					'grid'    => __( 'Grid', 'igit-related-posts-with-thumb-images-after-posts' ),
					'list'    => __( 'List', 'igit-related-posts-with-thumb-images-after-posts' ),
					'compact' => __( 'Compact (text only)', 'igit-related-posts-with-thumb-images-after-posts' ),
				);
				foreach ( $layouts as $val => $lbl ) {
					printf(
						'<option value="%s" %s>%s</option>',
						esc_attr( $val ),
						selected( $layout, $val, false ),
						esc_html( $lbl )
					);
				}
				?>
			</select>
		</p>
		<?php
	}

	// ── Update ───────────────────────────────────────────────────────────────

	/**
	 * Sanitize widget settings on save.
	 *
	 * @param array $new_instance New values from form submission.
	 * @param array $old_instance Previous saved values.
	 * @return array Sanitized values.
	 */
	public function update( $new_instance, $old_instance ) {
		return array(
			'title'      => sanitize_text_field( $new_instance['title'] ?? '' ),
			'post_count' => min( 20, max( 1, absint( $new_instance['post_count'] ?? 4 ) ) ),
			'layout'     => in_array( $new_instance['layout'] ?? '', array( 'grid', 'list', 'compact' ), true )
				? $new_instance['layout']
				: 'grid',
		);
	}
}
