<?php
/**
 * Normalized menu tree value object.
 *
 * @package MenuVerse
 */

namespace WPXero\MenuVerse\Menus;

defined( 'ABSPATH' ) || exit;

/**
 * Carries the single menu shape shared by every source adapter, module and
 * REST response.
 */
final class Menu_Tree {

	/**
	 * Source identifier the tree came from.
	 *
	 * @var string
	 */
	private $source;

	/**
	 * Menu identifier within the source.
	 *
	 * @var int|string
	 */
	private $menu_id;

	/**
	 * Menu name.
	 *
	 * @var string
	 */
	private $name;

	/**
	 * Nested items.
	 *
	 * @var array[]
	 */
	private $items;

	/**
	 * Constructor.
	 *
	 * @param string     $source  Source identifier.
	 * @param int|string $menu_id Menu identifier.
	 * @param string     $name    Menu name.
	 * @param array[]    $items   Nested items.
	 */
	public function __construct( $source, $menu_id, $name, array $items ) {
		$this->source  = (string) $source;
		$this->menu_id = $menu_id;
		$this->name    = (string) $name;
		$this->items   = $items;
	}

	/**
	 * Returns the default shape of a single item.
	 *
	 * @return array
	 */
	public static function item_defaults() {
		return array(
			'id'         => 0,
			'title'      => '',
			'url'        => '',
			'target'     => '',
			'rel'        => '',
			'classes'    => array(),
			'current'    => false,
			'attributes' => array(),
			'extras'     => array(),
			'children'   => array(),
		);
	}

	/**
	 * Returns the source identifier.
	 *
	 * @return string
	 */
	public function source() {
		return $this->source;
	}

	/**
	 * Returns the menu identifier.
	 *
	 * @return int|string
	 */
	public function menu_id() {
		return $this->menu_id;
	}

	/**
	 * Returns the menu name.
	 *
	 * @return string
	 */
	public function name() {
		return $this->name;
	}

	/**
	 * Returns the nested items.
	 *
	 * @return array[]
	 */
	public function items() {
		return $this->items;
	}

	/**
	 * Returns the tree as a plain array suitable for REST responses.
	 *
	 * @return array
	 */
	public function to_array() {
		return array(
			'source' => $this->source,
			'id'     => $this->menu_id,
			'name'   => $this->name,
			'items'  => $this->items,
		);
	}
}
