<?php
/**
 * Quick Edit & Bulk Edit for SEO Fields
 *
 * Adds SEO title, description, noindex, and nofollow fields to
 * WordPress's Quick Edit and Bulk Edit on post list tables.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Admin;

use SEOvaultSEO\Core\PostMeta;
use SEOvaultSEO\Utils\Sanitizer;
use SEOvaultSEO\Compatibility\Detector;

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

class QuickEdit {

	public static function init() {
		if ( ! Detector::should_output_seo() ) {
			return;
		}

		// Add hidden SEO data to each post row (for Quick Edit population).
		add_action( 'manage_posts_custom_column', array( __CLASS__, 'populate_quick_edit_data' ), 10, 2 );
		add_action( 'manage_pages_custom_column', array( __CLASS__, 'populate_quick_edit_data' ), 10, 2 );

		// Add Quick Edit fields via the quick_edit_custom_box filter.
		add_action( 'quick_edit_custom_box', array( __CLASS__, 'quick_edit_fields' ), 10, 2 );

		// Add Bulk Edit fields via the bulk_edit_custom_box filter.
		add_action( 'bulk_edit_custom_box', array( __CLASS__, 'bulk_edit_fields' ), 10, 2 );

		// Enqueue JS for Quick Edit population and saving.
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );

		// AJAX handler for Quick Edit save.
		add_action( 'wp_ajax_seovaultseo_quick_edit_save', array( __CLASS__, 'ajax_save' ) );

		// WordPress verifies the bulk-posts nonce before firing this hook.
		add_action( 'bulk_edit_posts', array( __CLASS__, 'handle_bulk_save' ), 10, 2 );

		// Post states — show SEO labels next to post titles in list tables.
		add_filter( 'display_post_states', array( __CLASS__, 'add_post_states' ), 10, 2 );
	}

	/**
	 * Enqueue assets on edit.php screens.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public static function enqueue_assets( $hook ) {
		if ( 'edit.php' !== $hook ) {
			return;
		}

		wp_enqueue_script(
			'seovaultseo-quick-edit',
			SEOVAULT_SEO_URL . 'assets/js/seo-quick-edit.js',
			array( 'jquery', 'inline-edit-post' ),
			SEOVAULT_SEO_VERSION . '-2',
			true
		);

		wp_set_script_translations( 'seovaultseo-quick-edit', 'seovault-ai', SEOVAULT_SEO_DIR . 'languages/' );

		wp_localize_script(
			'seovaultseo-quick-edit',
			'seovaultseo_quick_edit',
			array(
				'ajax_url' => admin_url( 'admin-ajax.php' ),
				'nonce'    => wp_create_nonce( 'seovaultseo_quick_edit_nonce' ),
			)
		);
	}

	/**
	 * Output hidden data attributes on the SEO column so Quick Edit JS
	 * can read the current values when the inline editor opens.
	 *
	 * This hooks into the existing 'seovaultseo-data' column content.
	 * We append hidden spans with the current SEO meta values.
	 *
	 * @param string $column_name Column name.
	 * @param int    $post_id     Post ID.
	 */
	public static function populate_quick_edit_data( $column_name, $post_id ) {
		if ( 'seovaultseo-data' !== $column_name ) {
			return;
		}

		$title    = PostMeta::get_seo_title( $post_id );
		$desc     = PostMeta::get_seo_description( $post_id );
		$noindex  = PostMeta::is_noindex( $post_id ) ? '1' : '0';
		$nofollow = PostMeta::is_nofollow( $post_id ) ? '1' : '0';

		printf(
			'<span class="hidden seovaultseo-quick-edit-data" data-post-id="%d" data-seo-title="%s" data-seo-description="%s" data-noindex="%s" data-nofollow="%s"></span>',
			esc_attr( (string) $post_id ),
			esc_attr( $title ),
			esc_attr( $desc ),
			esc_attr( $noindex ),
			esc_attr( $nofollow )
		);
	}

	/**
	 * Render Quick Edit fields.
	 *
	 * @param string $column_name Column name.
	 * @param string $post_type   Post type.
	 */
	public static function quick_edit_fields( $column_name, $post_type ) {
		if ( 'seovaultseo-data' !== $column_name ) {
			return;
		}

		?>
		<fieldset class="inline-edit-col seovaultseo-quick-edit">
			<div class="inline-edit-col">
				<label>
					<span class="title"><?php esc_html_e( 'SEO Title', 'seovault-ai' ); ?></span>
					<span class="input-text-wrap">
						<input type="text" name="seovault_seo_title" class="ptitle" value="" />
					</span>
				</label>
				<label>
					<span class="title"><?php esc_html_e( 'SEO Description', 'seovault-ai' ); ?></span>
					<span class="input-text-wrap">
						<textarea name="seovault_seo_description" rows="2" cols="22" class="ptitle"></textarea>
					</span>
				</label>
				<label class="alignleft">
					<input type="checkbox" name="seovault_robots_noindex" value="1" />
					<span class="checkbox-title"><?php esc_html_e( 'Noindex', 'seovault-ai' ); ?></span>
				</label>
				<label class="alignleft">
					<input type="checkbox" name="seovault_robots_nofollow" value="1" />
					<span class="checkbox-title"><?php esc_html_e( 'Nofollow', 'seovault-ai' ); ?></span>
				</label>
			</div>
		</fieldset>
		<?php
	}

	/**
	 * Render Bulk Edit fields.
	 *
	 * Bulk Edit doesn't allow pre-populating values (it applies to multiple posts).
	 * We provide a "leave unchanged" option via empty fields.
	 *
	 * @param string $column_name Column name.
	 * @param string $post_type   Post type.
	 */
	public static function bulk_edit_fields( $column_name, $post_type ) {
		if ( 'seovaultseo-data' !== $column_name ) {
			return;
		}

		?>
		<fieldset class="inline-edit-col seovaultseo-bulk-edit">
			<div class="inline-edit-col">
				<label>
					<span class="title"><?php esc_html_e( 'SEO Title', 'seovault-ai' ); ?></span>
					<span class="input-text-wrap">
						<input type="text" name="seovault_seo_title" class="ptitle" value="" placeholder="<?php esc_attr_e( 'Leave empty to keep existing', 'seovault-ai' ); ?>" />
					</span>
				</label>
				<label>
					<span class="title"><?php esc_html_e( 'SEO Description', 'seovault-ai' ); ?></span>
					<span class="input-text-wrap">
						<textarea name="seovault_seo_description" rows="2" cols="22" class="ptitle" placeholder="<?php esc_attr_e( 'Leave empty to keep existing', 'seovault-ai' ); ?>"></textarea>
					</span>
				</label>
				<label class="alignleft">
					<input type="checkbox" name="seovault_robots_noindex" value="1" />
					<span class="checkbox-title"><?php esc_html_e( 'Set Noindex', 'seovault-ai' ); ?></span>
				</label>
				<label class="alignleft">
					<input type="checkbox" name="seovault_robots_nofollow" value="1" />
					<span class="checkbox-title"><?php esc_html_e( 'Set Nofollow', 'seovault-ai' ); ?></span>
				</label>
				<p class="description"><?php esc_html_e( 'Empty fields will keep existing values. Checkboxes will apply to all selected posts.', 'seovault-ai' ); ?></p>
			</div>
		</fieldset>
		<?php
	}

	/**
	 * AJAX handler for Quick Edit save.
	 * WordPress Quick Edit saves via AJAX, so we handle it here.
	 */
	public static function ajax_save() {
		check_ajax_referer( 'seovaultseo_quick_edit_nonce', 'nonce' );

		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( array( 'message' => __( 'Unauthorized.', 'seovault-ai' ) ) );
		}

		$post_id = isset( $_POST['post_id'] ) ? absint( wp_unslash( $_POST['post_id'] ) ) : 0;

		if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
			wp_send_json_error( array( 'message' => __( 'Invalid post.', 'seovault-ai' ) ) );
		}

		if ( isset( $_POST['seovault_seo_title'] ) ) {
			$title = Sanitizer::sanitize_title( sanitize_text_field( wp_unslash( $_POST['seovault_seo_title'] ) ) );
			PostMeta::set_seo_title( $post_id, $title );
		}

		if ( isset( $_POST['seovault_seo_description'] ) ) {
			$desc = Sanitizer::sanitize_description( sanitize_textarea_field( wp_unslash( $_POST['seovault_seo_description'] ) ) );
			PostMeta::set_seo_description( $post_id, $desc );
		}

		if ( isset( $_POST['seovault_robots_noindex'] ) ) {
			PostMeta::set_noindex( $post_id, ! empty( $_POST['seovault_robots_noindex'] ) );
		}

		if ( isset( $_POST['seovault_robots_nofollow'] ) ) {
			PostMeta::set_nofollow( $post_id, ! empty( $_POST['seovault_robots_nofollow'] ) );
		}

		wp_send_json_success( array( 'message' => __( 'Saved.', 'seovault-ai' ) ) );
	}

	/**
	 * Validate and apply the WordPress bulk edit payload.
	 *
	 * @param array $post_ids Array of post IDs updated by core.
	 * @param array $payload  Sanitized-by-core bulk request payload.
	 */
	public static function handle_bulk_save( $post_ids, $payload = array() ) {
		// Verify the core bulk-post nonce before reading IDs or SEO fields.
		$nonce = isset( $_REQUEST['_wpnonce'] )
			? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) )
			: '';
		if ( '' === $nonce || ! wp_verify_nonce( $nonce, 'bulk-posts' ) ) {
			return;
		}

		if ( ! current_user_can( 'edit_posts' ) ) {
			return;
		}

		if ( ! is_array( $payload ) ) {
			return;
		}

		$clean_payload = array(
			'title'    => isset( $payload['seovault_seo_title'] ) ? sanitize_text_field( wp_unslash( $payload['seovault_seo_title'] ) ) : '',
			'desc'     => isset( $payload['seovault_seo_description'] ) ? sanitize_textarea_field( wp_unslash( $payload['seovault_seo_description'] ) ) : '',
			'noindex'  => isset( $payload['seovault_robots_noindex'] ) && '' !== (string) $payload['seovault_robots_noindex'],
			'nofollow' => isset( $payload['seovault_robots_nofollow'] ) && '' !== (string) $payload['seovault_robots_nofollow'],
		);

		$clean_ids = array_values( array_filter( array_map( 'absint', (array) $post_ids ) ) );
		self::apply_bulk_save( $clean_ids, $clean_payload );
	}

	/**
	 * Apply sanitized bulk SEO values without reading request globals.
	 *
	 * @param int[] $post_ids Sanitized post IDs.
	 * @param array $payload  Sanitized field values.
	 * @return void
	 */
	private static function apply_bulk_save( array $post_ids, array $payload ) {
		$title    = (string) $payload['title'];
		$desc     = (string) $payload['desc'];
		$noindex  = ! empty( $payload['noindex'] );
		$nofollow = ! empty( $payload['nofollow'] );

		// Only update fields that have values (bulk edit = leave empty = keep existing).
		foreach ( $post_ids as $post_id ) {
			if ( ! current_user_can( 'edit_post', $post_id ) ) {
				continue;
			}

			if ( '' !== $title ) {
				PostMeta::set_seo_title( $post_id, $title );
			}

			if ( '' !== $desc ) {
				PostMeta::set_seo_description( $post_id, $desc );
			}

			// Checkboxes: only apply if checked.
			if ( $noindex ) {
				PostMeta::set_noindex( $post_id, true );
			}
			if ( $nofollow ) {
				PostMeta::set_nofollow( $post_id, true );
			}
		}
	}

	/**
	 * Add SEO post states to the post list table.
	 *
	 * Shows "Noindex" and "Nofollow" labels next to post titles when those
	 * robots directives are set on the post.
	 *
	 * @param array   $post_states Existing post states.
	 * @param WP_Post $post        Post object.
	 * @return array Modified post states.
	 */
	public static function add_post_states( $post_states, $post ) {
		if ( ! $post instanceof \WP_Post ) {
			return $post_states;
		}

		if ( PostMeta::is_noindex( $post->ID ) ) {
			$post_states['seovaultseo_noindex'] = __( 'Noindex', 'seovault-ai' );
		}

		if ( PostMeta::is_nofollow( $post->ID ) ) {
			$post_states['seovaultseo_nofollow'] = __( 'Nofollow', 'seovault-ai' );
		}

		return $post_states;
	}
}
