<?php
/**
 * File Path: includes/taxonomies/class-mbs-taxonomy-contributor.php
 *
 * Contributor Taxonomy
 *
 * Flat (non-hierarchical) taxonomy for book contributors. Replaces the
 * mbs_contributors table (dropped in DB 2.4 migration). Each contributor
 * term stores is_corporate, bio, and ISNI as term_meta. Book assignments
 * (with ONIX role codes) live in the mbs_book_contributors pivot table,
 * managed by MBS_Metabox_Contributors (Phase 5).
 *
 * Phase 5 wires the custom add/edit term form fields and
 * MBS_Taxonomy_Contributor_Term_Fields hooks.
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Taxonomies
 * @since      1.1.0
 */

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

class MBS_Taxonomy_Contributor {

	public static function register(): void {
		$labels = array(
			'name'          => __( 'Contributors', 'my-book-showroom' ),
			'singular_name' => __( 'Contributor', 'my-book-showroom' ),
			'menu_name'     => __( 'Contributors', 'my-book-showroom' ),
			'search_items'  => __( 'Search Contributors', 'my-book-showroom' ),
			'all_items'     => __( 'All Contributors', 'my-book-showroom' ),
			'edit_item'     => __( 'Edit Contributor', 'my-book-showroom' ),
			'update_item'   => __( 'Update Contributor', 'my-book-showroom' ),
			'add_new_item'  => __( 'Add New Contributor', 'my-book-showroom' ),
			'new_item_name' => __( 'New Contributor Name', 'my-book-showroom' ),
			'not_found'     => __( 'No contributors found.', 'my-book-showroom' ),
		);

		register_taxonomy(
			MBS_TAX_CONTRIBUTOR,
			MBS_POST_TYPE,
			array(
				'labels'            => $labels,
				'hierarchical'      => false,
				'public'            => false,
				'show_ui'           => true,
				'show_in_rest'      => false,
				'show_admin_column' => false,
				'show_in_menu'      => false,
				'show_in_quick_edit' => false,
			)
		);

		self::register_term_meta_hooks();
	}

	public static function register_term_meta_hooks(): void {
		add_action( MBS_TAX_CONTRIBUTOR . '_add_form_fields',  array( __CLASS__, 'add_form_fields' ) );
		add_action( MBS_TAX_CONTRIBUTOR . '_edit_form_fields', array( __CLASS__, 'edit_form_fields' ), 10, 2 );
		add_action( 'created_' . MBS_TAX_CONTRIBUTOR,          array( __CLASS__, 'save_term_meta' ) );
		add_action( 'edited_'  . MBS_TAX_CONTRIBUTOR,          array( __CLASS__, 'save_term_meta' ) );
	}

	public static function add_form_fields(): void {
		?>
		<?php wp_nonce_field( 'mbs_save_contributor_new', 'mbs_contributor_nonce' ); ?>
		<div class="form-field">
			<label for="mbs_is_corporate">
				<input type="checkbox" id="mbs_is_corporate" name="mbs_is_corporate" value="1">
				<?php esc_html_e( 'Organization (not a person)', 'my-book-showroom' ); ?>
			</label>
		</div>
		<div class="form-field">
			<label for="mbs_author_bio"><?php esc_html_e( 'Bio', 'my-book-showroom' ); ?></label>
			<textarea id="mbs_author_bio" name="mbs_author_bio" rows="5" maxlength="4000"></textarea>
		</div>
		<div class="form-field">
			<label for="mbs_isni"><?php esc_html_e( 'ISNI', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_isni" name="mbs_isni" maxlength="16"
				placeholder="<?php esc_attr_e( '16-digit numeric', 'my-book-showroom' ); ?>">
		</div>
		<?php /* F-NAMES-1: structured name fields — persons only */ ?>
		<h3 style="margin-bottom:6px"><?php esc_html_e( 'Name structure (for sorting &amp; ONIX)', 'my-book-showroom' ); ?></h3>
		<p class="description" style="margin-bottom:12px"><?php esc_html_e( 'Optional. Leave blank if not a named person.', 'my-book-showroom' ); ?></p>
		<div class="form-field">
			<label for="mbs_name_titles_before"><?php esc_html_e( 'Title / Honorific', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_titles_before" name="mbs_name_titles_before"
				placeholder="<?php esc_attr_e( 'Dr., Sir, Prof.', 'my-book-showroom' ); ?>">
		</div>
		<div class="form-field">
			<label for="mbs_name_before_key"><?php esc_html_e( 'First / middle name(s)', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_before_key" name="mbs_name_before_key"
				placeholder="<?php esc_attr_e( 'Mary Jo, John A.', 'my-book-showroom' ); ?>">
		</div>
		<div class="form-field">
			<label for="mbs_name_prefix_to_key"><?php esc_html_e( 'Surname prefix', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_prefix_to_key" name="mbs_name_prefix_to_key"
				placeholder="<?php esc_attr_e( 'van der, de, von', 'my-book-showroom' ); ?>">
		</div>
		<div class="form-field">
			<label for="mbs_name_key"><?php esc_html_e( 'Surname / Last Name (key name)', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_key" name="mbs_name_key"
				placeholder="<?php esc_attr_e( 'Smith, van der Berg', 'my-book-showroom' ); ?>">
		</div>
		<div class="form-field">
			<label for="mbs_name_after_key"><?php esc_html_e( 'Suffix', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_after_key" name="mbs_name_after_key"
				placeholder="<?php esc_attr_e( 'Jr., III', 'my-book-showroom' ); ?>">
		</div>
		<div class="form-field">
			<label for="mbs_name_letters"><?php esc_html_e( 'Letters after name', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_letters" name="mbs_name_letters"
				placeholder="<?php esc_attr_e( 'PhD, OBE, CBE', 'my-book-showroom' ); ?>">
		</div>
		<div class="form-field">
			<label for="mbs_name_inverted"><?php esc_html_e( 'Inverted name (sort / ONIX PersonNameInverted)', 'my-book-showroom' ); ?></label>
			<input type="text" id="mbs_name_inverted" name="mbs_name_inverted"
				placeholder="<?php esc_attr_e( 'Auto-computed from fields above when left blank', 'my-book-showroom' ); ?>">
			<p class="description"><?php esc_html_e( 'Leave blank to auto-compute from surname + first name fields.', 'my-book-showroom' ); ?></p>
		</div>
		<?php
	}

	public static function edit_form_fields( WP_Term $term ): void {
		$is_corporate = (int) get_term_meta( $term->term_id, 'mbs_is_corporate', true );
		$bio          = (string) get_term_meta( $term->term_id, 'mbs_author_bio',   true );
		$isni         = (string) get_term_meta( $term->term_id, 'mbs_isni',         true );
		wp_nonce_field( 'mbs_save_contributor_' . $term->term_id, 'mbs_contributor_nonce' );
		?>
		<tr class="form-field">
			<th scope="row"><?php esc_html_e( 'Type', 'my-book-showroom' ); ?></th>
			<td>
				<label for="mbs_is_corporate">
					<input type="checkbox" id="mbs_is_corporate" name="mbs_is_corporate" value="1"
						<?php checked( $is_corporate, 1 ); ?>>
					<?php esc_html_e( 'Organization (not a person)', 'my-book-showroom' ); ?>
				</label>
			</td>
		</tr>
		<tr class="form-field">
			<th scope="row"><label for="mbs_author_bio"><?php esc_html_e( 'Bio', 'my-book-showroom' ); ?></label></th>
			<td><textarea id="mbs_author_bio" name="mbs_author_bio" rows="5" maxlength="4000"><?php echo esc_textarea( $bio ); ?></textarea></td>
		</tr>
		<tr class="form-field">
			<th scope="row"><label for="mbs_isni"><?php esc_html_e( 'ISNI', 'my-book-showroom' ); ?></label></th>
			<td>
				<input type="text" id="mbs_isni" name="mbs_isni" maxlength="16"
					value="<?php echo esc_attr( $isni ); ?>"
					placeholder="<?php esc_attr_e( '16-digit numeric', 'my-book-showroom' ); ?>">
				<p class="description"><?php esc_html_e( 'International Standard Name Identifier (16 digits).', 'my-book-showroom' ); ?></p>
			</td>
		</tr>
		<?php /* F-NAMES-1: structured name fields */ ?>
		<tr><th colspan="2"><h3 style="margin:8px 0 4px"><?php esc_html_e( 'Name structure (for sorting &amp; ONIX)', 'my-book-showroom' ); ?></h3>
		<p class="description"><?php esc_html_e( 'Optional. Leave blank if not a named person.', 'my-book-showroom' ); ?></p></th></tr>
		<?php
		$name_fields = array(
			'mbs_name_titles_before'  => array( 'label' => __( 'Title / Honorific', 'my-book-showroom' ),                           'placeholder' => 'Dr., Sir, Prof.' ),
			'mbs_name_before_key'     => array( 'label' => __( 'First / middle name(s)', 'my-book-showroom' ),                      'placeholder' => 'Mary Jo, John A.' ),
			'mbs_name_prefix_to_key'  => array( 'label' => __( 'Surname prefix', 'my-book-showroom' ),                              'placeholder' => 'van der, de, von' ),
			'mbs_name_key'            => array( 'label' => __( 'Surname / Last Name (key name)', 'my-book-showroom' ),                          'placeholder' => 'Smith, van der Berg' ),
			'mbs_name_after_key'      => array( 'label' => __( 'Suffix', 'my-book-showroom' ),                                      'placeholder' => 'Jr., III' ),
			'mbs_name_letters'        => array( 'label' => __( 'Letters after name', 'my-book-showroom' ),                          'placeholder' => 'PhD, OBE, CBE' ),
			'mbs_name_inverted'       => array( 'label' => __( 'Inverted name (sort / ONIX PersonNameInverted)', 'my-book-showroom' ), 'placeholder' => __( 'Auto-computed from fields above when left blank', 'my-book-showroom' ) ),
		);
		foreach ( $name_fields as $meta_key => $field ) :
			$val = (string) get_term_meta( $term->term_id, $meta_key, true );
		?>
		<tr class="form-field">
			<th scope="row"><label for="<?php echo esc_attr( $meta_key ); ?>"><?php echo esc_html( $field['label'] ); ?></label></th>
			<td><input type="text" id="<?php echo esc_attr( $meta_key ); ?>" name="<?php echo esc_attr( $meta_key ); ?>"
				value="<?php echo esc_attr( $val ); ?>"
				placeholder="<?php echo esc_attr( $field['placeholder'] ); ?>"></td>
		</tr>
		<?php endforeach; ?>
		<?php
	}

	public static function save_term_meta( int $term_id ): void {
		// V8-C-007: Contributor term meta requires nonce + capability check.
		if ( ! isset( $_POST['mbs_contributor_nonce'] ) ) {
			return;
		}
		$nonce_value = sanitize_text_field( wp_unslash( $_POST['mbs_contributor_nonce'] ) );
		// Accept either the edit-specific nonce or the add-form nonce (term_id not yet assigned at add render time).
		if ( ! wp_verify_nonce( $nonce_value, 'mbs_save_contributor_' . $term_id )
			&& ! wp_verify_nonce( $nonce_value, 'mbs_save_contributor_new' )
		) {
			return;
		}
		if ( ! current_user_can( 'manage_categories' ) ) {
			return;
		}

		update_term_meta( $term_id, 'mbs_is_corporate', isset( $_POST['mbs_is_corporate'] ) ? 1 : 0 );

		if ( isset( $_POST['mbs_author_bio'] ) ) {
			$bio = sanitize_textarea_field( wp_unslash( $_POST['mbs_author_bio'] ) );
			update_term_meta( $term_id, 'mbs_author_bio', mb_substr( $bio, 0, 4000 ) );
		}

		if ( isset( $_POST['mbs_isni'] ) ) {
			$isni = preg_replace( '/[^0-9X]/', '', strtoupper( sanitize_text_field( wp_unslash( $_POST['mbs_isni'] ) ) ) );
			if ( '' !== $isni && strlen( $isni ) !== 16 ) {
				$isni = ''; // Reject invalid ISNI — must be exactly 16 digits.
			}
			update_term_meta( $term_id, 'mbs_isni', $isni );
		}

		// F-NAMES-1: structured name fields.
		$simple_name_keys = array(
			'mbs_name_titles_before',
			'mbs_name_before_key',
			'mbs_name_prefix_to_key',
			'mbs_name_key',
			'mbs_name_after_key',
			'mbs_name_letters',
		);
		foreach ( $simple_name_keys as $key ) {
			$val = isset( $_POST[ $key ] )
				? sanitize_text_field( wp_unslash( $_POST[ $key ] ) )
				: '';
			update_term_meta( $term_id, $key, $val );
		}

		// mbs_name_inverted: use manual entry or auto-compute from structured parts.
		$name_inverted = isset( $_POST['mbs_name_inverted'] )
			? sanitize_text_field( wp_unslash( $_POST['mbs_name_inverted'] ) )
			: '';
		if ( '' === $name_inverted ) {
			$name_key           = isset( $_POST['mbs_name_key'] ) ? sanitize_text_field( wp_unslash( $_POST['mbs_name_key'] ) ) : '';
			$name_prefix_to_key = isset( $_POST['mbs_name_prefix_to_key'] ) ? sanitize_text_field( wp_unslash( $_POST['mbs_name_prefix_to_key'] ) ) : '';
			$name_before_key    = isset( $_POST['mbs_name_before_key'] ) ? sanitize_text_field( wp_unslash( $_POST['mbs_name_before_key'] ) ) : '';
			$name_after_key     = isset( $_POST['mbs_name_after_key'] ) ? sanitize_text_field( wp_unslash( $_POST['mbs_name_after_key'] ) ) : '';
			if ( '' !== $name_key ) {
				$key_part      = trim( $name_prefix_to_key . ' ' . $name_key );
				$rest_parts    = array_filter( array( $name_before_key, $name_after_key ) );
				$rest          = implode( ' ', $rest_parts );
				$name_inverted = $rest ? $key_part . ', ' . $rest : $key_part;
			}
		}
		update_term_meta( $term_id, 'mbs_name_inverted', $name_inverted );
	}
}
