<?php
/**
 * File Path: includes/metaboxes/class-mbs-metabox-book-header.php
 *
 * Book Header Parent Metabox (Orchestrator)
 *
 * This is the main entry point for the Book Header metabox.
 * It registers the metabox and delegates rendering/saving to child section classes.
 * This modular structure improves maintainability and reduces regression risk.
 *
 * Child sections are located in: includes/metaboxes/book-header/
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Metaboxes
 * @since      1.0.0
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class MBS_Metabox_Book_Header
 */
class MBS_Metabox_Book_Header extends MBS_Metabox_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

    /**
     * Constructor. Registers WordPress hooks.
     */
    public function __construct() {
        add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
        add_action( 'save_post_' . MBS_POST_TYPE, array( $this, 'save' ), 10, 2 );
    }

    /**
     * Registers the Book Header metabox with WordPress.
     *
     * @return void
     */
    public function add_meta_box(): void {
        add_meta_box(
            'mbs_book_header',
            __( 'Book Header', 'my-book-showroom' ),
            array( $this, 'render' ),
            MBS_POST_TYPE,
            'normal',
            'high'
        );
    }


    /**
     * Render the meta box (orchestrator).
     *
     * @param WP_Post $post The post object.
     */
    public function render( $post ) {
        wp_nonce_field( 'mbs_book_header_nonce', 'mbs_book_header_nonce' );

        ?>
        <div class="mbs-metabox-book-header">
            <table class="form-table"><tbody>
            <?php
            // Delegate rendering to child sections.
            // C2-004: child sections output <tr> rows — they must be wrapped in a
            // <table class="form-table"> so browsers do not orphan and discard the rows.
            do_action( 'mbs_book_header_render_core', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_authors', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_publication', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_cover', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_links', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_extended_meta', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_status', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_notes', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            do_action( 'mbs_book_header_render_woocommerce', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
            ?>
            </tbody></table>
        </div>
        <?php
        // F-026-7: Broadcast panel -- PRO + broadcast enabled + pending record.
        if ( class_exists( 'MBS_ESP_Broadcast' ) ) {
            MBS_ESP_Broadcast::maybe_render_panel( (int) $post->ID );
        }
    }

    /**
     * Save dispatcher - calls each child section's save method.
     *
     * @param int     $post_id The post ID.
     * @param WP_Post $post    The post object.
     */
    public function save( $post_id, $post ) {
        if ( ! $this->verify_save( $post_id, 'mbs_book_header_nonce', 'mbs_book_header_nonce' ) ) {
            return;
        }

        // Delegate saving to child sections
        do_action( 'mbs_book_header_save_core', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_authors', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_publication', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_cover', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_links', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_extended_meta', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_status', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_notes', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
        do_action( 'mbs_book_header_save_woocommerce', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
    }

	/**
	 * Render one editor section within the unified book editor shell.
	 *
	 * Routes to the applicable subset of sub-class action hooks. Never calls
	 * $this->render() — that method fires all hooks unconditionally.
	 *
	 * @since  1.0.0 (Sprint 169)
	 * @param  string  $section_key  Section key: 'main', 'media', 'awards', 'admin', 'pub-fields', 'woocommerce'.
	 * @param  WP_Post $post         Current post object.
	 * @return void
	 */
	public function render_section( string $section_key, WP_Post $post ): void {
		?>
		<div class="mbs-metabox-book-header">
			<table class="form-table"><tbody>
			<?php
			if ( 'main' === $section_key ) {
				wp_nonce_field( 'mbs_book_header_main', 'mbs_book_header_main_nonce' );
				do_action( 'mbs_book_header_render_core',    $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
				do_action( 'mbs_book_header_render_authors', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			} elseif ( 'media' === $section_key ) {
				wp_nonce_field( 'mbs_book_header_media', 'mbs_book_header_media_nonce' );
				do_action( 'mbs_book_header_render_cover', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
				do_action( 'mbs_book_header_render_links', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			} elseif ( 'awards' === $section_key ) {
				wp_nonce_field( 'mbs_book_header_awards', 'mbs_book_header_awards_nonce' );
				do_action( 'mbs_book_header_render_extended_meta', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			} elseif ( 'admin' === $section_key ) {
				wp_nonce_field( 'mbs_book_header_admin', 'mbs_book_header_admin_nonce' );
				do_action( 'mbs_book_header_render_notes', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			} elseif ( 'pub-fields' === $section_key ) {
				wp_nonce_field( 'mbs_book_header_pub_fields', 'mbs_book_header_pub_fields_nonce' );
				do_action( 'mbs_book_header_render_publication', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			} elseif ( 'woocommerce' === $section_key ) {
				wp_nonce_field( 'mbs_book_header_woocommerce', 'mbs_book_header_woocommerce_nonce' );
				do_action( 'mbs_book_header_render_woocommerce', $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			}
			?>
			</tbody></table>
		</div>
		<?php
		if ( 'main' === $section_key && class_exists( 'MBS_ESP_Broadcast' ) ) {
			MBS_ESP_Broadcast::maybe_render_panel( (int) $post->ID );
		}
	}

	/**
	 * Save one editor section within the unified book editor shell.
	 *
	 * Each section uses its own scoped nonce (Sprint 169). Never re-uses
	 * the old single shared nonce — section keys route to distinct save hooks.
	 *
	 * @since  1.0.0 (Sprint 169)
	 * @param  string  $section_key  Section key: 'main', 'pub-fields', 'woocommerce'.
	 * @param  int     $post_id      Post ID.
	 * @param  WP_Post $post         Post object.
	 * @return void
	 */
	public function save_section( string $section_key, int $post_id, WP_Post $post ): void {
		if ( 'main' === $section_key ) {
			$nonce = isset( $_POST['mbs_book_header_main_nonce'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_book_header_main_nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'mbs_book_header_main' ) ) { return; }
			do_action( 'mbs_book_header_save_core',    $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			do_action( 'mbs_book_header_save_authors', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
		} elseif ( 'media' === $section_key ) {
			$nonce = isset( $_POST['mbs_book_header_media_nonce'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_book_header_media_nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'mbs_book_header_media' ) ) { return; }
			do_action( 'mbs_book_header_save_cover', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
			do_action( 'mbs_book_header_save_links', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
		} elseif ( 'awards' === $section_key ) {
			$nonce = isset( $_POST['mbs_book_header_awards_nonce'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_book_header_awards_nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'mbs_book_header_awards' ) ) { return; }
			do_action( 'mbs_book_header_save_extended_meta', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
		} elseif ( 'admin' === $section_key ) {
			$nonce = isset( $_POST['mbs_book_header_admin_nonce'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_book_header_admin_nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'mbs_book_header_admin' ) ) { return; }
			do_action( 'mbs_book_header_save_notes', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
		} elseif ( 'pub-fields' === $section_key ) {
			$nonce = isset( $_POST['mbs_book_header_pub_fields_nonce'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_book_header_pub_fields_nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'mbs_book_header_pub_fields' ) ) { return; }
			do_action( 'mbs_book_header_save_publication', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
		} elseif ( 'woocommerce' === $section_key ) {
			$nonce = isset( $_POST['mbs_book_header_woocommerce_nonce'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_book_header_woocommerce_nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'mbs_book_header_woocommerce' ) ) { return; }
			do_action( 'mbs_book_header_save_woocommerce', $post_id, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
		}
	}

}
