<?php
/**
 * Generate an ellipsis menu.
 *
 * Only supports links for now, no buttons.
 *
 * Example usage:
 *
 * $menu = new EllipsisMenu();
 * $menu->add_item( __( 'Item 1', 'p2020' ), 'https://wordpress.com' );
 * $menu->add_item( __( 'Item 2', 'p2020' ), 'https://wordpress.com' );
 * echo html_output( $menu->generate() );
 *
 * @package p2020
 */

namespace Automattic\P2\Themes\P2020;

class EllipsisMenu {
	public const SEPARATOR = 'separator';

	private $items = [];
	public $label;
	public $classes;

	public function add_item( string $label, string $url, string $icon = null, array $attributes = [] ) {
		$this->items[] = [
			'label'      => $label,
			'url'        => $url,
			'attributes' => $attributes,
			'icon'       => $icon,
		];
	}

	public function add_item_html( string $html ) {
		$this->items[] = [
			'html' => $html,
		];
	}

	public function add_separator() {
		$this->items[] = self::SEPARATOR;
	}

	public function add_item_skeleton( $id ) {
		$skeleton_item = <<<HTML
<div id="{$id}">
	<div class="p2020-ellipsis-menu__item-skeleton">
		<div class="p2-skeleton-icon"></div>
		<div class="p2-skeleton-text"></div>
	</div>
</div>
HTML;
		$this->add_item_html( $skeleton_item );
	}

	public function generate_item_html( $item ): string {
		if ( self::SEPARATOR === $item ) {
			return '<li class="p2020-ellipsis-menu-separator" role="separator"/>';
		}

		if ( isset( $item['html'] ) ) {
			$link = $item['html'];

			return <<<ITEM
				<li role="menuitem">
					$link
				</li>
ITEM;
		}

		$label = esc_html( $item['label'] );
		$url   = esc_url( $item['url'] );

		$attributes_html = '';
		if ( $item['attributes'] ) {
			foreach ( $item['attributes'] as $key => $value ) {
				$attributes_html .= ' ' . esc_html( $key ) . '="' . esc_attr( $value ) . '"';
			}
		}

		if ( ! $url ) {
			return <<<ITEM
					<li role="menuitem">
						<span $attributes_html>
							$label
						</span>
					</li>
ITEM;

		}

		return <<<ITEM
				<li role="menuitem">
					<a href="$url" $attributes_html>
						$label
					</a>
				</li>
ITEM;
	}

	private function make_list(): string {
		return implode( array_map( array( $this, 'generate_item_html' ), $this->items ) );
	}

	public function header( $trigger_id ) {
		$menu_label = esc_attr__( 'More', 'p2020' );
		if ( $this->label ) {
			$menu_label = $this->label;
		}

		$classes = $this->classes;

		return <<<HEADER
			<nav class="$classes">
				<button
					id="$trigger_id"
					aria-haspopup="true"
					aria-expanded="false"
					aria-label="$menu_label"
					class="p2020-ellipsis-button"
					data-tippy-menu-trigger
				>
				</button>
				<div data-tippy-menu-content hidden>
					<ul class="p2020-ellipsis-menu" role="menu">
HEADER;
	}

	public function footer() {
		return <<<FOOTER
				</ul>
			</div>
		</nav>
FOOTER;
	}


	/**
	 * Returns the HTML for the menu.
	 *
	 * @param string $id trigger button id
	 *
	 * @return string
	 */
	public function generate( $trigger_id = 'p2020-ellipsis-button' ): string {
		$header = $this->header( $trigger_id );
		$list   = $this->make_list();
		$footer = $this->footer();

		// Outer div is required for proper tab order
		return $header . $list . $footer;
	}
}