<?php
/**
 * Popular Posts widget.
 *
 * @package Rubik News
 */

defined( 'ABSPATH' ) || exit;

/**
 * Popular Posts widget class.
 */
class Rubik_News_Popular_Posts_Widget extends WP_Widget {

	/**
	 * Sets up the widget.
	 */
	public function __construct() {
		parent::__construct(
			'rubik_news_popular_posts_widget',
			__( 'Rubik News: Popular Posts', 'rubik-news' ),
			array(
				'classname'                   => 'widget_block widget_rubik_news_popular_posts',
				'description'                 => __(
					'Displays popular posts based on comment count.',
					'rubik-news'
				),
				'customize_selective_refresh' => true,
			)
		);
	}

	/**
	 * Displays the widget.
	 *
	 * @param array $args     Widget arguments.
	 * @param array $instance Widget settings.
	 */
	public function widget( $args, $instance ) {
		$title = ! empty( $instance['title'] )
			? $instance['title']
			: __( 'Popular Posts', 'rubik-news' );

		$posts_number = ! empty( $instance['posts_number'] )
			? absint( $instance['posts_number'] )
			: 5;

		$category = ! empty( $instance['category'] )
			? absint( $instance['category'] )
			: 0;

		$show_thumbnail = isset( $instance['show_thumbnail'] )
			? (bool) $instance['show_thumbnail']
			: true;

		$show_date = isset( $instance['show_date'] )
			? (bool) $instance['show_date']
			: true;

		$show_comments = isset( $instance['show_comments'] )
			? (bool) $instance['show_comments']
			: true;

		$query_args = array(
			'post_type'           => 'post',
			'posts_per_page'      => $posts_number,
			'post_status'         => 'publish',
			'orderby'             => 'comment_count',
			'order'               => 'DESC',
			'ignore_sticky_posts' => true,
			'no_found_rows'       => true,
		);

		if ( $category ) {
			$query_args['cat'] = $category;
		}

		$popular_query = new WP_Query( $query_args );

		if ( ! $popular_query->have_posts() ) {
			return;
		}

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

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

		<ol class="popular-posts-list">
			<?php
			$post_number = 1;

			while ( $popular_query->have_posts() ) :
				$popular_query->the_post();
				?>
				<li class="popular-post-item">
					<span class="popular-post-number" aria-hidden="true">
						<?php
						echo esc_html(
							str_pad( (string) $post_number, 2, '0', STR_PAD_LEFT )
						);
						?>
					</span>

					<?php if ( $show_thumbnail ) : ?>
						<div class="popular-post-thumbnail">
							<a
								href="<?php the_permalink(); ?>"
								aria-label="<?php echo esc_attr( get_the_title() ); ?>"
							>
								<?php
								if ( has_post_thumbnail() ) {
									the_post_thumbnail(
										'thumbnail',
										array(
											'loading' => 'lazy',
										)
									);
								} else {
									?>
									<span class="popular-post-placeholder"></span>
									<?php
								}
								?>
							</a>
						</div><!-- .popular-post-thumbnail -->
					<?php endif; ?>

					<div class="popular-post-content">
						<h3 class="popular-post-title">
							<a href="<?php the_permalink(); ?>">
								<?php the_title(); ?>
							</a>
						</h3>

						<?php if ( $show_date || $show_comments ) : ?>
							<div class="popular-post-meta">
								<?php if ( $show_date ) : ?>
									<span class="popular-post-date">
										<?php echo esc_html( get_the_date() ); ?>
									</span>
								<?php endif; ?>

								<?php if ( $show_date && $show_comments ) : ?>
									<span
										class="popular-meta-separator"
										aria-hidden="true"
									>
										•
									</span>
								<?php endif; ?>

								<?php if ( $show_comments ) : ?>
									<span class="popular-post-comments">
										<i
											class="far fa-comment"
											aria-hidden="true"
										></i>

										<?php
										echo esc_html(
											get_comments_number()
										);
										?>
									</span>
								<?php endif; ?>
							</div><!-- .popular-post-meta -->
						<?php endif; ?>
					</div><!-- .popular-post-content -->
				</li>
				<?php
				$post_number++;
			endwhile;
			?>
		</ol><!-- .popular-posts-list -->

		<?php
		wp_reset_postdata();

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

	/**
	 * Displays the widget settings form.
	 *
	 * @param array $instance Current widget settings.
	 */
	public function form( $instance ) {
		$title = isset( $instance['title'] )
			? $instance['title']
			: __( 'Popular Posts', 'rubik-news' );

		$posts_number = isset( $instance['posts_number'] )
			? absint( $instance['posts_number'] )
			: 5;

		$category = isset( $instance['category'] )
			? absint( $instance['category'] )
			: 0;

		$show_thumbnail = isset( $instance['show_thumbnail'] )
			? (bool) $instance['show_thumbnail']
			: true;

		$show_date = isset( $instance['show_date'] )
			? (bool) $instance['show_date']
			: true;

		$show_comments = isset( $instance['show_comments'] )
			? (bool) $instance['show_comments']
			: true;
		?>

		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
				<?php esc_html_e( 'Title:', 'rubik-news' ); ?>
			</label>

			<input
				class="widefat"
				id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>"
				type="text"
				value="<?php echo esc_attr( $title ); ?>"
			>
		</p>

		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>">
				<?php esc_html_e( 'Category:', 'rubik-news' ); ?>
			</label>

			<?php
			wp_dropdown_categories(
				array(
					'show_option_all' => __( 'All Categories', 'rubik-news' ),
					'hide_empty'      => false,
					'id'              => $this->get_field_id( 'category' ),
					'name'            => $this->get_field_name( 'category' ),
					'class'           => 'widefat',
					'selected'        => $category,
				)
			);
			?>
		</p>

		<p>
			<label
				for="<?php echo esc_attr( $this->get_field_id( 'posts_number' ) ); ?>"
			>
				<?php esc_html_e( 'Number of posts:', 'rubik-news' ); ?>
			</label>

			<input
				class="tiny-text"
				id="<?php echo esc_attr( $this->get_field_id( 'posts_number' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'posts_number' ) ); ?>"
				type="number"
				min="1"
				max="10"
				step="1"
				value="<?php echo esc_attr( $posts_number ); ?>"
			>
		</p>

		<p>
			<input
				class="checkbox"
				id="<?php echo esc_attr( $this->get_field_id( 'show_thumbnail' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'show_thumbnail' ) ); ?>"
				type="checkbox"
				<?php checked( $show_thumbnail ); ?>
			>

			<label
				for="<?php echo esc_attr( $this->get_field_id( 'show_thumbnail' ) ); ?>"
			>
				<?php esc_html_e( 'Show thumbnail', 'rubik-news' ); ?>
			</label>
		</p>

		<p>
			<input
				class="checkbox"
				id="<?php echo esc_attr( $this->get_field_id( 'show_date' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'show_date' ) ); ?>"
				type="checkbox"
				<?php checked( $show_date ); ?>
			>

			<label
				for="<?php echo esc_attr( $this->get_field_id( 'show_date' ) ); ?>"
			>
				<?php esc_html_e( 'Show date', 'rubik-news' ); ?>
			</label>
		</p>

		<p>
			<input
				class="checkbox"
				id="<?php echo esc_attr( $this->get_field_id( 'show_comments' ) ); ?>"
				name="<?php echo esc_attr( $this->get_field_name( 'show_comments' ) ); ?>"
				type="checkbox"
				<?php checked( $show_comments ); ?>
			>

			<label
				for="<?php echo esc_attr( $this->get_field_id( 'show_comments' ) ); ?>"
			>
				<?php esc_html_e( 'Show comments count', 'rubik-news' ); ?>
			</label>
		</p>

		<?php
	}

	/**
	 * Sanitizes and saves widget settings.
	 *
	 * @param array $new_instance New widget settings.
	 * @param array $old_instance Previous widget settings.
	 *
	 * @return array
	 */
	public function update( $new_instance, $old_instance ) {
		$instance = array();

		$instance['title'] = isset( $new_instance['title'] )
			? sanitize_text_field( $new_instance['title'] )
			: '';

		$instance['category'] = isset( $new_instance['category'] )
			? absint( $new_instance['category'] )
			: 0;

		$instance['posts_number'] = isset( $new_instance['posts_number'] )
			? min( 10, max( 1, absint( $new_instance['posts_number'] ) ) )
			: 5;

		$instance['show_thumbnail'] = ! empty(
			$new_instance['show_thumbnail']
		);

		$instance['show_date'] = ! empty(
			$new_instance['show_date']
		);

		$instance['show_comments'] = ! empty(
			$new_instance['show_comments']
		);

		return $instance;
	}
}