<?php
/**
 * Per-post metabox — schema work in context (Phase F)
 *
 * A "Solomon Schema" box on the edit screen of every schema-enabled post
 * type. Tabbed (many tools, one small box — same reasoning as Yoast):
 *
 *   [Schema]  what this post emits + per-post overrides
 *   [Preview] the actual JSON-LD, with copy + validator link
 *
 * Per-post state lives in post meta:
 *   _bw_schema_disable        '1' = this post emits no Article/Person schema
 *   _bw_schema_type_override  schema.org type replacing the default BlogPosting
 *
 * @package BW_Schema
 * @since 3.7.0
 */

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

class BW_Schema_Metabox {

	/**
	 * Register hooks
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'add_meta_boxes', array( __CLASS__, 'register' ) );
		add_action( 'save_post', array( __CLASS__, 'save' ) );
	}

	/**
	 * Post types that get the metabox
	 *
	 * Article-enabled post types (Content settings) plus the team post type.
	 *
	 * @return string[]
	 */
	public static function get_target_post_types() {
		$types = BW_Schema_Service_Content::get_article_post_types();

		$team = BW_Schema_Service_People::get_team_post_type();
		if ( $team && ! in_array( $team, $types, true ) ) {
			$types[] = $team;
		}

		return array_values( array_filter( $types, 'post_type_exists' ) );
	}

	/**
	 * Allowed schema type overrides for article-type posts
	 *
	 * @return array Type => label ('' = default)
	 */
	public static function get_type_options() {
		return array(
			''            => __( 'Default (BlogPosting)', 'bw-schema' ),
			'Article'     => __( 'Article — generic', 'bw-schema' ),
			'NewsArticle' => __( 'News Article', 'bw-schema' ),
			'TechArticle' => __( 'Tech Article — how-to / documentation', 'bw-schema' ),
			'WebPage'     => __( 'Web Page — plain page, not an article', 'bw-schema' ),
			'AboutPage'   => __( 'About Page', 'bw-schema' ),
			'ContactPage' => __( 'Contact Page', 'bw-schema' ),
		);
	}

	/**
	 * Register the metabox on target post types
	 *
	 * @return void
	 */
	public static function register() {
		foreach ( self::get_target_post_types() as $post_type ) {
			add_meta_box(
				'bw-schema-metabox',
				__( 'Solomon Schema', 'bw-schema' ),
				array( __CLASS__, 'render' ),
				$post_type,
				'normal',
				'default'
			);
		}
	}

	/**
	 * Save metabox fields
	 *
	 * @param int $post_id Post ID
	 * @return void
	 */
	public static function save( $post_id ) {
		if ( ! isset( $_POST['bw_schema_metabox_nonce'] ) ) {
			return;
		}
		if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['bw_schema_metabox_nonce'] ) ), 'bw_schema_metabox' ) ) {
			return;
		}
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}
		if ( wp_is_post_revision( $post_id ) || ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}

		// Exclude toggle
		if ( ! empty( $_POST['bw_schema_disable'] ) ) {
			update_post_meta( $post_id, '_bw_schema_disable', '1' );
		} else {
			delete_post_meta( $post_id, '_bw_schema_disable' );
		}

		// Type override (article-type posts only; team posts don't post this field)
		if ( isset( $_POST['bw_schema_type_override'] ) ) {
			$override = sanitize_text_field( wp_unslash( $_POST['bw_schema_type_override'] ) );
			if ( '' !== $override && array_key_exists( $override, self::get_type_options() ) ) {
				update_post_meta( $post_id, '_bw_schema_type_override', $override );
			} else {
				delete_post_meta( $post_id, '_bw_schema_type_override' );
			}
		}

		// Cached schema for this post is stale now
		if ( class_exists( 'BW_Schema_Service_Cache' ) ) {
			BW_Schema_Service_Cache::clear_post( $post_id );
		}
	}

	/**
	 * Whether a post is the team (Person) kind
	 *
	 * @param WP_Post $post Post object
	 * @return bool
	 */
	private static function is_team_post( $post ) {
		$team = BW_Schema_Service_People::get_team_post_type();
		return $team && $post->post_type === $team;
	}

	/**
	 * Render the metabox
	 *
	 * @param WP_Post $post Post object
	 * @return void
	 */
	public static function render( $post ) {
		wp_nonce_field( 'bw_schema_metabox', 'bw_schema_metabox_nonce' );

		$disabled = ( '1' === get_post_meta( $post->ID, '_bw_schema_disable', true ) );
		?>
		<div class="bws-mb" id="bws-mb">
			<nav class="bws-mb-tabs">
				<button type="button" class="bws-mb-tab is-active" data-panel="bws-mb-schema"><?php esc_html_e( 'Schema', 'bw-schema' ); ?></button>
				<button type="button" class="bws-mb-tab" data-panel="bws-mb-preview"><?php esc_html_e( 'Preview', 'bw-schema' ); ?></button>
			</nav>

			<div class="bws-mb-panel is-active" id="bws-mb-schema">
				<?php self::render_schema_panel( $post, $disabled ); ?>
			</div>

			<div class="bws-mb-panel" id="bws-mb-preview">
				<?php self::render_preview_panel( $post, $disabled ); ?>
			</div>
		</div>
		<script>
		(function () {
			var box = document.getElementById('bws-mb');
			if (!box) { return; }

			box.querySelectorAll('.bws-mb-tab').forEach(function (tab) {
				tab.addEventListener('click', function () {
					box.querySelectorAll('.bws-mb-tab').forEach(function (t) { t.classList.remove('is-active'); });
					box.querySelectorAll('.bws-mb-panel').forEach(function (p) { p.classList.remove('is-active'); });
					tab.classList.add('is-active');
					document.getElementById(tab.dataset.panel).classList.add('is-active');
				});
			});

			var copyBtn = document.getElementById('bws-mb-copy');
			if (copyBtn) {
				copyBtn.addEventListener('click', function () {
					var json = document.getElementById('bws-mb-json');
					if (!json) { return; }
					navigator.clipboard.writeText(json.textContent).then(function () {
						copyBtn.textContent = '<?php echo esc_js( __( 'Copied!', 'bw-schema' ) ); ?>';
						setTimeout(function () {
							copyBtn.textContent = '<?php echo esc_js( __( 'Copy JSON', 'bw-schema' ) ); ?>';
						}, 1500);
					});
				});
			}
		})();
		</script>
		<?php
	}

	/**
	 * Render the Schema tab
	 *
	 * @param WP_Post $post Post object
	 * @param bool    $disabled Whether schema is disabled for this post
	 * @return void
	 */
	private static function render_schema_panel( $post, $disabled ) {
		$is_team  = self::is_team_post( $post );
		$override = get_post_meta( $post->ID, '_bw_schema_type_override', true );

		// What this post emits
		if ( $disabled ) {
			$emits = __( 'Nothing — schema is turned off for this post', 'bw-schema' );
		} elseif ( $is_team ) {
			$emits = __( 'Person (team member page)', 'bw-schema' );
		} else {
			$emits = ( $override && array_key_exists( $override, self::get_type_options() ) ) ? $override : 'BlogPosting';
		}

		echo '<p class="bws-mb-status">';
		printf(
			/* translators: %s: schema type this post emits */
			esc_html__( 'This post emits: %s', 'bw-schema' ),
			'<strong>' . esc_html( $emits ) . '</strong>'
		);
		echo '</p>';

		if ( ! $is_team ) {
			echo '<p><label for="bw_schema_type_override">' . esc_html__( 'Schema type for this post', 'bw-schema' ) . '</label><br>';
			echo '<select id="bw_schema_type_override" name="bw_schema_type_override">';
			foreach ( self::get_type_options() as $value => $label ) {
				echo '<option value="' . esc_attr( $value ) . '" ' . selected( $override, $value, false ) . '>' . esc_html( $label ) . '</option>';
			}
			echo '</select></p>';
			echo '<p class="description">' . esc_html__( 'Use this when a page isn\'t really an article — e.g. mark your about page as About Page.', 'bw-schema' ) . '</p>';
		}

		echo '<p><label>';
		echo '<input type="checkbox" name="bw_schema_disable" value="1" ' . checked( $disabled, true, false ) . '> ';
		echo esc_html__( 'Don\'t emit schema for this post', 'bw-schema' );
		echo '</label></p>';
		echo '<p class="description">' . esc_html__( 'Site-level Organization markup still appears — this only removes this post\'s own schema.', 'bw-schema' ) . '</p>';
	}

	/**
	 * Render the Preview tab
	 *
	 * @param WP_Post $post Post object
	 * @param bool    $disabled Whether schema is disabled for this post
	 * @return void
	 */
	private static function render_preview_panel( $post, $disabled ) {
		if ( $disabled ) {
			echo '<p>' . esc_html__( 'Schema is turned off for this post — nothing to preview.', 'bw-schema' ) . '</p>';
			return;
		}

		$schema = null;
		try {
			if ( self::is_team_post( $post ) ) {
				$obj = new BW_Schema_Schema_Person( $post );
			} else {
				$obj = new BW_Schema_Schema_Article( $post );
			}
			$schema = $obj->to_array();
		} catch ( Throwable $e ) {
			$schema = null;
		}

		if ( empty( $schema ) ) {
			echo '<p>' . esc_html__( 'No schema could be generated for this post yet — is it published with a title?', 'bw-schema' ) . '</p>';
			return;
		}

		echo '<p class="description">' . esc_html__( 'Reflects the last saved version of this post. Site-level Organization and breadcrumb markup are added on the live page.', 'bw-schema' ) . '</p>';

		echo '<pre class="bws-mb-json" id="bws-mb-json">';
		echo esc_html( wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) );
		echo '</pre>';

		$validate_url = 'https://validator.schema.org/#url=' . rawurlencode( get_permalink( $post->ID ) );

		echo '<p>';
		echo '<button type="button" class="button" id="bws-mb-copy">' . esc_html__( 'Copy JSON', 'bw-schema' ) . '</button> ';
		echo '<a class="button" href="' . esc_url( $validate_url ) . '" target="_blank" rel="noopener noreferrer">';
		echo esc_html__( 'Validate with Schema.org', 'bw-schema' ) . ' <span aria-hidden="true">↗</span></a>';
		echo '</p>';
	}
}
