<?php

defined( 'ABSPATH' ) || exit;

/**
 * Disable Comments module.
 *
 * Strips all comment functionality from the site. Designed for the typical
 * Bowden Works build where comments are unused and a perennial spam target.
 * Replaces the standalone "Disable Comments" plugin.
 *
 * When enabled (the editor_admin group defaults ON), this module:
 *  - Removes `comments` and `trackbacks` post-type support from every CPT.
 *  - Forces `comments_open`, `pings_open`, `get_comments_number`, and
 *    `comments_array` to read as closed / zero / empty everywhere.
 *  - Forces WP core's `default_comment_status` / `default_ping_status` to
 *    `closed` so new posts ship with comments off at the DB-column level.
 *  - Hard-fails any comment submission that slips through (`pre_comment_on_post`
 *    → wp_die 403).
 *  - Hides the Comments admin menu, the admin bar node, and the Recent
 *    Comments dashboard widget.
 *  - Redirects `edit-comments.php` and `options-discussion.php` to the
 *    dashboard so the screens aren't reachable by direct URL.
 *  - Empties `comments_notify_recipients`, `comment_moderation_recipients`,
 *    and forces `notify_post_author` false — no notification or moderation
 *    emails are ever generated.
 *  - Dequeues `comment-reply.js`, unregisters the Recent Comments core
 *    widget, and drops the comments-feed link from the front-end.
 *
 * No persisted settings — enabling this module on the Modules tab is the
 * toggle. Disable on the Modules tab to restore WordPress's default
 * comment behaviour.
 *
 * @package BW_Dev
 */

class BW_Dev_Module_Disable_Comments implements BW_Dev_Module_Interface {

	public function slug(): string {
		return 'disable_comments';
	}

	public function label(): string {
		return __( 'Disable Comments', 'bw-dev' );
	}

	public function group(): string {
		return 'editor_admin';
	}

	public function default_settings(): array {
		return array();
	}

	public function sanitize( array $data ): array {
		// No settings beyond the master on/off toggle on the Modules tab.
		return array();
	}

	public function register(): void {
		// Strip comment + trackback support from every post type.
		add_action( 'init', array( $this, 'remove_post_type_support' ), 100 );

		// Force WP defaults so new posts ship comments-off at the DB level.
		add_filter( 'pre_option_default_comment_status', array( $this, 'force_closed' ) );
		add_filter( 'pre_option_default_ping_status',    array( $this, 'force_closed' ) );

		// Force comments closed at runtime everywhere.
		add_filter( 'comments_open',       '__return_false',       20 );
		add_filter( 'pings_open',          '__return_false',       20 );
		add_filter( 'comments_array',      '__return_empty_array', 20 );
		add_filter( 'get_comments_number', '__return_zero',        20 );

		// Hard-fail any comment submission that slips through.
		add_action( 'pre_comment_on_post', array( $this, 'block_submission' ), 1 );

		// Admin: hide Comments menu, admin bar, dashboard widget; redirect screens.
		add_action( 'admin_menu',                 array( $this, 'remove_admin_menu' ) );
		add_action( 'wp_before_admin_bar_render', array( $this, 'remove_admin_bar' ) );
		add_action( 'wp_dashboard_setup',         array( $this, 'remove_dashboard_widget' ) );
		add_action( 'admin_init',                 array( $this, 'redirect_admin_pages' ) );

		// No notification / moderation emails.
		add_filter( 'comments_notify_recipients',    '__return_empty_array', 20 );
		add_filter( 'comment_moderation_recipients', '__return_empty_array', 20 );
		add_filter( 'notify_post_author',            '__return_false',       20 );

		// Front-end cleanup.
		add_action( 'wp_enqueue_scripts',            array( $this, 'dequeue_comment_reply' ), 100 );
		add_filter( 'feed_links_show_comments_feed', '__return_false' );
		add_action( 'widgets_init',                  array( $this, 'unregister_widget' ), 100 );
	}

	public function remove_post_type_support(): void {
		foreach ( get_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' );
			}
		}
	}

	public function force_closed(): string {
		return 'closed';
	}

	public function block_submission(): void {
		wp_die(
			esc_html__( 'Comments are closed.', 'bw-dev' ),
			esc_html__( 'Comments are closed', 'bw-dev' ),
			array( 'response' => 403 )
		);
	}

	public function remove_admin_menu(): void {
		remove_menu_page( 'edit-comments.php' );
		remove_submenu_page( 'options-general.php', 'options-discussion.php' );
	}

	public function remove_admin_bar(): void {
		global $wp_admin_bar;
		if ( $wp_admin_bar instanceof WP_Admin_Bar ) {
			$wp_admin_bar->remove_node( 'comments' );
		}
	}

	public function remove_dashboard_widget(): void {
		remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' );
	}

	public function redirect_admin_pages(): void {
		global $pagenow;
		if ( ! is_admin() || wp_doing_ajax() ) {
			return;
		}
		if ( 'edit-comments.php' === $pagenow || 'options-discussion.php' === $pagenow ) {
			wp_safe_redirect( admin_url() );
			exit;
		}
	}

	public function dequeue_comment_reply(): void {
		wp_dequeue_script( 'comment-reply' );
		wp_deregister_script( 'comment-reply' );
	}

	public function unregister_widget(): void {
		unregister_widget( 'WP_Widget_Recent_Comments' );
	}

	public function render_tab(): void {
		$modules_url = admin_url( 'options-general.php?page=bw-dev&tab=modules' );
		?>
		<p class="description">
			<?php esc_html_e( 'Strips all comment functionality from the site. Replaces the standalone "Disable Comments" plugin.', 'bw-dev' ); ?>
		</p>

		<div style="background:#edfaef;border:1px solid #00a32a;border-left-width:6px;padding:16px 20px;margin:14px 0;max-width:720px;border-radius:4px;">
			<p style="margin:0 0 8px;font-size:15px;">
				<span class="dashicons dashicons-yes-alt" style="color:#00a32a;font-size:20px;width:20px;height:20px;vertical-align:-3px;margin-right:4px;"></span>
				<strong><?php esc_html_e( 'Comments are disabled site-wide.', 'bw-dev' ); ?></strong>
			</p>
			<p style="margin:0;color:#1d2327;">
				<?php
				printf(
					/* translators: %s: anchor tag with link to Modules tab */
					esc_html__( 'To turn this feature OFF, %s and untick the "Disable Comments" checkbox under "Editor & Admin".', 'bw-dev' ),
					'<a href="' . esc_url( $modules_url ) . '"><strong>' . esc_html__( 'go to the Modules tab', 'bw-dev' ) . '</strong></a>'
				);
				?>
			</p>
			<p style="margin:8px 0 0;color:#646970;font-size:12px;">
				<?php esc_html_e( 'There are no per-feature toggles inside this tab — the module enable/disable switch on the Modules tab is the single on/off control.', 'bw-dev' ); ?>
			</p>
		</div>

		<h3><?php esc_html_e( 'What this strips', 'bw-dev' ); ?></h3>
		<ul style="list-style:disc;margin-left:20px;">
			<li><?php esc_html_e( 'Comment and trackback support is removed from every registered post type — the Discussion meta box never appears in the editor.', 'bw-dev' ); ?></li>
			<li><?php esc_html_e( 'New posts ship with comments and pings closed at the database level (default_comment_status and default_ping_status are forced to "closed").', 'bw-dev' ); ?></li>
			<li><?php esc_html_e( 'Any comment submission that slips through is rejected with a 403.', 'bw-dev' ); ?></li>
			<li><?php esc_html_e( 'The Comments admin menu, admin bar node, and Recent Comments dashboard widget are hidden.', 'bw-dev' ); ?></li>
			<li><?php esc_html_e( 'edit-comments.php and Settings → Discussion redirect back to the dashboard.', 'bw-dev' ); ?></li>
			<li><?php esc_html_e( 'No notification emails. No moderation emails. notify_post_author is forced false.', 'bw-dev' ); ?></li>
			<li><?php esc_html_e( 'The front-end comment-reply.js script is dequeued, the Recent Comments core widget is unregistered, and the comments-feed link is dropped.', 'bw-dev' ); ?></li>
		</ul>
		<?php
	}

	public function uninstall(): void {
		// No persisted state.
	}
}
