<?php
/**
 * JM_Web_Development\Giornalismo\Sidebars\Component class
 *
 * @package giornalismo
 */

namespace JM_Web_Development\Giornalismo\Sidebars;

use JM_Web_Development\Giornalismo\Component_Interface;
use JM_Web_Development\Giornalismo\Templating_Component_Interface;
use function add_action;
use function add_filter;
use function register_sidebar;
use function esc_html__;
use function is_active_sidebar;
use function dynamic_sidebar;

/**
 * Class for managing sidebars.
 *
 * Exposes template tags:
 * * `giornalismo()->is_primary_sidebar_active()`
 * * `giornalismo()->display_primary_sidebar()`
 *
 * @link https://developer.wordpress.org/themes/functionality/sidebars/
 */
class Component implements Component_Interface, Templating_Component_Interface {

	const LEFT_SIDEBAR_SLUG   = 'left_sidebar';
	const RIGHT_SIDEBAR_SLUG  = 'right_sidebar';
	const HEADER_SIDEBAR_SLUG = 'header_widget_area';

	/**
	 * Gets the unique identifier for the theme component.
	 *
	 * @return string Component slug.
	 */
	public function get_slug() : string {
		return 'sidebars';
	}

	/**
	 * Adds the action and filter hooks to integrate with WordPress.
	 */
	public function initialize() {
		add_action( 'widgets_init', array( $this, 'action_register_sidebars' ) );
		add_filter( 'body_class', array( $this, 'filter_body_classes' ) );
	}

	/**
	 * Gets template tags to expose as methods on the Template_Tags class instance, accessible through `giornalismo()`.
	 *
	 * @return array Associative array of $method_name => $callback_info pairs. Each $callback_info must either be
	 *               a callable or an array with key 'callable'. This approach is used to reserve the possibility of
	 *               adding support for further arguments in the future.
	 */
	public function template_tags() : array {
		return array(
			'is_right_sidebar_active'  => array( $this, 'is_right_sidebar_active' ),
			'display_right_sidebar'    => array( $this, 'display_right_sidebar' ),
			'is_left_sidebar_active'   => array( $this, 'is_left_sidebar_active' ),
			'display_left_sidebar'     => array( $this, 'display_left_sidebar' ),
			'is_header_sidebar_active' => array( $this, 'is_header_sidebar_active' ),
			'display_header_sidebar'   => array( $this, 'display_header_sidebar' ),
		);
	}

	/**
	 * Registers the sidebars.
	 */
	public function action_register_sidebars() {
		register_sidebar(
			array(
				'name'          => esc_html__( 'Left Sidebar', 'giornalismo' ),
				'id'            => static::LEFT_SIDEBAR_SLUG,
				'description'   => esc_html__( 'Add widgets here.', 'giornalismo' ),
				'before_widget' => '<section id="%1$s" class="widget %2$s">',
				'after_widget'  => '</section>',
				'before_title'  => '<h3 class="widget-title">',
				'after_title'   => '</h3>',
			)
		);

		register_sidebar(
			array(
				'name'          => esc_html__( 'Right Sidebar', 'giornalismo' ),
				'id'            => static::RIGHT_SIDEBAR_SLUG,
				'description'   => esc_html__( 'Add widgets here.', 'giornalismo' ),
				'before_widget' => '<section id="%1$s" class="widget %2$s">',
				'after_widget'  => '</section>',
				'before_title'  => '<h3 class="widget-title">',
				'after_title'   => '</h3>',
			)
		);

		register_sidebar(
			array(
				'name'          => esc_html__( 'Header Widget Area', 'giornalismo' ),
				'id'            => static::HEADER_SIDEBAR_SLUG,
				'description'   => esc_html__( 'Use this area to display an ad in the header area.', 'giornalismo' ),
				'before_widget' => '<section id="%1$s" class="widget %2$s">',
				'after_widget'  => '</section>',
				'before_title'  => '<h3 class="widget-title">',
				'after_title'   => '</h3>',
			)
		);
	}

	/**
	 * Adds custom classes to indicate whether a sidebar is present to the array of body classes.
	 *
	 * @param array $classes Classes for the body element.
	 * @return array Filtered body classes.
	 */
	public function filter_body_classes( array $classes ) : array {
		if ( 'right-sidebar' === get_theme_mod( 'giornalismo-layout' ) ) {
			global $template;

			$classes[] = 'has-right-sidebar';
		} elseif ( 'left-sidebar' === get_theme_mod( 'giornalismo-layout' ) ) {
			global $template;

			$classes[] = 'has-left-sidebar';
		} elseif ( 'two-sidebars' === get_theme_mod( 'giornalismo-layout' ) ) {
			global $template;

			$classes[] = 'has-two-sidebars';
		}

		return $classes;
	}

	/**
	 * Checks whether the primary sidebar is active.
	 *
	 * @return bool True if the primary sidebar is active, false otherwise.
	 */
	public function is_left_sidebar_active() : bool {
		return (bool) is_active_sidebar( static::LEFT_SIDEBAR_SLUG );
	}

	/**
	 * Displays the primary sidebar.
	 */
	public function display_left_sidebar() {
		dynamic_sidebar( static::LEFT_SIDEBAR_SLUG );
	}

	/**
	 * Checks whether the primary sidebar is active.
	 *
	 * @return bool True if the primary sidebar is active, false otherwise.
	 */
	public function is_right_sidebar_active() : bool {
		return (bool) is_active_sidebar( static::RIGHT_SIDEBAR_SLUG );
	}

	/**
	 * Displays the primary sidebar.
	 */
	public function display_right_sidebar() {
		dynamic_sidebar( static::RIGHT_SIDEBAR_SLUG );
	}

	/**
	 * Checks whether the primary sidebar is active.
	 *
	 * @return bool True if the primary sidebar is active, false otherwise.
	 */
	public function is_header_sidebar_active() : bool {
		return (bool) is_active_sidebar( static::HEADER_SIDEBAR_SLUG );
	}

	/**
	 * Displays the primary sidebar.
	 */
	public function display_header_sidebar() {
		dynamic_sidebar( static::HEADER_SIDEBAR_SLUG );
	}
}
