<?php
/**
 * Mute Core Emails Module
 *
 * Mute automatic emails from WordPress core.
 *
 * @package BlaminhorEssentials
 */

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

/**
 * Mute Core Emails module class
 */
class Blaminhor_Essentials_Module_Mute_Core_Emails extends Blaminhor_Essentials_Module {

	/**
	 * Module ID
	 *
	 * @var string
	 */
	protected $id = 'mute-core-emails';

	/**
	 * Module name
	 *
	 * @var string
	 */
	protected $name = 'Mute Core Emails';

	/**
	 * Initialize module
	 */
	protected function init() {
		$this->name        = __( 'Mute Core Emails', 'blaminhor-essentials' );
		$this->description = __( 'Mute automatic emails from WordPress core.', 'blaminhor-essentials' );
	}

	/**
	 * Get default settings
	 *
	 * @return array
	 */
	protected function get_default_settings() {
		return array(
			// Auto-updates notifications.
			'disable_auto_core_update_email'   => false,
			'disable_auto_plugin_update_email' => false,
			'disable_auto_theme_update_email'  => false,

			// Core update available notification.
			'disable_core_update_notification' => false,

			// User notifications.
			'disable_new_user_admin_email'        => false,
			'disable_new_user_email'              => false,
			'disable_password_change_email'       => false,
			'disable_password_change_admin_email' => false,
			'disable_email_change_email'          => false,

			// Comment notifications.
			'disable_comment_notification'     => false,
			'disable_comment_moderation'       => false,

			// Recovery mode.
			'disable_recovery_mode_email'      => false,
		);
	}

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

		// Auto-updates notifications.
		if ( $this->get_setting( 'disable_auto_core_update_email', false ) ) {
			add_filter( 'auto_core_update_send_email', '__return_false' );
		}

		if ( $this->get_setting( 'disable_auto_plugin_update_email', false ) ) {
			add_filter( 'auto_plugin_update_send_email', '__return_false' );
		}

		if ( $this->get_setting( 'disable_auto_theme_update_email', false ) ) {
			add_filter( 'auto_theme_update_send_email', '__return_false' );
		}

		// Core update available notification.
		if ( $this->get_setting( 'disable_core_update_notification', false ) ) {
			add_filter( 'send_core_update_notification_email', '__return_false' );
		}

		// User notifications.
		// We return an empty-recipient array (rather than false) so WP core does not
		// emit "Trying to access array offset on false" warnings when it reads keys
		// like ['to'] before calling wp_mail. wp_mail() with an empty 'to' silently
		// no-ops, achieving the same effect.
		if ( $this->get_setting( 'disable_new_user_admin_email', false ) ) {
			add_filter( 'wp_new_user_notification_email_admin', array( $this, 'return_empty_email_array' ), 10, 3 );
		}

		if ( $this->get_setting( 'disable_new_user_email', false ) ) {
			add_filter( 'wp_new_user_notification_email', array( $this, 'return_empty_email_array' ), 10, 3 );
		}

		if ( $this->get_setting( 'disable_password_change_email', false ) ) {
			add_filter( 'send_password_change_email', '__return_false' );
		}

		// Admin notification when a user changes their password (different from
		// the user-facing 'send_password_change_email' filter above).
		if ( $this->get_setting( 'disable_password_change_admin_email', false ) ) {
			add_filter( 'wp_password_change_notification_email', array( $this, 'return_empty_email_array' ), 10, 2 );
		}

		if ( $this->get_setting( 'disable_email_change_email', false ) ) {
			add_filter( 'send_email_change_email', '__return_false' );
		}

		// Comment notifications.
		if ( $this->get_setting( 'disable_comment_notification', false ) ) {
			add_filter( 'notify_post_author', '__return_false' );
		}

		if ( $this->get_setting( 'disable_comment_moderation', false ) ) {
			add_filter( 'notify_moderator', '__return_false' );
		}

		// Recovery mode.
		if ( $this->get_setting( 'disable_recovery_mode_email', false ) ) {
			add_filter( 'recovery_mode_email', array( $this, 'disable_recovery_email' ), 10, 2 );
		}
	}

	/**
	 * Disable recovery mode email
	 *
	 * @param array $email Email arguments.
	 * @param string $url  Recovery URL.
	 * @return bool
	 */
	public function disable_recovery_email( $email, $url ) {
		return false;
	}

	/**
	 * Return a well-formed but empty email array.
	 *
	 * Used as a callback on WP filters that expect an array shape with 'to',
	 * 'subject', 'message', 'headers' keys. Returning false here would make
	 * WP core trigger PHP warnings when it reads $arr['to'] etc.; returning
	 * this empty array keeps core warning-free while ensuring wp_mail() is
	 * called with an empty recipient and silently no-ops.
	 *
	 * @return array
	 */
	public function return_empty_email_array() {
		return array(
			'to'      => '',
			'subject' => '',
			'message' => '',
			'headers' => '',
		);
	}

	/**
	 * Enqueue module assets
	 *
	 * @param string $hook Admin page hook.
	 */
	public function enqueue_assets( $hook ) {
		if ( strpos( $hook, 'blaminhor-essentials-mute-core-emails' ) === false ) {
			return;
		}

		$config = array(
			'strings' => array(
				'unsavedChanges' => __( 'You have unsaved changes', 'blaminhor-essentials' ),
			),
		);

		wp_add_inline_script(
			'blaminhor-essentials-modules',
			'jQuery(document).ready(function($) { BlaminhorEssentialsMuteEmails.init(' . wp_json_encode( $config ) . '); });'
		);
	}

	/**
	 * Get notification groups for display
	 *
	 * @return array
	 */
	private function get_notification_groups() {
		return array(
			'auto_updates' => array(
				'title'       => __( 'Auto-Updates', 'blaminhor-essentials' ),
				'description' => __( 'Notifications sent after automatic updates.', 'blaminhor-essentials' ),
				'items'       => array(
					'disable_auto_core_update_email'   => array(
						'label'       => __( 'WordPress Core auto-update', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to admin after WordPress core auto-updates.', 'blaminhor-essentials' ),
					),
					'disable_auto_plugin_update_email' => array(
						'label'       => __( 'Plugin auto-updates', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to admin after plugins auto-update.', 'blaminhor-essentials' ),
					),
					'disable_auto_theme_update_email'  => array(
						'label'       => __( 'Theme auto-updates', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to admin after themes auto-update.', 'blaminhor-essentials' ),
					),
					'disable_core_update_notification' => array(
						'label'       => __( 'Update available notification', 'blaminhor-essentials' ),
						'description' => __( 'Email sent when a new WordPress version is available.', 'blaminhor-essentials' ),
					),
				),
			),
			'users'        => array(
				'title'       => __( 'Users', 'blaminhor-essentials' ),
				'description' => __( 'Notifications related to user accounts.', 'blaminhor-essentials' ),
				'items'       => array(
					'disable_new_user_admin_email'  => array(
						'label'       => __( 'New user (to admin)', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to admin when a new user registers.', 'blaminhor-essentials' ),
					),
					'disable_new_user_email'        => array(
						'label'       => __( 'New user (to user)', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to new user with login credentials.', 'blaminhor-essentials' ),
					),
					'disable_password_change_email' => array(
						'label'       => __( 'Password change (to user)', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to user when their password changes.', 'blaminhor-essentials' ),
					),
					'disable_password_change_admin_email' => array(
						'label'       => __( 'Password change (to admin)', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to admin when a user changes their password.', 'blaminhor-essentials' ),
					),
					'disable_email_change_email'    => array(
						'label'       => __( 'Email address change', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to user when their email address changes.', 'blaminhor-essentials' ),
					),
				),
			),
			'comments'     => array(
				'title'       => __( 'Comments', 'blaminhor-essentials' ),
				'description' => __( 'Notifications related to comments.', 'blaminhor-essentials' ),
				'items'       => array(
					'disable_comment_notification' => array(
						'label'       => __( 'New comment notification', 'blaminhor-essentials' ),
						'description' => __( 'Email sent to post author when a comment is posted.', 'blaminhor-essentials' ),
					),
					'disable_comment_moderation'   => array(
						'label'       => __( 'Comment moderation', 'blaminhor-essentials' ),
						'description' => __( 'Email sent when a comment requires moderation.', 'blaminhor-essentials' ),
					),
				),
			),
			'system'       => array(
				'title'       => __( 'System', 'blaminhor-essentials' ),
				'description' => __( 'System-related notifications.', 'blaminhor-essentials' ),
				'items'       => array(
					'disable_recovery_mode_email' => array(
						'label'       => __( 'Recovery mode', 'blaminhor-essentials' ),
						'description' => __( 'Email sent when WordPress enters recovery mode due to a fatal error.', 'blaminhor-essentials' ),
						'warning'     => __( 'Warning: Disabling this may prevent you from receiving critical error notifications.', 'blaminhor-essentials' ),
					),
				),
			),
		);
	}

	/**
	 * Count disabled notifications
	 *
	 * @return int
	 */
	private function count_disabled_notifications() {
		$count  = 0;
		$groups = $this->get_notification_groups();

		foreach ( $groups as $group ) {
			foreach ( $group['items'] as $key => $item ) {
				if ( $this->get_setting( $key, false ) ) {
					++$count;
				}
			}
		}

		return $count;
	}

	/**
	 * Count total notifications
	 *
	 * @return int
	 */
	private function count_total_notifications() {
		$count  = 0;
		$groups = $this->get_notification_groups();

		foreach ( $groups as $group ) {
			$count += count( $group['items'] );
		}

		return $count;
	}

	/**
	 * Render settings page
	 */
	public function render_settings_page() {
		$groups         = $this->get_notification_groups();
		$disabled_count = $this->count_disabled_notifications();
		$total_count    = $this->count_total_notifications();
		?>
		<div class="wrap blaminhor-essentials-wrap">
			<div class="blaminhor-essentials-header">
				<h1><?php esc_html_e( 'Mute Core Emails', 'blaminhor-essentials' ); ?></h1>
				<p class="blaminhor-essentials-tagline"><?php esc_html_e( 'Mute automatic emails from WordPress core.', 'blaminhor-essentials' ); ?></p>
			</div>

			<div class="blaminhor-essentials-card">
				<div class="ap-status-banner ap-status-info">
					<span class="dashicons dashicons-controls-volumeoff"></span>
					<span>
						<?php
						printf(
							/* translators: 1: number of muted emails, 2: total number of email types */
							esc_html__( '%1$d of %2$d email types muted.', 'blaminhor-essentials' ),
							(int) $disabled_count,
							(int) $total_count
						);
						?>
					</span>
				</div>

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

					<?php foreach ( $groups as $group_key => $group ) : ?>
						<div class="ap-notification-group">
							<h3><?php echo esc_html( $group['title'] ); ?></h3>
							<p class="description"><?php echo esc_html( $group['description'] ); ?></p>

							<table class="form-table ap-mute-table">
								<?php foreach ( $group['items'] as $setting_key => $item ) : ?>
									<tr>
										<th scope="row"><?php echo esc_html( $item['label'] ); ?></th>
										<td>
											<label class="ap-switch">
												<input type="checkbox" name="<?php echo esc_attr( $setting_key ); ?>" value="1"
													<?php checked( $this->get_setting( $setting_key, false ) ); ?>>
												<span class="ap-switch-slider"></span>
												<span class="ap-switch-label ap-switch-label-on"><?php esc_html_e( 'Muted', 'blaminhor-essentials' ); ?></span>
												<span class="ap-switch-label ap-switch-label-off"><?php esc_html_e( 'Active', 'blaminhor-essentials' ); ?></span>
											</label>
											<p class="description"><?php echo esc_html( $item['description'] ); ?></p>
											<?php if ( ! empty( $item['warning'] ) ) : ?>
												<p class="description ap-warning">
													<?php echo esc_html( $item['warning'] ); ?>
												</p>
											<?php endif; ?>
										</td>
									</tr>
								<?php endforeach; ?>
							</table>
						</div>

						<?php if ( $group_key !== array_key_last( $groups ) ) : ?>
							<hr>
						<?php endif; ?>

					<?php endforeach; ?>

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

		<div id="ap-unsaved-modal" class="ap-modal ap-hidden">
			<div class="ap-modal-backdrop"></div>
			<div class="ap-modal-content">
				<div class="ap-modal-icon">
					<span class="dashicons dashicons-warning"></span>
				</div>
				<h3><?php esc_html_e( 'Unsaved Changes', 'blaminhor-essentials' ); ?></h3>
				<p><?php esc_html_e( 'You have unsaved changes. Do you want to leave without saving?', 'blaminhor-essentials' ); ?></p>
				<div class="ap-modal-buttons">
					<button type="button" class="button ap-modal-cancel"><?php esc_html_e( 'Stay on Page', 'blaminhor-essentials' ); ?></button>
					<button type="button" class="button button-primary ap-modal-leave"><?php esc_html_e( 'Leave Without Saving', 'blaminhor-essentials' ); ?></button>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Process settings
	 *
	 * @param array $data Form data.
	 */
	protected function process_settings( $data ) {
		$groups   = $this->get_notification_groups();
		$settings = array();

		// Process each setting from groups.
		foreach ( $groups as $group ) {
			foreach ( $group['items'] as $key => $item ) {
				$settings[ $key ] = isset( $data[ $key ] );
			}
		}

		$this->save_settings( $settings );

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