<?php
/**
 * Menu Base Class
 *
 * @package errigal
 * @since 1.1.0
 */

namespace Errigal\Navigation;

defined( 'ABSPATH' ) || exit;

use Errigal\Constant\Errigal_Navigation_Class as Navigation_Class;
use Errigal\Shared\{
	Errigal_Utility as Utility,
	Errigal_Validator as Validator,
};

/**
 * This class is in charge of providing shared menu functions.
 *
 * @since 1.1.0
 */
abstract class Errigal_Menu_Base {
	/**
	 * Constructor.
	 *
	 * @since 1.1.0
	 */
	public function __construct() {
		$location    = static::get_location();
		$description = static::get_description();

		if (
			! Validator::is_non_empty_string( $location ) ||
			! Validator::is_non_empty_string( $description )
		) {
			return;
		}

		if ( has_nav_menu( $location ) ) {
			return;
		}

		register_nav_menu(
			sanitize_key( $location ),
			esc_html( $description )
		);
	}

	/**
	 * Gets location.
	 *
	 * @since 1.1.0
	 *
	 * @return string
	 */
	abstract public static function get_location();

	/**
	 * Gets description.
	 *
	 * @since 1.1.0
	 *
	 * @return string
	 */
	abstract protected static function get_description();

	/**
	 * Determines whether menu can be displayed.
	 *
	 * @since 1.1.0
	 *
	 * @return bool
	 */
	public static function can_show() {
		$location = static::get_location();

		return Validator::is_non_empty_string( $location ) &&
			has_nav_menu( $location ) &&
			self::has_menu_items( $location );
	}

	/**
	 * Renders menu.
	 *
	 * @since 1.1.0
	 *
	 * @return void
	 */
	public static function render_menu() {
		if ( ! static::can_show() ) {
			return;
		}

		wp_nav_menu(
			array(
				'menu_class'     => Utility::get_class( ...static::get_menu_classes() ),
				'container'      => false,
				'theme_location' => sanitize_key( static::get_location() ),
			)
		);
	}

	/**
	 * Gets menu classes.
	 *
	 * @since 1.1.0
	 *
	 * @return string[]
	 */
	protected static function get_menu_classes() {
		return array(
			Navigation_Class::MENU,
		);
	}

	/**
	 * Determines whether menu has items.
	 *
	 * @since 1.1.0
	 *
	 * @param string $location Menu location identifier.
	 * @return bool
	 */
	private static function has_menu_items( $location ) {
		if ( ! Validator::is_non_empty_string( $location ) ) {
			return false;
		}

		$locations = get_nav_menu_locations();

		if ( ! Validator::has_array_key( $locations, $location ) ) {
			return false;
		}

		$menu_items = wp_get_nav_menu_items( $locations[ $location ] );

		return Validator::is_non_empty_array( $menu_items );
	}
}
