<?php
/**
 * Disable Comments Module
 *
 * Disable comments on your site.
 *
 * @package BlaminhorEssentials
 */

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Disable Comments module class
 */
class Blaminhor_Essentials_Module_Disable_Comments extends Blaminhor_Essentials_Module {

	/**
	 * Module ID
	 *
	 * @var string
	 */
	protected $id = 'disable-comments';

	/**
	 * Module name
	 *
	 * @var string
	 */
	protected $name = 'Disable Comments';

	/**
	 * Initialize module
	 */
	protected function init() {
		$this->name        = __( 'Disable Comments', 'blaminhor-essentials' );
		$this->description = __( 'Disable comments on your site.', 'blaminhor-essentials' );
	}

	/**
	 * Get default settings
	 *
	 * @return array
	 */
	protected function get_default_settings() {
		return array(
			'disable_comments'    => true,
			'hide_from_admin'     => true,
			'existing_closed'     => false,
		);
	}

	/**
	 * Register hooks
	 */
	protected function register_hooks() {
		add_action( 'admin_init', array( $this, 'handle_settings_submission' ) );

		// AJAX handlers.
		add_action( 'wp_ajax_ap_disable_comments_close_existing', array( $this, 'ajax_close_existing' ) );
		add_action( 'wp_ajax_ap_disable_comments_delete_all', array( $this, 'ajax_delete_all' ) );

		if ( ! $this->get_setting( 'disable_comments', true ) ) {
			return;
		}

		// Close comments and pings on all post types.
		add_filter( 'comments_open', '__return_false', 20, 2 );
		add_filter( 'pings_open', '__return_false', 20, 2 );

		// Return empty comments array.
		add_filter( 'comments_array', '__return_empty_array', 10, 2 );

		// Remove comments support from all post types.
		add_action( 'init', array( $this, 'remove_comment_support' ), 100 );

		// Remove X-Pingback header.
		add_filter( 'wp_headers', array( $this, 'remove_pingback_header' ) );

		// Deregister Recent Comments widget.
		add_action( 'widgets_init', array( $this, 'unregister_comments_widget' ) );

		// Remove comments from admin bar.
		add_action( 'wp_before_admin_bar_render', array( $this, 'remove_admin_bar_comments' ) );

		// Remove comment feed links.
		add_filter( 'feed_links_show_comments_feed', '__return_false' );

		if ( $this->get_setting( 'hide_from_admin', true ) ) {
			// Remove Comments menu from admin.
			add_action( 'admin_menu', array( $this, 'remove_comments_menu' ), 999 );

			// Redirect edit-comments.php to dashboard.
			add_action( 'admin_init', array( $this, 'redirect_comments_page' ) );

			// Remove comments column from post lists.
			add_action( 'admin_init', array( $this, 'remove_comments_columns' ) );

			// Remove comments metabox from post editor.
			add_action( 'admin_init', array( $this, 'remove_comments_metabox' ) );

			// Remove dashboard comments widget.
			add_action( 'wp_dashboard_setup', array( $this, 'remove_dashboard_comments_widget' ) );
		}
	}

	/**
	 * Remove comment and trackback support from all post types
	 */
	public function remove_comment_support() {
		$post_types = get_post_types( array(), 'names' );

		foreach ( $post_types as $post_type ) {
			if ( post_type_supports( $post_type, 'comments' ) ) {
				remove_post_type_support( $post_type, 'comments' );
			}
			if ( post_type_supports( $post_type, 'trackbacks' ) ) {
				remove_post_type_support( $post_type, 'trackbacks' );
			}
		}
	}

	/**
	 * Remove X-Pingback header
	 *
	 * @param array $headers HTTP headers.
	 * @return array
	 */
	public function remove_pingback_header( $headers ) {
		unset( $headers['X-Pingback'] );
		return $headers;
	}

	/**
	 * Unregister Recent Comments widget
	 */
	public function unregister_comments_widget() {
		unregister_widget( 'WP_Widget_Recent_Comments' );
	}

	/**
	 * Remove comments from admin bar
	 */
	public function remove_admin_bar_comments() {
		global $wp_admin_bar;
		$wp_admin_bar->remove_menu( 'comments' );
	}

	/**
	 * Remove Comments menu from admin
	 */
	public function remove_comments_menu() {
		remove_menu_page( 'edit-comments.php' );
	}

	/**
	 * Redirect edit-comments.php to dashboard
	 */
	public function redirect_comments_page() {
		global $pagenow;

		if ( 'edit-comments.php' === $pagenow ) {
			wp_safe_redirect( admin_url() );
			exit;
		}
	}

	/**
	 * Remove comments column from all post type list tables
	 */
	public function remove_comments_columns() {
		$post_types = get_post_types( array( 'public' => true ), 'names' );

		foreach ( $post_types as $post_type ) {
			add_filter( "manage_{$post_type}_posts_columns", array( $this, 'filter_comments_column' ) );
		}

		// Also pages.
		add_filter( 'manage_pages_columns', array( $this, 'filter_comments_column' ) );
	}

	/**
	 * Filter out the comments column
	 *
	 * @param array $columns Post list columns.
	 * @return array
	 */
	public function filter_comments_column( $columns ) {
		unset( $columns['comments'] );
		return $columns;
	}

	/**
	 * Remove comments metabox from post editor
	 */
	public function remove_comments_metabox() {
		$post_types = get_post_types( array(), 'names' );

		foreach ( $post_types as $post_type ) {
			remove_meta_box( 'commentstatusdiv', $post_type, 'normal' );
			remove_meta_box( 'commentsdiv', $post_type, 'normal' );
			remove_meta_box( 'trackbacksdiv', $post_type, 'normal' );
		}
	}

	/**
	 * Remove dashboard comments widgets
	 */
	public function remove_dashboard_comments_widget() {
		remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' );
	}

	/**
	 * Get total comment count
	 *
	 * @return int
	 */
	private function get_comment_count() {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		return (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->comments}" );
	}

	/**
	 * Get count of posts with open comments
	 *
	 * @return int
	 */
	private function get_open_comments_count() {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		return (int) $wpdb->get_var(
			"SELECT COUNT(*) FROM {$wpdb->posts} WHERE comment_status = 'open' OR ping_status = 'open'"
		);
	}

	/**
	 * AJAX: Close existing comments on all posts
	 */
	public function ajax_close_existing() {
		check_ajax_referer( 'blaminhor_essentials_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'Unauthorized', 'blaminhor-essentials' ) );
		}

		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$affected = $wpdb->query(
			"UPDATE {$wpdb->posts} SET comment_status = 'closed', ping_status = 'closed' WHERE comment_status = 'open' OR ping_status = 'open'"
		);

		// Save flag.
		$settings                   = $this->settings;
		$settings['existing_closed'] = true;
		$this->save_settings( $settings );

		wp_send_json_success(
			array(
				/* translators: %d: number of posts updated */
				'message' => sprintf( __( '%d posts updated.', 'blaminhor-essentials' ), $affected ),
				'count'   => (int) $affected,
			)
		);
	}

	/**
	 * AJAX: Delete all comments
	 */
	public function ajax_delete_all() {
		check_ajax_referer( 'blaminhor_essentials_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'Unauthorized', 'blaminhor-essentials' ) );
		}

		global $wpdb;

		// Delete comment meta first (foreign key).
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( "DELETE FROM {$wpdb->commentmeta}" );

		// Delete all comments.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$deleted = $wpdb->query( "DELETE FROM {$wpdb->comments}" );

		// Reset comment counts on all posts.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query( "UPDATE {$wpdb->posts} SET comment_count = 0" );

		wp_send_json_success(
			array(
				/* translators: %d: number of comments deleted */
				'message' => sprintf( __( '%d comments deleted.', 'blaminhor-essentials' ), $deleted ),
				'count'   => (int) $deleted,
			)
		);
	}

	/**
	 * Enqueue module assets
	 *
	 * @param string $hook Current admin page hook.
	 */
	public function enqueue_assets( $hook ) {
		if ( strpos( $hook, 'blaminhor-essentials-disable-comments' ) === false ) {
			return;
		}

		$config = array(
			'nonce'   => wp_create_nonce( 'blaminhor_essentials_admin' ),
			'ajaxurl' => admin_url( 'admin-ajax.php' ),
			'strings' => array(
				'closing'         => __( 'Closing comments...', 'blaminhor-essentials' ),
				'deleting'        => __( 'Deleting comments...', 'blaminhor-essentials' ),
				'confirmDelete'   => __( 'Are you sure you want to permanently delete ALL comments? This action cannot be undone.', 'blaminhor-essentials' ),
				'error'           => __( 'An error occurred.', 'blaminhor-essentials' ),
			),
		);

		wp_add_inline_script(
			'blaminhor-essentials-modules',
			'jQuery(document).ready(function($) {
				var DisableComments = {
					config: ' . wp_json_encode( $config ) . ',
					init: function() {
						this.bindEvents();
					},
					bindEvents: function() {
						var self = this;

						$("#ap-close-existing-btn").on("click", function() {
							var $btn = $(this);
							var originalText = $btn.html();
							$btn.prop("disabled", true).html(\'<span class="dashicons dashicons-update ap-spin"></span> \' + self.config.strings.closing);

							$.post(self.config.ajaxurl, {
								action: "ap_disable_comments_close_existing",
								nonce: self.config.nonce
							}, function(response) {
								if (response.success) {
									$("#ap-close-existing-status").html(\'<div class="blaminhor-essentials-notice success" style="margin: 10px 0 0;"><p>\' + response.data.message + \'</p></div>\');
									$btn.prop("disabled", true).html(originalText);
									$("#ap-open-count").text("0");
								} else {
									$btn.prop("disabled", false).html(originalText);
									alert(response.data || self.config.strings.error);
								}
							}).fail(function() {
								$btn.prop("disabled", false).html(originalText);
								alert(self.config.strings.error);
							});
						});

						$("#ap-delete-all-btn").on("click", function() {
							if (!confirm(self.config.strings.confirmDelete)) {
								return;
							}

							var $btn = $(this);
							var originalText = $btn.html();
							$btn.prop("disabled", true).html(\'<span class="dashicons dashicons-update ap-spin"></span> \' + self.config.strings.deleting);

							$.post(self.config.ajaxurl, {
								action: "ap_disable_comments_delete_all",
								nonce: self.config.nonce
							}, function(response) {
								if (response.success) {
									$("#ap-delete-all-status").html(\'<div class="blaminhor-essentials-notice success" style="margin: 10px 0 0;"><p>\' + response.data.message + \'</p></div>\');
									$btn.prop("disabled", true).html(originalText);
									$("#ap-comment-count").text("0");
								} else {
									$btn.prop("disabled", false).html(originalText);
									alert(response.data || self.config.strings.error);
								}
							}).fail(function() {
								$btn.prop("disabled", false).html(originalText);
								alert(self.config.strings.error);
							});
						});
					}
				};
				DisableComments.init();
			});'
		);
	}

	/**
	 * Process settings
	 *
	 * @param array $data Form data.
	 */
	protected function process_settings( $data ) {
		$settings = array(
			'disable_comments' => isset( $data['disable_comments'] ),
			'hide_from_admin'  => isset( $data['hide_from_admin'] ),
			'existing_closed'  => $this->get_setting( 'existing_closed', false ),
		);

		$this->save_settings( $settings );

		add_action( 'admin_notices', function () {
			blaminhor_essentials_admin_notice( __( 'Settings saved.', 'blaminhor-essentials' ), 'success' );
		} );
	}

	/**
	 * Render settings page
	 */
	public function render_settings_page() {
		$this->handle_settings_submission();

		$comment_count      = $this->get_comment_count();
		$open_count         = $this->get_open_comments_count();
		$disable_comments   = $this->get_setting( 'disable_comments', true );
		$hide_from_admin    = $this->get_setting( 'hide_from_admin', true );
		?>
		<div class="wrap blaminhor-essentials-wrap">
			<div class="blaminhor-essentials-header">
				<h1><?php esc_html_e( 'Disable Comments', 'blaminhor-essentials' ); ?></h1>
				<p class="blaminhor-essentials-tagline">
					<?php esc_html_e( 'Disable comments on your site.', 'blaminhor-essentials' ); ?>
				</p>
			</div>

			<div class="blaminhor-essentials-section">
				<div class="ap-db-summary-cards ap-mb-lg">
					<div class="ap-db-card <?php echo $disable_comments ? 'ap-db-card-success' : 'ap-db-card-warning'; ?>">
						<div class="ap-db-card-icon">
							<span class="dashicons dashicons-<?php echo $disable_comments ? 'yes-alt' : 'warning'; ?>"></span>
						</div>
						<div class="ap-db-card-value"><?php echo $disable_comments ? esc_html__( 'Disabled', 'blaminhor-essentials' ) : esc_html__( 'Enabled', 'blaminhor-essentials' ); ?></div>
						<div class="ap-db-card-label"><?php esc_html_e( 'Comments Status', 'blaminhor-essentials' ); ?></div>
					</div>
					<div class="ap-db-card ap-db-card-info">
						<div class="ap-db-card-icon">
							<span class="dashicons dashicons-admin-comments"></span>
						</div>
						<div class="ap-db-card-value" id="ap-comment-count"><?php echo esc_html( number_format_i18n( $comment_count ) ); ?></div>
						<div class="ap-db-card-label"><?php esc_html_e( 'Comments in Database', 'blaminhor-essentials' ); ?></div>
					</div>
					<div class="ap-db-card ap-db-card-info">
						<div class="ap-db-card-icon">
							<span class="dashicons dashicons-unlock"></span>
						</div>
						<div class="ap-db-card-value" id="ap-open-count"><?php echo esc_html( number_format_i18n( $open_count ) ); ?></div>
						<div class="ap-db-card-label"><?php esc_html_e( 'Posts with Open Comments', 'blaminhor-essentials' ); ?></div>
					</div>
				</div>

				<form method="post">
					<?php $this->render_nonce_field(); ?>

					<table class="form-table">
						<tr>
							<th scope="row"><?php esc_html_e( 'Disable Comments', 'blaminhor-essentials' ); ?></th>
							<td>
								<label>
									<input type="checkbox" name="disable_comments" <?php checked( $disable_comments ); ?>>
									<?php esc_html_e( 'Disable all comments on all post types', 'blaminhor-essentials' ); ?>
								</label>
								<p class="description"><?php esc_html_e( 'Closes comments, hides existing comments, disables pingbacks/trackbacks, and removes comment feeds.', 'blaminhor-essentials' ); ?></p>
							</td>
						</tr>
						<tr>
							<th scope="row"><?php esc_html_e( 'Hide from Admin', 'blaminhor-essentials' ); ?></th>
							<td>
								<label>
									<input type="checkbox" name="hide_from_admin" <?php checked( $hide_from_admin ); ?>>
									<?php esc_html_e( 'Remove comments from admin menu, columns, and dashboard', 'blaminhor-essentials' ); ?>
								</label>
								<p class="description"><?php esc_html_e( 'Hides the Comments menu, removes comment columns from post lists, and redirects the comments page.', 'blaminhor-essentials' ); ?></p>
							</td>
						</tr>
					</table>

					<p class="submit">
						<button type="submit" class="button button-primary">
							<?php esc_html_e( 'Save Settings', 'blaminhor-essentials' ); ?>
						</button>
					</p>
				</form>

				<hr style="margin: 30px 0;">

				<h3><?php esc_html_e( 'Close Existing Comments', 'blaminhor-essentials' ); ?></h3>
				<p class="description">
					<?php esc_html_e( 'Set comment_status and ping_status to "closed" on all existing posts in the database.', 'blaminhor-essentials' ); ?>
				</p>
				<p>
					<?php
					printf(
						/* translators: %s: number of posts with open comments */
						esc_html__( '%s posts currently have open comments or pingbacks.', 'blaminhor-essentials' ),
						'<strong id="ap-open-count-tools">' . esc_html( number_format_i18n( $open_count ) ) . '</strong>'
					);
					?>
				</p>
				<div class="ap-mt-sm">
					<button type="button" id="ap-close-existing-btn" class="button button-secondary ap-btn-icon" <?php disabled( 0 === $open_count ); ?>>
						<span class="dashicons dashicons-lock"></span>
						<?php esc_html_e( 'Close Existing Comments', 'blaminhor-essentials' ); ?>
					</button>
					<div id="ap-close-existing-status"></div>
				</div>

				<hr style="margin: 30px 0;">

				<h3><?php esc_html_e( 'Delete All Comments', 'blaminhor-essentials' ); ?></h3>
				<p class="description">
					<?php esc_html_e( 'Permanently delete all comments and comment metadata from the database. This action cannot be undone.', 'blaminhor-essentials' ); ?>
				</p>
				<p>
					<?php
					printf(
						/* translators: %s: number of comments */
						esc_html__( '%s comments currently exist in the database.', 'blaminhor-essentials' ),
						'<strong id="ap-comment-count-tools">' . esc_html( number_format_i18n( $comment_count ) ) . '</strong>'
					);
					?>
				</p>
				<div class="ap-mt-sm">
					<button type="button" id="ap-delete-all-btn" class="button ap-btn-icon" style="color: #b32d2e; border-color: #b32d2e;" <?php disabled( 0 === $comment_count ); ?>>
						<span class="dashicons dashicons-trash"></span>
						<?php esc_html_e( 'Delete All Comments', 'blaminhor-essentials' ); ?>
					</button>
					<div id="ap-delete-all-status"></div>
				</div>
			</div>
		</div>
		<?php
	}
}
