<?php
/**
 * File Path: includes/admin/class-mbs-admin-tab-ui.php
 *
 * Book Editor Tab UI
 *
 * Static renderer for the domain tab bar and section sub-nav. Shared
 * infrastructure for the Book Editor shell and future admin page overhauls.
 * Both render_tab_bar() and render_section_nav() are fully self-contained:
 * each opens and closes its own container element.
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Admin
 * @since      1.2.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class MBS_Admin_Tab_UI { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	/**
	 * Render the domain tab bar.
	 *
	 * Self-contained: outputs <div class="nav-tab-wrapper mbs-editor-tab-bar" role="tablist">,
	 * all tab <a> elements, and the closing </div>.
	 *
	 * Each tab link carries:
	 *   href="#{domain_key}/{first_section_key}"
	 *   id="mbs-tab-{domain_key}"
	 *   role="tab"
	 *   aria-selected="true|false"
	 *   aria-controls="{space-separated panel IDs for all domain sections}"
	 *   data-mbs-domain="{domain_key}"
	 *
	 * The first domain in $domains receives nav-tab-active and aria-selected="true".
	 * JS activate() toggles nav-tab-active and aria-selected on navigation.
	 *
	 * @param array  $domains       Ordered domain config arrays. Each must have:
	 *                              'key' (string), 'label' (string), 'sections' (array).
	 * @param string $active_domain Domain key to receive nav-tab-active on initial render.
	 * @return void
	 * @since 1.2.0
	 */
	public static function render_tab_bar( array $domains, string $active_domain, array $icon_html_map = array() ): void {
		echo '<div class="nav-tab-wrapper mbs-editor-tab-bar" role="tablist">';
		foreach ( $domains as $domain ) {
			$dk       = $domain['key'];
			$first_sk = ! empty( $domain['sections'] ) ? $domain['sections'][0]['key'] : '';
			$active   = ( $dk === $active_domain );
			$classes  = $active ? 'nav-tab nav-tab-active' : 'nav-tab';
			$aria_sel = $active ? 'true' : 'false';

			$panel_ids = array();
			foreach ( $domain['sections'] as $s ) {
				$panel_ids[] = 'mbs-panel-' . $dk . '-' . $s['key'];
			}

			$domain_icon_html = isset( $icon_html_map[ $dk ] ) ? $icon_html_map[ $dk ] : '';
			printf(
				'<a href="#%1$s/%2$s" id="mbs-tab-%1$s" class="%3$s" role="tab" aria-selected="%4$s" aria-controls="%5$s" data-mbs-domain="%1$s">%6$s%7$s</a>',
				esc_attr( $dk ),
				esc_attr( $first_sk ),
				esc_attr( $classes ),
				esc_attr( $aria_sel ),
				esc_attr( implode( ' ', $panel_ids ) ),
				$domain_icon_html, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Pre-sanitized by MBS_Icon::render()
				esc_html( $domain['label'] )
			);
		}
		echo '</div>';
	}

	/**
	 * Render the section sub-nav for one domain.
	 *
	 * Self-contained: outputs <ul class="subsubsub mbs-editor-subnav" data-mbs-domain="{key}">,
	 * all <li> elements, and the closing </ul>.
	 *
	 * data-mbs-section is placed on the <li> element so JS activate() can query
	 * li[data-mbs-section="{sectionKey}"] within the active domain's sub-nav.
	 * The <a> inside each <li> carries href="#{domain_key}/{section_key}".
	 * The active <li> receives class="current"; JS activate() toggles this on navigation.
	 *
	 * Called once per domain; $active_section is the first section key of that domain.
	 * JS activate() controls visibility of inactive domain sub-navs via display:none.
	 *
	 * @param array  $sections       Ordered section config arrays. Each must have:
	 *                               'key' (string), 'label' (string).
	 * @param string $active_section Section key whose <li> receives class="current".
	 * @param string $domain_key     Placed on the <ul> as data-mbs-domain.
	 * @return void
	 * @since 1.2.0
	 */
	public static function render_section_nav( array $sections, string $active_section, string $domain_key, array $icon_html_map = array() ): void {
		$dk     = esc_attr( $domain_key );
		$count  = count( $sections );
		$i      = 0;
		// Phase 1-B (UX-EDIT-002): hide pill nav for single-section domains via CSS.
		$single = ( 1 === $count ) ? ' data-mbs-single="true"' : '';
		echo '<ul class="subsubsub mbs-editor-subnav" data-mbs-domain="' . $dk . '"' . $single . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variables are hardcoded HTML or pre-escaped with esc_attr()
		foreach ( $sections as $section ) {
			$i++;
			$sk        = $section['key'];
			$active    = ( $sk === $active_section );
			$li_class  = $active ? ' class="current"' : '';
			$separator = ( $i < $count ) ? ' <span class="sep">|</span>' : '';
			$section_icon_html = isset( $icon_html_map[ $sk ] ) ? $icon_html_map[ $sk ] : '';
			printf(
				'<li%1$s data-mbs-section="%2$s"><a href="#%3$s/%2$s">%4$s%5$s</a>%6$s</li>',
				$li_class, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variables are hardcoded HTML or pre-escaped with esc_attr()
				esc_attr( $sk ),
				$dk, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variables are hardcoded HTML or pre-escaped with esc_attr()
				$section_icon_html, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Pre-sanitized by MBS_Icon::render()
				esc_html( $section['label'] ),
				$separator // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variables are hardcoded HTML or pre-escaped with esc_attr()
			);
		}
		echo '</ul>';
	}

	/**
	 * Open a content panel <div> for one domain/section combination.
	 *
	 * Panel id uses hyphens only (forward slashes are invalid in HTML ids).
	 * data-mbs-panel retains the slash format for JS router targeting via
	 * $('.mbs-editor-panel[data-mbs-panel="domain/section"]').
	 *
	 * PHP always outputs aria-hidden="false" on every panel (accessible by default).
	 * JS activate() sets aria-hidden="true" on inactive panels and "false" on the active one.
	 *
	 * Must be paired with a matching call to render_content_close().
	 *
	 * @param string $domain_key  Domain key.
	 * @param string $section_key Section key.
	 * @return void
	 * @since 1.2.0
	 */
	public static function render_content_open( string $domain_key, string $section_key ): void {
		$dk = esc_attr( $domain_key );
		$sk = esc_attr( $section_key );
		printf(
			'<div id="mbs-panel-%1$s-%2$s" class="mbs-editor-panel" data-mbs-panel="%1$s/%2$s" role="tabpanel" aria-labelledby="mbs-tab-%1$s" aria-hidden="false" tabindex="0">',
			$dk, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variables are hardcoded HTML or pre-escaped with esc_attr()
			$sk // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- variables are hardcoded HTML or pre-escaped with esc_attr()
		);
	}

	/**
	 * Close a content panel opened by render_content_open().
	 *
	 * @return void
	 * @since 1.2.0
	 */
	public static function render_content_close(): void {
		echo '</div>';
	}
}
