<?php
/**
 * File Path: includes/metaboxes/class-mbs-metabox-book-club.php
 *
 * Book Club Resources Metabox — My Book Showroom
 *
 * Adds a "Book Club Resources" metabox to the mbs_book edit screen.
 * Provides four PRO-only resource fields:
 *   · Visibility toggle    — checkbox; controls front-end rendering
 *   · Discussion guide     — rich-text (wp_kses_post on save)
 *   · Discussion questions — draggable rows, stored as JSON array of strings
 *   · Downloadable files   — attachment ID + label pairs, stored as JSON array of {id,label} objects
 *
 * FREE behavior: the metabox is registered so the section order list can
 * reference 'book-club-resources', but the render callback outputs only an
 * HTML comment — never a visible element.
 *
 * Section key: 'book-club-resources'
 *
 * Orchestrator wiring (class-mbs-plugin.php, inside is_admin() block):
 *   require_once MBS_INCLUDES_DIR . 'metaboxes/class-mbs-metabox-book-club.php';
 *   new MBS_Metabox_Book_Club();
 *
 * Story 14-4 — Sprint 14. UI improvements — Sprint BOOK-CLUB-UI.
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Metaboxes
 * @since      1.0.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_Book_Club extends MBS_Metabox_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	// Postmeta keys — canonical; match these exactly in templates and importers.
	const META_ENABLED   = 'mbs_book_club_enabled';
	const META_GUIDE     = 'mbs_book_club_guide';
	const META_QUESTIONS = 'mbs_book_club_questions';
	const META_FILES     = 'mbs_book_club_files';

	// __ Render ________________________________________________________________

	/**
	 * Render the Book Club Resources metabox.
	 *
	 * @param WP_Post $post Current post object.
	 */
	public function render( WP_Post $post ): void {
		if ( ! mbs_is_pro() ) {
			echo '<!-- MBS: Book Club requires PRO license -->';
			return;
		}

		wp_nonce_field( 'mbs_book_club_save', 'mbs_book_club_nonce' );

		// Phase 9: read from DAO (backed by mbs_book_club / questions / files tables).
		$header     = MBS_Book_Club_DAO::get_header( $post->ID );
		$guide      = $header['guide'];
		$is_enabled = $header['enabled'];
		$questions  = MBS_Book_Club_DAO::get_questions( $post->ID );
		$files      = MBS_Book_Club_DAO::get_files( $post->ID );
		?>
		<div class="mbs-book-club-wrap">

			<!-- Visibility toggle -->
			<div class="mbs-book-club-field" style="margin-bottom:16px; padding:12px; background:#f8f9fa; border:1px solid #ddd; border-radius:4px;">
				<label style="display:flex; align-items:center; gap:8px; font-weight:600; cursor:pointer;">
					<input type="checkbox"
					       name="mbs_book_club_enabled"
					       value="1"
					       <?php checked( $is_enabled ); ?>
					/>
					<?php esc_html_e( 'Show Book Club Resources on front end', 'my-book-showroom' ); ?>
				</label>
				<p class="description" style="margin:6px 0 0 24px;"><?php esc_html_e( 'When unchecked, this section is hidden from readers even if content is saved.', 'my-book-showroom' ); ?></p>
			</div>

			<!-- Discussion guide -->
			<div class="mbs-book-club-field" style="margin-bottom:20px;">
				<h4 style="margin:0 0 6px;"><?php esc_html_e( 'Discussion Guide', 'my-book-showroom' ); ?></h4>
				<p class="description" style="margin-bottom:8px;"><?php esc_html_e( 'Paste or write a discussion guide. Supports basic formatting.', 'my-book-showroom' ); ?></p>
				<?php
				wp_editor(
					wp_kses_post( (string) $guide ),
					'mbs_book_club_guide_editor',
					array(
						'textarea_name' => 'mbs_book_club_guide',
						'media_buttons' => false,
						'teeny'         => true,
						'textarea_rows' => 8,
					)
				);
				?>
			</div>

			<!-- Discussion questions -->
			<div class="mbs-book-club-field" style="margin-bottom:20px;">
				<h4 style="margin:0 0 6px;"><?php esc_html_e( 'Discussion Questions', 'my-book-showroom' ); ?></h4>
				<p class="description" style="margin-bottom:8px;"><?php esc_html_e( 'Add one question per row. Drag the handle to reorder, or use the arrows if drag is unavailable.', 'my-book-showroom' ); ?></p>

				<ul id="mbs-book-club-questions-list" style="margin:0; padding:0; list-style:none;">
					<?php foreach ( $questions as $question ) : ?>
					<li class="mbs-book-club-question-row" style="display:flex; align-items:center; gap:8px; margin-bottom:6px;">
						<span class="dashicons dashicons-menu mbs-question-drag-handle" style="cursor:grab; color:#aaa; flex-shrink:0;" aria-hidden="true"></span>
						<span class="mbs-question-fallback" style="display:none; flex-shrink:0;">
							<button type="button" class="button button-small mbs-question-move-up"
							        title="<?php esc_attr_e( 'Move up', 'my-book-showroom' ); ?>"
							        aria-label="<?php esc_attr_e( 'Move up', 'my-book-showroom' ); ?>">&#9650;</button>
							<button type="button" class="button button-small mbs-question-move-down"
							        title="<?php esc_attr_e( 'Move down', 'my-book-showroom' ); ?>"
							        aria-label="<?php esc_attr_e( 'Move down', 'my-book-showroom' ); ?>">&#9660;</button>
						</span>
						<input type="text"
						       name="mbs_book_club_question[]"
						       value="<?php echo esc_attr( $question ); ?>"
						       class="regular-text"
						       style="flex:1;"
						       placeholder="<?php esc_attr_e( 'Enter a discussion question…', 'my-book-showroom' ); ?>"
						/>
						<button type="button"
						        class="button button-small mbs-book-club-remove-question"
						        aria-label="<?php esc_attr_e( 'Remove question', 'my-book-showroom' ); ?>">
							<span class="dashicons dashicons-trash" aria-hidden="true"></span>
						</button>
					</li>
					<?php endforeach; ?>
				</ul>

				<p style="margin-top:8px;">
					<button type="button" id="mbs-book-club-add-question" class="button">
						<span class="dashicons dashicons-plus-alt2" style="vertical-align:middle;"></span>
						<?php esc_html_e( 'Add Question', 'my-book-showroom' ); ?>
					</button>
				</p>
			</div>

			<!-- Downloadable files -->
			<div class="mbs-book-club-field">
				<h4 style="margin:0 0 6px;"><?php esc_html_e( 'Downloadable Files', 'my-book-showroom' ); ?></h4>
				<p class="description" style="margin-bottom:8px;"><?php esc_html_e( 'Add PDFs or other files readers can download. Optionally give each file a descriptive label.', 'my-book-showroom' ); ?></p>

				<div id="mbs-book-club-files-list">
					<?php foreach ( $files as $item ) :
						// Backward-compat: old format was plain int, new is {id, label}.
						if ( is_array( $item ) ) {
							$attachment_id = absint( $item['id']    ?? 0 );
							$file_label    = sanitize_text_field( $item['label'] ?? '' );
						} else {
							$attachment_id = absint( $item );
							$file_label    = '';
						}
						if ( ! $attachment_id || ! get_post( $attachment_id ) ) {
							continue;
						}
						$url      = wp_get_attachment_url( $attachment_id );
						$filename = basename( get_attached_file( $attachment_id ) );
					?>
					<div class="mbs-book-club-file-row"
					     data-id="<?php echo esc_attr( $attachment_id ); ?>"
					     style="display:flex; align-items:center; gap:8px; margin-bottom:8px; padding:8px; background:#fff; border:1px solid #ddd; border-radius:3px;">
						<span class="dashicons dashicons-media-default" aria-hidden="true" style="flex-shrink:0;"></span>
						<input type="hidden" name="mbs_book_club_file_ids[]" value="<?php echo esc_attr( $attachment_id ); ?>" />
						<div style="flex:1; min-width:0;">
							<a href="<?php echo esc_url( $url ); ?>"
							   target="_blank" rel="noopener"
							   style="display:block; font-size:12px; color:#666; margin-bottom:4px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
								<?php echo esc_html( $filename ); ?>
							</a>
							<input type="text"
							       name="mbs_book_club_file_labels[]"
							       value="<?php echo esc_attr( $file_label ); ?>"
							       class="widefat"
							       placeholder="<?php esc_attr_e( 'File label (optional, e.g. Discussion Guide PDF)', 'my-book-showroom' ); ?>"
							/>
						</div>
						<button type="button"
						        class="button button-small mbs-book-club-remove-file"
						        data-id="<?php echo esc_attr( $attachment_id ); ?>"
						        aria-label="<?php esc_attr_e( 'Remove file', 'my-book-showroom' ); ?>"
						        style="flex-shrink:0;">
							<?php esc_html_e( 'Remove', 'my-book-showroom' ); ?>
						</button>
					</div>
					<?php endforeach; ?>
				</div>

				<p>
					<button type="button" id="mbs-book-club-add-file" class="button">
						<span class="dashicons dashicons-upload" style="vertical-align:middle;"></span>
						<?php esc_html_e( 'Add File', 'my-book-showroom' ); ?>
					</button>
				</p>
			</div>

		</div><!-- .mbs-book-club-wrap -->
		<?php
	}

	// __ Save __________________________________________________________________

	/**
	 * Persist Book Club Resource fields on book save.
	 *
	 * Nonce: mbs_book_club_nonce / mbs_book_club_save.
	 * PRO gate enforced server-side — non-PRO saves are silently ignored.
	 *
	 * Files data model: JSON array of {id: int, label: string} objects.
	 * Backward-compat read (template-side): items may be plain int (legacy).
	 *
	 * @param int     $post_id
	 * @param WP_Post $post
	 */
	public function save( int $post_id, WP_Post $post ): void {
		if ( ! $this->verify_save( $post_id, 'mbs_book_club_nonce', 'mbs_book_club_save' ) ) {
			return;
		}

		// PRO gate: wipe fields on non-PRO saves to prevent data accumulation.
		if ( ! mbs_is_pro() ) {
			MBS_Book_Club_DAO::delete_all_for_book( $post_id );
			return;
		}

		// Visibility toggle.
		$enabled = isset( $_POST['mbs_book_club_enabled'] ) && '1' === $_POST['mbs_book_club_enabled'] ? '1' : '0';

		// Discussion guide (HTML).
		$guide_raw   = wp_unslash( $_POST['mbs_book_club_guide'] ?? '' );
		$guide_clean = wp_kses_post( $guide_raw );
		MBS_Book_Club_DAO::upsert_header( $post_id, '1' === $enabled, $guide_clean );

		// Discussion questions — JSON array of strings from mbs_book_club_question[].
		$q_lines = array();
		if ( isset( $_POST['mbs_book_club_question'] ) && is_array( $_POST['mbs_book_club_question'] ) ) {
			foreach ( $_POST['mbs_book_club_question'] as $raw_q ) {
				$q = sanitize_text_field( wp_unslash( $raw_q ) );
				if ( '' !== $q ) {
					$q_lines[] = $q;
				}
			}
		}
		MBS_Book_Club_DAO::replace_questions( $post_id, $q_lines );

		// Downloadable files — JSON array of {id, label} objects.
		// mbs_book_club_file_ids[] and mbs_book_club_file_labels[] are parallel arrays.
		$submitted_files = array();
		$raw_ids    = isset( $_POST['mbs_book_club_file_ids'] )    && is_array( $_POST['mbs_book_club_file_ids'] )    ? $_POST['mbs_book_club_file_ids']    : array();
		$raw_labels = isset( $_POST['mbs_book_club_file_labels'] ) && is_array( $_POST['mbs_book_club_file_labels'] ) ? $_POST['mbs_book_club_file_labels'] : array();
		$seen_ids   = array();

		foreach ( $raw_ids as $i => $raw_id ) {
			$att_id = absint( $raw_id );
			if ( $att_id <= 0 || in_array( $att_id, $seen_ids, true ) ) {
				continue;
			}
			if ( ! ( get_post( $att_id ) instanceof WP_Post ) ) {
				continue;
			}
			$seen_ids[]        = $att_id;
			$label             = sanitize_text_field( wp_unslash( $raw_labels[ $i ] ?? '' ) );
			$submitted_files[] = array( 'id' => $att_id, 'label' => $label );
		}

		MBS_Book_Club_DAO::replace_files( $post_id, $submitted_files );
	}

	/**
	 * 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 );
	}

}
