<?php
/**
 * File Path: includes/metaboxes/class-mbs-metabox-onix.php
 *
 * ONIX Distribution Data Metabox
 *
 * PUB-gated metabox on the mbs_book edit screen that provides UI for:
 *   - Sales Territory / Territorial Rights v2 (structured country grid)
 *   - Product Contact (ONIX List 198)
 *
 * All UI and save logic are disabled for non-PUB licenses; the metabox
 * renders as an HTML comment when mbs_is_pub() is false.
 *
 * @package MyBookShowroom
 * @since   1.2.0
 */

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

// phpcs:disable WordPress.Security.NonceVerification -- nonce verified in parent class verify_save() / check_admin_referer() before $_POST access; PHPCS cannot trace cross-method nonce verification
// phpcs:disable WordPress.Security.ValidatedSanitizedInput -- input sanitized at point of use (sanitize_text_field, absint, wp_kses_post, etc.); false positives from PHPCS not tracing sanitization helpers called before this method
class MBS_Metabox_Onix extends MBS_Metabox_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix


	/**
	 * Valid ONIX List 198 product contact role values.
	 *
	 * @var string[]
	 */
	const LIST_198 = array( '01', '02', '03', '04', '05', '06' );

	// -------------------------------------------------------------------------
	// Bootstrap
	// -------------------------------------------------------------------------

	/**
	 * Constructor — registers hooks.
	 */
	public function __construct() {
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
	}


	/**
	 * Enqueue the ONIX metabox JS on the mbs_book edit screen (PUB only).
	 *
	 * @param string $hook Current admin page hook.
	 * @return void
	 */
	public function enqueue_assets( string $hook ): void {
		if ( ! in_array( $hook, array( 'post.php', 'post-new.php' ), true ) ) {
			return;
		}
		$screen = get_current_screen();
		if ( ! $screen || MBS_POST_TYPE !== $screen->post_type ) {
			return;
		}
		if ( ! mbs_is_pub() ) {
			return;
		}

		wp_enqueue_style(
			'mbs-onix-metabox',
			MBS_ASSETS_URL . 'css/mbs-admin-onix.css',
			array(),
			MBS_VERSION
		);

		wp_enqueue_script(
			'mbs-onix-metabox',
			MBS_ASSETS_URL . 'js/adminjs/mbs-onix-metabox.js',
			array( 'jquery', 'wp-i18n' ),
			MBS_VERSION,
			true
		);
		wp_set_script_translations( 'mbs-onix-metabox', 'my-book-showroom', MBS_DIR . 'languages' );
	}

	// -------------------------------------------------------------------------
	// Render
	// -------------------------------------------------------------------------

	/**
	 * Render the ONIX Distribution Data metabox.
	 *
	 * Non-PUB licenses receive an HTML comment only — no visible elements.
	 *
	 * @param WP_Post $post Current post.
	 * @return void
	 */
	public function render( WP_Post $post ): void {
		if ( ! mbs_is_pub() ) {
			echo '<!-- MBS: ONIX Distribution Data requires PRO license -->';
			return;
		}
		MBS_Metabox_Onix_Render::render( $post );
	}

	// -------------------------------------------------------------------------
	// Save
	// -------------------------------------------------------------------------

	/**
	 * Save all ONIX distribution data fields.
	 *
	 * @param int     $post_id Post ID.
	 * @param WP_Post $post    Post object.
	 * @return void
	 */
	public function save( int $post_id, WP_Post $post ): void {
		if ( ! $this->verify_save( $post_id, 'mbs_onix_nonce', 'mbs_onix_save' ) ) {
			return;
		}
		if ( ! mbs_is_pub() ) {
			return;
		}

		// Audience Code (ONIX List 28) is owned by MBS_Metabox_Classification (CLASS-6).

		// ---- Territorial Rights v2 (structured JSON) ---------------------------
		$rights_type = isset( $_POST['mbs_territory_type'] )
			? sanitize_text_field( wp_unslash( $_POST['mbs_territory_type'] ) )
			: 'world';
		if ( ! in_array( $rights_type, array( 'world', 'include', 'exclude' ), true ) ) {
			$rights_type = 'world';
		}

		$countries = array();
		if ( in_array( $rights_type, array( 'include', 'exclude' ), true )
			&& isset( $_POST['mbs_territory_countries'] )
			&& is_array( $_POST['mbs_territory_countries'] )
		) {
			$allowed = MBS_Metabox_Onix_Render::COUNTRY_CODES;
			foreach ( wp_unslash( $_POST['mbs_territory_countries'] ) as $code ) {
				$code = strtoupper( sanitize_text_field( $code ) );
				if ( in_array( $code, $allowed, true ) ) {
					$countries[] = $code;
				}
			}
			$countries = array_values( array_unique( $countries ) );
		}

		// Write to mbs_book_territorial_rights via DAO -- replaces mbs_territorial_rights_v2 postmeta.
		MBS_Book_Territorial_Rights_DAO::save( $post_id, $rights_type, $countries );

		// ---- Product Contact (ONIX List 198) -----------------------------------
		$contact_role = isset( $_POST['mbs_product_contact_role'] )
			? sanitize_text_field( wp_unslash( $_POST['mbs_product_contact_role'] ) )
			: '';
		if ( ! in_array( $contact_role, self::LIST_198, true ) ) {
			$contact_role = '';
		}
		update_post_meta( $post_id, 'mbs_product_contact_role', $contact_role );

		update_post_meta(
			$post_id,
			'mbs_product_contact_name',
			isset( $_POST['mbs_product_contact_name'] )
				? sanitize_text_field( wp_unslash( $_POST['mbs_product_contact_name'] ) )
				: ''
		);

		update_post_meta(
			$post_id,
			'mbs_product_contact_email',
			isset( $_POST['mbs_product_contact_email'] )
				? sanitize_email( wp_unslash( $_POST['mbs_product_contact_email'] ) )
				: ''
		);
	}

	/**
	 * Render one editor section within the unified book editor shell.
	 *
	 * Passthrough — single-section handler (Sprint 169).
	 *
	 * @since  1.0.0
	 * @param  string  $section_key  Section key (ignored for single-section handlers).
	 * @param  WP_Post $post         Current post object.
	 * @return void
	 */
	public function render_section( string $section_key, WP_Post $post ): void {
		$this->render( $post );
	}

	/**
	 * Save one editor section within the unified book editor shell.
	 *
	 * Passthrough — single-section handler (Sprint 169).
	 *
	 * @since  1.0.0
	 * @param  string  $section_key  Section key (ignored for single-section handlers).
	 * @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 {
		$this->save( $post_id, $post );
	}

}
