<?php
/**
 * Email Health admin page.
 *
 * @package SubmissionInbox
 */

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

/**
 * Renders the action-first Email Health diagnostic workspace.
 */
class SUBIN_EmailStatusPage {
	const PAGE_SLUG = 'subin-email-status';
	const ACTION_FIELD = 'subin_health_action';
	const VERIFY_ACTION = 'subin_verify_email_health';
	const VERIFY_NONCE  = 'subin_email_health_nonce';

	/** @var \SUBIN\Mail\EmailErrorClassifier */
	private $error_classifier;

	/** @var \SUBIN\Mail\EmailHealthService */
	private $health;

	/** @var \SUBIN\Mail\EmailVerificationService */
	private $verification;

	/** @var \SUBIN\Mail\EmailHealthDiagnosticService */
	private $diagnostics;

	/** @var array<string,mixed> */
	private $active_filters = array();

	/** Constructor. */
	public function __construct() {
		$this->error_classifier = new \SUBIN\Mail\EmailErrorClassifier();
		$this->health           = new \SUBIN\Mail\EmailHealthService( $this->error_classifier );
		$settings               = new SUBIN_SettingsRepository();
		$this->verification     = new \SUBIN\Mail\EmailVerificationService( $settings, $this->error_classifier );
		$this->diagnostics      = new \SUBIN\Mail\EmailHealthDiagnosticService( $settings, $this->health, $this->verification );
	}

	/** Handle nonce-protected Email Health actions before admin output. */
	public function handle_request() {
		$method = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ?? '' ) ) );
		if ( 'POST' !== $method ) {
			return;
		}
		if ( ! \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::VIEW_EMAIL_HEALTH ) ) {
			wp_die( esc_html__( 'You do not have permission to perform this action.', 'submission-inbox' ) );
		}

		$action          = sanitize_key( wp_unslash( $_POST[ self::ACTION_FIELD ] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- The allowlisted action selects the nonce-protected handler below.
		$allowed_actions = array( 'verify', 'confirm_received', 'confirm_not_received' );
		if ( ! in_array( $action, $allowed_actions, true ) ) {
			return;
		}
		if ( ! \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::SEND_TEST_EMAILS ) ) {
			wp_die( esc_html__( 'You do not have permission to send verification emails.', 'submission-inbox' ) );
		}

		$nonce = sanitize_text_field( wp_unslash( $_POST[ self::VERIFY_NONCE ] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified on the next line.
		if ( '' === $nonce || ! wp_verify_nonce( $nonce, self::VERIFY_ACTION ) ) {
			SUBIN_AdminNotices::flash( __( 'Security check failed. Reload Email Health and try again.', 'submission-inbox' ), 'error', 'health_verification_nonce' );
			$this->redirect_after_action();
		}

		if ( 'verify' === $action ) {
			$recipient = wp_unslash( $_POST['subin_verification_recipient'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce is verified above; service validates the scalar email address.
			$result    = $this->verification->send( $recipient, get_current_user_id() );
			if ( is_wp_error( $result ) ) {
				SUBIN_AdminNotices::flash( $result->get_error_message(), 'error', $result->get_error_code() );
			} else {
				SUBIN_AdminNotices::flash( $result['message'], 'success', 'health_verification_accepted' );
			}
		} else {
			$received = 'confirm_received' === $action;
			$result   = $this->verification->confirm_arrival( $received );
			if ( is_wp_error( $result ) ) {
				SUBIN_AdminNotices::flash( $result->get_error_message(), 'error', $result->get_error_code() );
			} elseif ( $received ) {
				SUBIN_AdminNotices::flash( __( 'Delivery confirmed. This verifies the full route to your mailbox for this test.', 'submission-inbox' ), 'success', 'health_verification_received' );
			} else {
				SUBIN_AdminNotices::flash( __( 'The handoff succeeded but the message did not arrive. Check spam and sender authentication, then inspect Email Log or run another test.', 'submission-inbox' ), 'warning', 'health_verification_not_received' );
			}
		}
		$this->redirect_after_action();
	}

	/** Render page. */
	public function render() {
		if ( ! \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::VIEW_EMAIL_HEALTH ) ) {
			wp_die( esc_html__( 'You do not have permission to perform this action.', 'submission-inbox' ) );
		}

		$filters              = $this->filters_from_request();
		$this->active_filters = $filters;
		$report               = $this->health->build_report( $filters );
		$global_signal        = $this->health->current_signal();
		$global_incidents     = $this->health->current_incidents( array( 'date_range' => '30' ), 8 );
		$checks               = $this->diagnostics->checks();
		$can_view_log         = \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::VIEW_EMAIL_LOG );
		$can_manage_sending   = \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::MANAGE_SENDING );
		$can_send_test        = \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::SEND_TEST_EMAILS );
		$header               = array( 'wrapper_class' => 'subin-email-status-page subin-email-health-page' );
		if ( $can_view_log ) {
			$header['primary_action'] = array(
				'label' => __( 'View Email Log', 'submission-inbox' ),
				'url'   => $this->email_log_url( array(), false ),
			);
		}
		if ( $can_manage_sending ) {
			$header['secondary_actions'] = array(
				array(
					'label' => __( 'SMTP Settings', 'submission-inbox' ),
					'url'   => $this->sending_settings_url(),
				),
			);
		}

		SUBIN_View::page_header(
			__( 'Email Health', 'submission-inbox' ),
			__( 'Find active sending problems, fix the cause, and confirm that email is working again.', 'submission-inbox' ),
			$header
		);

		$this->render_health_overview( $global_signal, $can_view_log );
		if ( empty( $global_signal['total'] ) ) {
			$this->render_no_data_guidance();
		} else {
			$this->render_issues( $global_incidents, $global_signal, $can_view_log, $can_manage_sending );
		}

		?><div class="subin-health-remediation-grid"><?php
		$this->render_verification( $can_send_test, $can_view_log );
		$this->render_diagnostic_checks( $checks, $can_view_log, $can_manage_sending, $can_send_test );
		?></div><?php

		$this->render_activity_history( $report, $can_view_log );
		$this->render_support_report( $report, $checks );
		SUBIN_View::page_footer();
	}

	/** Read and normalize report filters. */
	private function filters_from_request() {
		$source     = $this->health->normalize_source( SUBIN_Request::get_key( 'subin_source' ) );
		$date_range = SUBIN_Request::get_key( 'subin_date_range', '30' );
		$form_key   = sanitize_text_field( wp_unslash( $_GET['subin_form'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only report filter.
		$provider   = '';
		$form_id    = '';
		if ( false !== strpos( $form_key, ':' ) ) {
			list( $provider, $form_id ) = array_pad( explode( ':', $form_key, 2 ), 2, '' );
		}
		if ( '' === $form_id ) {
			$form_id = sanitize_text_field( wp_unslash( $_GET['subin_form_id'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Backward-compatible read-only report filter.
			if ( '' !== $form_id && '' === $provider ) {
				$provider = 'submission_inbox_form';
			}
		}

		return array(
			'source'     => $source,
			'date_range' => in_array( $date_range, array( '7', '30', '90', 'all', 'custom' ), true ) ? $date_range : '30',
			'date_from'  => sanitize_text_field( wp_unslash( $_GET['subin_date_from'] ?? '' ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only report filter.
			'date_to'    => sanitize_text_field( wp_unslash( $_GET['subin_date_to'] ?? '' ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only report filter.
			'provider'   => sanitize_key( $provider ),
			'form_id'    => sanitize_text_field( $form_id ),
			'form_key'   => '' !== $provider && '' !== $form_id ? sanitize_key( $provider ) . ':' . sanitize_text_field( $form_id ) : '',
			'status'     => SUBIN_Request::get_key( 'subin_status' ),
		);
	}

	/** Render source, form, outcome, and period filters. */
	private function render_filters( array $report ) {
		$filters      = (array) ( $report['filters'] ?? array() );
		$form_options = (array) ( $report['form_options'] ?? array() );
		$form_key     = '' !== (string) ( $filters['provider'] ?? '' ) && '' !== (string) ( $filters['form_id'] ?? '' )
			? (string) $filters['provider'] . ':' . (string) $filters['form_id']
			: '';
		$custom_open  = 'custom' === ( $filters['date_range'] ?? '' ) || ! empty( $filters['date_from'] ) || ! empty( $filters['date_to'] );
		$is_default   = $this->filters_are_default( $filters );
		?>
		<details class="subin-filter-panel subin-health-filters"<?php echo $is_default ? '' : ' open'; ?>>
			<summary class="subin-health-filters__summary">
				<span><strong><?php esc_html_e( 'Filter activity', 'submission-inbox' ); ?></strong><small><?php echo esc_html( $this->filter_scope_label( $filters, $form_options ) ); ?></small></span>
				<span class="subin-health-filters__control"><?php echo $is_default ? esc_html__( 'Optional', 'submission-inbox' ) : esc_html__( 'Filters applied', 'submission-inbox' ); ?></span>
			</summary>
			<form method="get" action="<?php echo esc_url( admin_url( 'admin.php#subin-health-activity' ) ); ?>" class="subin-filter-form">
				<input type="hidden" name="page" value="<?php echo esc_attr( self::PAGE_SLUG ); ?>" />
				<div class="subin-filter-main subin-filter-main--health">
					<div class="subin-filter-field">
						<label for="subin-email-health-source"><?php esc_html_e( 'Source', 'submission-inbox' ); ?></label>
						<select id="subin-email-health-source" name="subin_source">
							<option value=""><?php esc_html_e( 'All active sources', 'submission-inbox' ); ?></option>
							<?php foreach ( $this->health->source_labels() as $key => $label ) : ?>
								<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $filters['source'] ?? '', $key ); ?>><?php echo esc_html( $label ); ?></option>
							<?php endforeach; ?>
						</select>
					</div>
					<div class="subin-filter-field">
						<label for="subin-email-health-form"><?php esc_html_e( 'Form', 'submission-inbox' ); ?></label>
						<select id="subin-email-health-form" name="subin_form">
							<option value=""><?php esc_html_e( 'All forms', 'submission-inbox' ); ?></option>
							<?php foreach ( $form_options as $form ) : ?>
								<option value="<?php echo esc_attr( (string) ( $form['key'] ?? '' ) ); ?>" <?php selected( $form_key, (string) ( $form['key'] ?? '' ) ); ?>><?php echo esc_html( (string) ( $form['label'] ?? '' ) ); ?></option>
							<?php endforeach; ?>
						</select>
					</div>
					<div class="subin-filter-field">
						<label for="subin-email-health-status"><?php esc_html_e( 'Outcome', 'submission-inbox' ); ?></label>
						<select id="subin-email-health-status" name="subin_status">
							<option value=""><?php esc_html_e( 'All outcomes', 'submission-inbox' ); ?></option>
							<option value="sent" <?php selected( $filters['status'] ?? '', 'sent' ); ?>><?php esc_html_e( 'Accepted by WordPress', 'submission-inbox' ); ?></option>
							<option value="failed" <?php selected( $filters['status'] ?? '', 'failed' ); ?>><?php esc_html_e( 'Failed', 'submission-inbox' ); ?></option>
							<option value="no_email_generated" <?php selected( $filters['status'] ?? '', 'no_email_generated' ); ?>><?php esc_html_e( 'No email generated', 'submission-inbox' ); ?></option>
							<option value="unknown" <?php selected( $filters['status'] ?? '', 'unknown' ); ?>><?php esc_html_e( 'Unknown or pending', 'submission-inbox' ); ?></option>
						</select>
					</div>
					<div class="subin-filter-field">
						<label for="subin-email-health-range"><?php esc_html_e( 'Period', 'submission-inbox' ); ?></label>
						<select id="subin-email-health-range" name="subin_date_range">
							<option value="7" <?php selected( $filters['date_range'] ?? '', '7' ); ?>><?php esc_html_e( 'Last 7 days', 'submission-inbox' ); ?></option>
							<option value="30" <?php selected( $filters['date_range'] ?? '', '30' ); ?>><?php esc_html_e( 'Last 30 days', 'submission-inbox' ); ?></option>
							<option value="90" <?php selected( $filters['date_range'] ?? '', '90' ); ?>><?php esc_html_e( 'Last 90 days', 'submission-inbox' ); ?></option>
							<option value="all" <?php selected( $filters['date_range'] ?? '', 'all' ); ?>><?php esc_html_e( 'All time', 'submission-inbox' ); ?></option>
							<option value="custom" <?php selected( $filters['date_range'] ?? '', 'custom' ); ?>><?php esc_html_e( 'Custom dates', 'submission-inbox' ); ?></option>
						</select>
					</div>
					<div class="subin-filter-actions">
						<button type="submit" class="button subin-btn subin-btn-primary"><?php esc_html_e( 'Apply', 'submission-inbox' ); ?></button>
						<?php if ( ! $is_default ) : ?><a class="button subin-btn" href="<?php echo esc_url( admin_url( 'admin.php?page=' . self::PAGE_SLUG . '#subin-health-activity' ) ); ?>"><?php esc_html_e( 'Reset', 'submission-inbox' ); ?></a><?php endif; ?>
					</div>
				</div>
				<details class="subin-advanced-filters subin-filter-advanced subin-health-custom-dates"<?php echo $custom_open ? ' open' : ''; ?>>
					<summary class="subin-filter-toggle"><?php esc_html_e( 'Custom date range', 'submission-inbox' ); ?></summary>
					<div class="subin-advanced-filters__grid">
						<div class="subin-filter-field"><label for="subin-health-date-from"><?php esc_html_e( 'From', 'submission-inbox' ); ?></label><input type="date" id="subin-health-date-from" name="subin_date_from" value="<?php echo esc_attr( (string) ( $filters['date_from'] ?? '' ) ); ?>" /></div>
						<div class="subin-filter-field"><label for="subin-health-date-to"><?php esc_html_e( 'To', 'submission-inbox' ); ?></label><input type="date" id="subin-health-date-to" name="subin_date_to" value="<?php echo esc_attr( (string) ( $filters['date_to'] ?? '' ) ); ?>" /></div>
					</div>
				</details>
			</form>
		</details>
		<?php
	}

	/** Whether the activity view is using its intentionally quiet default scope. */
	private function filters_are_default( array $filters ) {
		return empty( $filters['source'] )
			&& empty( $filters['provider'] )
			&& empty( $filters['form_id'] )
			&& empty( $filters['status'] )
			&& empty( $filters['date_from'] )
			&& empty( $filters['date_to'] )
			&& '30' === (string) ( $filters['date_range'] ?? '30' );
	}

	/** Describe the selected activity filters without making them look global. */
	private function filter_scope_label( array $filters, array $form_options ) {
		if ( $this->filters_are_default( $filters ) ) {
			return __( 'All email activity · Last 30 days', 'submission-inbox' );
		}

		$source_labels = $this->health->source_labels();
		$source        = sanitize_key( $filters['source'] ?? '' );
		$form_key      = sanitize_key( $filters['provider'] ?? '' ) . ':' . sanitize_text_field( $filters['form_id'] ?? '' );
		$form_label    = '';
		foreach ( $form_options as $form ) {
			if ( $form_key === (string) ( $form['key'] ?? '' ) ) {
				$form_label = sanitize_text_field( $form['label'] ?? '' );
				break;
			}
		}
		$status_labels = array(
			'sent'               => __( 'Accepted only', 'submission-inbox' ),
			'failed'             => __( 'Failed only', 'submission-inbox' ),
			'no_email_generated' => __( 'Missing notifications', 'submission-inbox' ),
			'unknown'            => __( 'Unknown or pending', 'submission-inbox' ),
		);
		$range_labels = array(
			'7'   => __( 'Last 7 days', 'submission-inbox' ),
			'30'  => __( 'Last 30 days', 'submission-inbox' ),
			'90'  => __( 'Last 90 days', 'submission-inbox' ),
			'all' => __( 'All time', 'submission-inbox' ),
		);
		$parts = array();
		if ( '' !== $source ) {
			$parts[] = $source_labels[ $source ] ?? __( 'Selected source', 'submission-inbox' );
		}
		if ( '' !== $form_label ) {
			$parts[] = $form_label;
		}
		$status = sanitize_key( $filters['status'] ?? '' );
		if ( isset( $status_labels[ $status ] ) ) {
			$parts[] = $status_labels[ $status ];
		}
		$range = (string) ( $filters['date_range'] ?? '30' );
		if ( 'custom' === $range ) {
			/* translators: %1$s: start date, %2$s: end date. */
			$parts[] = sprintf( __( '%1$s to %2$s', 'submission-inbox' ), sanitize_text_field( $filters['date_from'] ?? '' ), sanitize_text_field( $filters['date_to'] ?? '' ) );
		} else {
			$parts[] = $range_labels[ $range ] ?? $range_labels['30'];
		}

		return implode( ' · ', array_filter( $parts ) );
	}

	/** Render the site-wide signal that exactly explains the admin-menu badge. */
	private function render_health_overview( array $signal, $can_view_log ) {
		$state            = sanitize_key( $signal['state'] ?? \SUBIN\Mail\EmailHealthService::STATE_UNKNOWN );
		$active_count     = absint( $signal['active_issue_count'] ?? 0 );
		$recovering_count = absint( $signal['recovering_issue_count'] ?? 0 );
		$focus_recovering = 0 === $active_count && $recovering_count > 0;
		$affected_count   = absint( $signal[ $focus_recovering ? 'recovering_source_count' : 'affected_source_count' ] ?? 0 );
		$problem_count    = absint( $signal[ $focus_recovering ? 'recovering_event_count' : 'problem_event_count' ] ?? 0 );
		$is_lower_bound   = ! empty( $signal['count_is_lower_bound'] );
		$count_suffix     = $is_lower_bound ? '+' : '';
		$last_success     = sanitize_text_field( $signal['last_success_at'] ?? '' );
		$last_problem     = sanitize_text_field( $signal['last_problem_at'] ?? '' );
		$latest_at        = $last_success > $last_problem ? $last_success : $last_problem;
		$content          = $this->overview_content( $state, $signal );
		?>
		<section class="subin-health-overview subin-health-overview--<?php echo esc_attr( $state ); ?>" data-health-scope="global" aria-labelledby="subin-health-overview-title">
			<div class="subin-health-overview__signal" aria-hidden="true"><span class="dashicons <?php echo esc_attr( $this->state_icon( $state ) ); ?>"></span></div>
			<div class="subin-health-overview__content">
				<div class="subin-health-overview__heading">
					<div><span class="subin-health-eyebrow"><?php esc_html_e( 'Detect · Site-wide status · Last 30 days', 'submission-inbox' ); ?></span><h2 id="subin-health-overview-title"><?php echo esc_html( $content['title'] ); ?></h2></div>
					<?php SUBIN_View::badge( $this->state_label( $state ), $this->state_badge_type( $state ) ); ?>
				</div>
				<p class="subin-health-overview__message"><?php echo esc_html( $content['message'] ); ?></p>
				<p class="subin-health-overview__badge-help"><span class="dashicons dashicons-info-outline" aria-hidden="true"></span><?php esc_html_e( 'The number beside Email Health in the WordPress menu is the Active issues value shown here. Repeated failures with the same cause are grouped into one issue.', 'submission-inbox' ); ?></p>
				<div class="subin-health-actions">
					<?php if ( $active_count + $recovering_count > 0 ) : ?><a class="button button-primary subin-btn subin-btn-primary" href="#subin-health-incidents"><?php esc_html_e( 'Review issues', 'submission-inbox' ); ?></a><?php else : ?><a class="button button-primary subin-btn subin-btn-primary" href="#subin-health-verify"><?php esc_html_e( 'Run verification', 'submission-inbox' ); ?></a><?php endif; ?>
					<?php if ( $can_view_log && ! empty( $signal['total'] ) ) : ?><a class="button subin-btn" href="<?php echo esc_url( $this->email_log_url( array(), false ) ); ?>"><?php esc_html_e( 'View 30-day Email Log', 'submission-inbox' ); ?></a><?php endif; ?>
				</div>
			</div>
			<dl class="subin-health-overview__facts">
				<div class="subin-health-overview__primary-fact"><dt><?php esc_html_e( 'Active issues', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( number_format_i18n( $active_count ) . $count_suffix ); ?></dd><small><?php esc_html_e( 'Matches the menu badge', 'submission-inbox' ); ?></small></div>
				<div><dt><?php esc_html_e( 'Affected sources', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( number_format_i18n( $affected_count ) . $count_suffix ); ?></dd><small><?php echo esc_html( $focus_recovering ? __( 'Sources currently in recovery', 'submission-inbox' ) : __( 'Unique sources with active issues', 'submission-inbox' ) ); ?></small></div>
				<div><dt><?php esc_html_e( 'Problem attempts', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( number_format_i18n( $problem_count ) . $count_suffix ); ?></dd><small><?php echo esc_html( $focus_recovering ? __( 'History behind recovering issues', 'submission-inbox' ) : __( 'Grouped under active issues', 'submission-inbox' ) ); ?></small></div>
				<div><dt><?php esc_html_e( 'Last activity', 'submission-inbox' ); ?></dt><dd class="subin-health-overview__date"><?php echo esc_html( $latest_at ? $this->format_date( $latest_at ) : __( 'No events yet', 'submission-inbox' ) ); ?></dd><small><?php esc_html_e( 'Rolling 30-day window', 'submission-inbox' ); ?></small></div>
			</dl>
			<?php if ( $is_lower_bound ) : ?><p class="subin-health-overview__limit"><?php esc_html_e( 'High-volume site: counts marked “+” are minimums from the bounded diagnostic window. Email Log remains the complete event history.', 'submission-inbox' ); ?></p><?php endif; ?>
		</section>
		<?php
	}

	/** Render deterministic configuration checks without performing network work. */
	private function render_diagnostic_checks( array $checks, $can_view_log, $can_manage_sending, $can_send_test ) {
		$counts = array( 'pass' => 0, 'warning' => 0, 'fail' => 0, 'info' => 0 );
		foreach ( $checks as $check ) {
			$status = sanitize_key( $check['status'] ?? 'info' );
			$status = isset( $counts[ $status ] ) ? $status : 'info';
			++$counts[ $status ];
		}
		$needs_attention = $counts['fail'] + $counts['warning'] > 0;
		?>
			<details class="subin-health-section subin-health-diagnostics"<?php echo $needs_attention ? ' open' : ''; ?>>
				<summary class="subin-health-diagnostics__summary">
					<span><span class="subin-health-eyebrow"><?php esc_html_e( 'Configuration', 'submission-inbox' ); ?></span><strong id="subin-health-diagnostics-title"><?php esc_html_e( 'Configuration checks', 'submission-inbox' ); ?></strong><small><?php esc_html_e( 'Local configuration clues—not a live SMTP or DNS test.', 'submission-inbox' ); ?></small></span>
					<?php /* translators: %1$d: total checks, %2$d: passed checks, %3$d: checks needing review, %4$d: informational checks. */ ?>
					<span class="subin-health-check-counts"><?php echo esc_html( sprintf( __( '%1$d checks · %2$d passed · %3$d review · %4$d info', 'submission-inbox' ), count( $checks ), $counts['pass'], $counts['fail'] + $counts['warning'], $counts['info'] ) ); ?></span>
			</summary>
			<div class="subin-health-checks">
				<?php foreach ( $checks as $check ) : ?>
					<div class="subin-health-check subin-health-check--<?php echo esc_attr( sanitize_key( $check['status'] ?? 'info' ) ); ?>">
						<span class="subin-health-check__icon dashicons <?php echo esc_attr( $this->check_icon( $check['status'] ?? '' ) ); ?>" aria-hidden="true"></span>
						<div class="subin-health-check__content"><div><strong><?php echo esc_html( $check['title'] ?? '' ); ?></strong><?php SUBIN_View::badge( $this->check_status_label( $check['status'] ?? '' ), $this->check_badge_type( $check['status'] ?? '' ) ); ?></div><p><?php echo esc_html( $check['message'] ?? '' ); ?></p></div>
						<div class="subin-health-check__action"><?php $this->render_check_action( $check['action'] ?? '', $can_view_log, $can_manage_sending, $can_send_test ); ?></div>
					</div>
				<?php endforeach; ?>
			</div>
		</details>
		<?php
	}

	/** Render a verification test using the same wp_mail path as Settings. */
	private function render_verification( $can_send_test, $can_view_log ) {
		$last         = $this->verification->last_result();
		$status       = sanitize_key( $last['status'] ?? '' );
		$confirmation = sanitize_key( $last['confirmation'] ?? '' );
		$confirm_open = $last && 'accepted' === $status && $this->verification_confirmation_is_open( $last );
		$send_step    = $last ? 'done' : 'current';
		$handoff_step = 'accepted' === $status ? 'done' : ( 'failed' === $status ? 'failed' : 'pending' );
		$inbox_step   = 'received' === $confirmation ? 'done' : ( 'not_received' === $confirmation ? 'failed' : ( 'awaiting' === $confirmation ? 'current' : 'pending' ) );
		?>
		<section id="subin-health-verify" class="subin-health-section subin-health-verify" aria-labelledby="subin-health-verify-title">
			<div class="subin-health-verify__copy">
				<span class="subin-health-eyebrow"><?php esc_html_e( 'Verify · Confirm', 'submission-inbox' ); ?></span>
				<h2 id="subin-health-verify-title"><?php esc_html_e( 'Test the real email route', 'submission-inbox' ); ?></h2>
				<p><?php esc_html_e( 'First send through the current WordPress mail path. Then confirm whether the message reached the mailbox. The test is recorded in Email Log.', 'submission-inbox' ); ?></p>
				<ol class="subin-health-verify-steps" aria-label="<?php esc_attr_e( 'Verification progress', 'submission-inbox' ); ?>">
					<li class="is-<?php echo esc_attr( $send_step ); ?>"<?php echo 'current' === $send_step ? ' aria-current="step"' : ''; ?>><span>1</span><div><strong><?php esc_html_e( 'Send', 'submission-inbox' ); ?></strong><small><?php esc_html_e( 'Use the live WordPress path', 'submission-inbox' ); ?></small></div></li>
					<li class="is-<?php echo esc_attr( $handoff_step ); ?>"<?php echo 'current' === $handoff_step ? ' aria-current="step"' : ''; ?>><span>2</span><div><strong><?php esc_html_e( 'Handoff', 'submission-inbox' ); ?></strong><small><?php esc_html_e( 'WordPress accepts or rejects', 'submission-inbox' ); ?></small></div></li>
					<li class="is-<?php echo esc_attr( $inbox_step ); ?>"<?php echo 'current' === $inbox_step ? ' aria-current="step"' : ''; ?>><span>3</span><div><strong><?php esc_html_e( 'Confirm', 'submission-inbox' ); ?></strong><small><?php esc_html_e( 'Record actual mailbox arrival', 'submission-inbox' ); ?></small></div></li>
				</ol>
				<?php if ( $last ) : ?>
					<div class="subin-health-last-test subin-health-last-test--<?php echo esc_attr( 'accepted' === $status ? $confirmation : 'failed' ); ?>">
						<span class="dashicons <?php echo esc_attr( $this->verification_icon( $status, $confirmation ) ); ?>" aria-hidden="true"></span>
						<div>
								<strong><?php echo esc_html( $this->verification_result_title( $status, $confirmation ) ); ?></strong>
								<small><?php echo esc_html( $this->format_gmt_date( $last['tested_at_gmt'] ?? '' ) ); ?> · <?php echo esc_html( 'smtp' === ( $last['transport'] ?? '' ) ? __( 'InboxMend SMTP', 'submission-inbox' ) : __( 'WordPress default mail', 'submission-inbox' ) ); ?></small>
								<?php /* translators: %s: date and time when the mailbox result was recorded. */ ?>
								<?php if ( ! empty( $last['confirmed_at_gmt'] ) ) : ?><small><?php echo esc_html( sprintf( __( 'Mailbox result recorded %s', 'submission-inbox' ), $this->format_gmt_date( $last['confirmed_at_gmt'] ) ) ); ?></small><?php endif; ?>
							<p><?php echo esc_html( $this->verification_result_message( $status, $confirmation ) ); ?></p>
							<?php if ( ! empty( $last['issue_title'] ) ) : ?><p><strong><?php echo esc_html( $last['issue_title'] ); ?></strong></p><?php endif; ?>
						</div>
					</div>
					<?php if ( $can_send_test && $confirm_open && 'awaiting' === $confirmation ) : ?>
						<form method="post" action="" class="subin-health-confirmation" aria-label="<?php esc_attr_e( 'Confirm verification email delivery', 'submission-inbox' ); ?>">
							<?php wp_nonce_field( self::VERIFY_ACTION, self::VERIFY_NONCE ); ?>
							<span><?php esc_html_e( 'Did this verification message reach the mailbox?', 'submission-inbox' ); ?></span>
							<div><button type="submit" name="<?php echo esc_attr( self::ACTION_FIELD ); ?>" value="confirm_received" class="button subin-btn"><?php esc_html_e( 'Yes, it arrived', 'submission-inbox' ); ?></button><button type="submit" name="<?php echo esc_attr( self::ACTION_FIELD ); ?>" value="confirm_not_received" class="button subin-btn"><?php esc_html_e( 'No, it did not arrive', 'submission-inbox' ); ?></button></div>
						</form>
					<?php elseif ( $can_send_test && $confirm_open && 'not_received' === $confirmation ) : ?>
						<form method="post" action="" class="subin-health-confirmation subin-health-confirmation--update">
							<?php wp_nonce_field( self::VERIFY_ACTION, self::VERIFY_NONCE ); ?>
							<span><?php esc_html_e( 'Found the message later in spam or another folder?', 'submission-inbox' ); ?></span>
							<button type="submit" name="<?php echo esc_attr( self::ACTION_FIELD ); ?>" value="confirm_received" class="button subin-btn"><?php esc_html_e( 'Mark as arrived', 'submission-inbox' ); ?></button>
						</form>
					<?php elseif ( 'accepted' === $status && ! $confirm_open ) : ?>
						<p class="subin-health-verify__expired"><?php esc_html_e( 'This result is too old to confirm. Send a new verification below.', 'submission-inbox' ); ?></p>
					<?php endif; ?>
					<?php if ( ! empty( $last['technical_error'] ) ) : ?><details class="subin-health-technical"><summary><?php esc_html_e( 'Last test technical details', 'submission-inbox' ); ?></summary><pre><?php echo esc_html( $last['technical_error'] ); ?></pre></details><?php endif; ?>
				<?php else : ?>
					<p class="subin-health-verify__never"><?php esc_html_e( 'No verification has been run yet. This is the fastest way to create real delivery evidence.', 'submission-inbox' ); ?></p>
				<?php endif; ?>
			</div>
			<div class="subin-health-verify__form">
				<?php if ( $can_send_test ) : ?>
					<form method="post" action="">
						<input type="hidden" name="<?php echo esc_attr( self::ACTION_FIELD ); ?>" value="verify" />
						<?php wp_nonce_field( self::VERIFY_ACTION, self::VERIFY_NONCE ); ?>
						<label for="subin-verification-recipient"><?php esc_html_e( 'Mailbox to verify', 'submission-inbox' ); ?></label>
						<input type="email" id="subin-verification-recipient" name="subin_verification_recipient" autocomplete="email" placeholder="name@example.com" required />
						<button type="submit" class="button button-primary subin-btn subin-btn-primary"><?php esc_html_e( 'Send verification email', 'submission-inbox' ); ?></button>
						<small><?php esc_html_e( 'One request per user per minute. The mailbox address is used for this send and is not stored in Email Health.', 'submission-inbox' ); ?></small>
					</form>
				<?php else : ?>
					<p><?php esc_html_e( 'Your role can review Email Health but cannot send test emails. Ask a site administrator or a teammate with test-email access.', 'submission-inbox' ); ?></p>
				<?php endif; ?>
				<?php if ( $can_view_log ) : ?><a class="subin-health-verify__log" href="<?php echo esc_url( $this->email_log_url() ); ?>"><?php esc_html_e( 'Open verification history in Email Log', 'submission-inbox' ); ?></a><?php endif; ?>
			</div>
		</section>
		<?php
	}

	/** Whether the latest accepted verification can still receive mailbox evidence. */
	private function verification_confirmation_is_open( array $result ) {
		$tested_at = sanitize_text_field( $result['tested_at_gmt'] ?? '' );
		if ( ! preg_match( '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $tested_at ) ) {
			return false;
		}
		$timestamp = strtotime( $tested_at . ' UTC' );
		$now       = time();

		return false !== $timestamp && $timestamp <= $now && $timestamp >= $now - \SUBIN\Mail\EmailVerificationService::CONFIRMATION_WINDOW_SECONDS;
	}

	/** Concise verification outcome title. */
	private function verification_result_title( $status, $confirmation ) {
		if ( 'failed' === $status ) {
			return __( 'The last verification failed', 'submission-inbox' );
		}
		$labels = array(
			'received'     => __( 'Mailbox delivery confirmed', 'submission-inbox' ),
			'not_received' => __( 'Handoff succeeded, but delivery was not confirmed', 'submission-inbox' ),
			'awaiting'     => __( 'WordPress accepted the verification', 'submission-inbox' ),
		);

		return $labels[ sanitize_key( $confirmation ) ] ?? $labels['awaiting'];
	}

	/** Explain the distinction between handoff and confirmed arrival. */
	private function verification_result_message( $status, $confirmation ) {
		if ( 'failed' === $status ) {
			return __( 'WordPress could not hand the message to the configured mail transport. Fix the reported cause before checking the mailbox.', 'submission-inbox' );
		}
		$messages = array(
			'received'     => __( 'You confirmed that this test reached the mailbox, which verifies the complete route for this message.', 'submission-inbox' ),
			'not_received' => __( 'WordPress completed its handoff, but the message was not found in the mailbox. Check spam, sender authentication, and provider filtering.', 'submission-inbox' ),
			'awaiting'     => __( 'The handoff is complete. Check the destination mailbox and record what actually happened.', 'submission-inbox' ),
		);

		return $messages[ sanitize_key( $confirmation ) ] ?? $messages['awaiting'];
	}

	/** Verification outcome icon. */
	private function verification_icon( $status, $confirmation ) {
		if ( 'failed' === $status || 'not_received' === $confirmation ) {
			return 'dashicons-warning';
		}
		if ( 'received' === $confirmation ) {
			return 'dashicons-yes-alt';
		}

		return 'dashicons-email-alt';
	}

	/** Render a redacted, copyable support report under progressive disclosure. */
	private function render_support_report( array $report, array $checks ) {
		$support_report = $this->diagnostics->support_report( $report, $checks );
		?>
		<details class="subin-health-support">
			<summary><?php esc_html_e( 'Support report', 'submission-inbox' ); ?></summary>
			<div class="subin-health-support__body">
				<p><?php esc_html_e( 'Use this redacted report when asking for help. It excludes recipients, message content, SMTP host, username, and password.', 'submission-inbox' ); ?></p>
				<textarea id="subin-health-support-report" rows="12" readonly><?php echo esc_textarea( $support_report ); ?></textarea>
				<div><button type="button" class="button subin-btn" data-subin-copy-report="subin-health-support-report" data-subin-copied-label="<?php esc_attr_e( 'Copied', 'submission-inbox' ); ?>" data-subin-manual-label="<?php esc_attr_e( 'Select and copy the report manually', 'submission-inbox' ); ?>"><?php esc_html_e( 'Copy report', 'submission-inbox' ); ?></button><span class="subin-copy-feedback" aria-live="polite"></span></div>
			</div>
		</details>
		<?php
	}

	/** Explain a globally empty dataset without calling it healthy. */
	private function render_no_data_guidance() {
		?>
		<section class="subin-health-no-data">
			<span class="dashicons dashicons-chart-line" aria-hidden="true"></span>
			<div><h2><?php esc_html_e( 'Build the first health baseline', 'submission-inbox' ); ?></h2><p><?php esc_html_e( 'No data is different from healthy. Send a verification email now, then let normal form and WordPress email activity build the baseline.', 'submission-inbox' ); ?></p></div>
			<a class="button subin-btn" href="#subin-health-verify"><?php esc_html_e( 'Start verification', 'submission-inbox' ); ?></a>
		</section>
		<?php
	}

	/** Render filterable history separately from the fixed site-wide assessment. */
	private function render_activity_history( array $report, $can_view_log ) {
		$has_activity = ! empty( $report['summary']['total'] );
		?>
		<section id="subin-health-activity" class="subin-health-activity" data-health-scope="filtered" aria-labelledby="subin-health-activity-title">
			<div class="subin-health-activity__heading">
				<div><span class="subin-health-eyebrow"><?php esc_html_e( 'Explore', 'submission-inbox' ); ?></span><h2 id="subin-health-activity-title"><?php esc_html_e( 'Activity history', 'submission-inbox' ); ?></h2><p><?php esc_html_e( 'Use filters to investigate outcomes. These controls change the analytics below, never the site-wide status or menu badge above.', 'submission-inbox' ); ?></p></div>
				<span class="subin-health-scope-badge"><?php esc_html_e( 'Filtered view', 'submission-inbox' ); ?></span>
			</div>
			<?php $this->render_filters( $report ); ?>
			<?php if ( $has_activity ) : ?>
				<div class="subin-health-analytics-grid">
					<?php $this->render_metrics( $report, $can_view_log ); ?>
					<?php $this->render_trend( $report ); ?>
				</div>
				<?php $this->render_sources( $report, $can_view_log ); ?>
			<?php else : ?>
				<div class="subin-health-inline-empty subin-health-activity__empty"><span class="dashicons dashicons-filter" aria-hidden="true"></span><div><strong><?php esc_html_e( 'No activity matches these filters', 'submission-inbox' ); ?></strong><p><?php esc_html_e( 'The site-wide assessment above is unchanged. Reset or broaden this activity view to inspect other email events.', 'submission-inbox' ); ?></p></div></div>
			<?php endif; ?>
		</section>
		<?php
	}

	/** Render the four outcome metrics for the selected activity view. */
	private function render_metrics( array $report, $can_view_log ) {
		$summary = (array) ( $report['summary'] ?? array() );
		$rate    = $report['acceptance_rate'];
		$change  = $report['acceptance_change'];
		$metrics = array(
			array(
				'key'      => 'acceptance',
				'label'    => __( 'Accepted by WordPress', 'submission-inbox' ),
				'value'    => null === $rate ? '—' : number_format_i18n( (float) $rate, 1 ) . '%',
				/* translators: %1$s: optional plus sign, %2$s: acceptance-rate change in percentage points. */
				'subtext'  => null === $change ? __( 'Handoff accepted; inbox delivery unconfirmed', 'submission-inbox' ) : sprintf( __( '%1$s%2$s points vs previous period', 'submission-inbox' ), $change > 0 ? '+' : '', number_format_i18n( (float) $change, 1 ) ),
				'icon'     => 'dashicons-email-alt2',
				'log_args' => array(),
			),
			array( 'key' => 'failed', 'label' => __( 'Failed', 'submission-inbox' ), 'value' => number_format_i18n( absint( $summary['failed'] ?? 0 ) ), 'subtext' => __( 'Transport rejected the handoff', 'submission-inbox' ), 'icon' => 'dashicons-warning', 'log_args' => array( 'subin_status' => 'failed' ) ),
			array( 'key' => 'missing', 'label' => __( 'No email generated', 'submission-inbox' ), 'value' => number_format_i18n( absint( $summary['no_email_generated'] ?? 0 ) ), 'subtext' => __( 'A submission produced no notification', 'submission-inbox' ), 'icon' => 'dashicons-dismiss', 'log_args' => array( 'subin_status' => 'no_email_generated' ) ),
			array( 'key' => 'unknown', 'label' => __( 'Unknown or pending', 'submission-inbox' ), 'value' => number_format_i18n( absint( $summary['unknown'] ?? 0 ) ), 'subtext' => __( 'Outcome needs confirmation', 'submission-inbox' ), 'icon' => 'dashicons-info-outline', 'log_args' => array( 'subin_status' => 'unknown' ) ),
		);
		?>
		<section class="subin-health-metrics" aria-label="<?php esc_attr_e( 'Email outcome summary for the filtered activity view', 'submission-inbox' ); ?>">
			<?php foreach ( $metrics as $metric ) : ?>
				<?php $tag = $can_view_log ? 'a' : 'div'; ?>
				<<?php echo esc_html( $tag ); ?> class="subin-health-metric subin-health-metric--<?php echo esc_attr( $metric['key'] ); ?>"<?php echo $can_view_log ? ' href="' . esc_url( $this->email_log_url( $metric['log_args'] ) ) . '"' : ''; ?>>
					<span class="subin-health-metric__icon dashicons <?php echo esc_attr( $metric['icon'] ); ?>" aria-hidden="true"></span>
					<span class="subin-health-metric__value"><?php echo esc_html( $metric['value'] ); ?></span>
					<strong><?php echo esc_html( $metric['label'] ); ?></strong>
					<small><?php echo esc_html( $metric['subtext'] ); ?></small>
				</<?php echo esc_html( $tag ); ?>>
			<?php endforeach; ?>
		</section>
		<?php
	}

	/** Render a compact, accessible server-side trend. */
	private function render_trend( array $report ) {
		$trend = (array) ( $report['trend'] ?? array() );
		if ( empty( $trend ) ) {
			return;
		}
		$maximum = 1;
		foreach ( $trend as $day ) {
			$maximum = max( $maximum, absint( $day['sent'] ?? 0 ) + absint( $day['failed'] ?? 0 ) + absint( $day['no_email_generated'] ?? 0 ) + absint( $day['unknown'] ?? 0 ) );
		}
		?>
		<section class="subin-health-section subin-health-trend" aria-labelledby="subin-health-trend-title">
			<div class="subin-health-section__heading"><div><h2 id="subin-health-trend-title"><?php esc_html_e( 'Outcome trend', 'submission-inbox' ); ?></h2><p><?php esc_html_e( 'Daily WordPress handoffs and problem events in this activity view.', 'submission-inbox' ); ?></p></div><div class="subin-health-legend" aria-hidden="true"><span class="is-sent"><?php esc_html_e( 'Accepted', 'submission-inbox' ); ?></span><span class="is-problem"><?php esc_html_e( 'Problems', 'submission-inbox' ); ?></span></div></div>
				<ul class="screen-reader-text">
					<?php foreach ( $trend as $day ) : ?>
						<?php $day_problems = absint( $day['failed'] ?? 0 ) + absint( $day['no_email_generated'] ?? 0 ) + absint( $day['unknown'] ?? 0 ); ?>
						<?php /* translators: %1$s: date, %2$d: accepted handoffs, %3$d: problem events. */ ?>
						<li><?php echo esc_html( sprintf( __( '%1$s: %2$d accepted, %3$d problems', 'submission-inbox' ), $this->format_short_date( $day['date'] ?? '' ), absint( $day['sent'] ?? 0 ), $day_problems ) ); ?></li>
				<?php endforeach; ?>
			</ul>
			<div class="subin-health-chart" aria-hidden="true">
				<?php foreach ( $trend as $index => $day ) : ?>
					<?php
					$sent     = absint( $day['sent'] ?? 0 );
					$problems = absint( $day['failed'] ?? 0 ) + absint( $day['no_email_generated'] ?? 0 ) + absint( $day['unknown'] ?? 0 );
					$sent_pct = round( ( $sent / $maximum ) * 100, 2 );
					$bad_pct  = round( ( $problems / $maximum ) * 100, 2 );
					/* translators: %1$s: date, %2$d: accepted handoffs, %3$d: problem events. */
					$label    = sprintf( __( '%1$s: %2$d accepted, %3$d problems', 'submission-inbox' ), $this->format_short_date( $day['date'] ?? '' ), $sent, $problems );
					$show_date = 0 === $index || count( $trend ) - 1 === $index || 0 === $index % max( 1, (int) floor( count( $trend ) / 5 ) );
					?>
					<div class="subin-health-chart__day" title="<?php echo esc_attr( $label ); ?>">
						<div class="subin-health-chart__bar"><span class="is-problem<?php echo 0 === $problems ? ' is-empty' : ''; ?>" style="height: <?php echo esc_attr( (string) $bad_pct ); ?>%"></span><span class="is-sent<?php echo 0 === $sent ? ' is-empty' : ''; ?>" style="height: <?php echo esc_attr( (string) $sent_pct ); ?>%"></span></div>
						<small><?php echo $show_date ? esc_html( $this->format_short_date( $day['date'] ?? '' ) ) : '<span aria-hidden="true">·</span>'; ?></small>
					</div>
				<?php endforeach; ?>
			</div>
			<?php /* translators: %d: number of recent days shown in the chart. */ ?>
			<?php if ( ! empty( $report['trend_limited_to_days'] ) ) : ?><p class="subin-health-footnote"><?php echo esc_html( sprintf( __( 'The all-time summary is complete; the chart shows the most recent %d days.', 'submission-inbox' ), absint( $report['trend_limited_to_days'] ) ) ); ?></p><?php endif; ?>
		</section>
		<?php
	}

	/** Render current grouped incidents without duplicating Email Log rows. */
	private function render_issues( array $issues, array $signal, $can_view_log, $can_manage_sending ) {
		$active_count     = absint( $signal['active_issue_count'] ?? 0 );
		$recovering_count = absint( $signal['recovering_issue_count'] ?? 0 );
		$count_suffix     = ! empty( $signal['count_is_lower_bound'] ) ? '+' : '';
		?>
			<section id="subin-health-incidents" class="subin-health-section subin-health-incidents" data-health-scope="global" aria-labelledby="subin-health-issues-title">
				<div class="subin-health-section__heading">
					<div><span class="subin-health-eyebrow"><?php esc_html_e( 'Fix', 'submission-inbox' ); ?></span><h2 id="subin-health-issues-title"><?php esc_html_e( 'Needs attention', 'submission-inbox' ); ?></h2><p><?php esc_html_e( 'Current problems are grouped by cause and remediation scope. This is the actionable layer behind the menu badge.', 'submission-inbox' ); ?></p></div>
					<?php /* translators: %s: localized active-issue count (possibly with a plus sign); %d: recovering-issue count. */ ?>
					<div class="subin-health-incident-summary"><span class="is-active"><?php echo esc_html( sprintf( _n( '%s active issue', '%s active issues', $active_count, 'submission-inbox' ), number_format_i18n( $active_count ) . $count_suffix ) ); ?></span><?php if ( $recovering_count > 0 ) : ?><span class="is-recovering"><?php echo esc_html( sprintf( _n( '%d recovering issue', '%d recovering issues', $recovering_count, 'submission-inbox' ), $recovering_count ) ); ?></span><?php endif; ?></div>
			</div>
			<?php if ( empty( $issues ) ) : ?>
				<div class="subin-health-inline-empty"><span class="dashicons dashicons-yes-alt" aria-hidden="true"></span><div><strong><?php esc_html_e( 'No current issues need action', 'submission-inbox' ); ?></strong><p><?php esc_html_e( 'Resolved problems stay in Email Log as history and do not keep a warning badge open.', 'submission-inbox' ); ?></p></div></div>
			<?php else : ?>
				<div class="subin-health-issue-list">
					<?php foreach ( $issues as $issue ) : ?>
						<?php $data = $this->issue_data( $issue ); ?>
						<article class="subin-health-issue subin-health-issue--<?php echo esc_attr( $data['lifecycle'] ); ?>">
							<div class="subin-health-issue__main">
								<span class="subin-health-issue__icon dashicons <?php echo esc_attr( 'failed' === ( $data['status'] ?? '' ) ? 'dashicons-warning' : 'dashicons-info-outline' ); ?>" aria-hidden="true"></span>
								<div><div class="subin-health-issue__title"><h3><?php echo esc_html( $data['title'] ); ?></h3><?php SUBIN_View::badge( $this->issue_state_label( $data ), $this->issue_badge_type( $data ) ); ?></div><p><?php echo esc_html( $data['explanation'] ); ?></p><strong class="subin-health-recommendation"><?php echo esc_html( $data['recommended_action'] ); ?></strong><div class="subin-health-source-chips" aria-label="<?php esc_attr_e( 'Affected sources', 'submission-inbox' ); ?>"><?php $this->render_source_chips( $data['sources'] ); ?></div></div>
							</div>
							<dl class="subin-health-issue__meta"><div><dt><?php esc_html_e( 'Problem attempts', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( number_format_i18n( absint( $data['occurrences'] ) ) ); ?></dd></div><div><dt><?php esc_html_e( 'First detected', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( $this->format_date( $data['first_at'] ) ); ?></dd></div><div><dt><?php esc_html_e( 'Last problem', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( $this->format_date( $data['latest_at'] ) ); ?></dd></div><div><dt><?php esc_html_e( 'Recovery evidence', 'submission-inbox' ); ?></dt><dd><?php echo esc_html( $this->issue_recovery_label( $data ) ); ?></dd></div></dl>
							<div class="subin-health-issue__actions"><?php $this->render_issue_primary_action( $data, $can_manage_sending ); ?><?php if ( $can_view_log ) : ?><a href="<?php echo esc_url( $this->email_log_url( $this->status_args_for_issue( $data ), false ) ); ?>"><?php esc_html_e( 'Inspect problem events', 'submission-inbox' ); ?></a><?php endif; ?><?php if ( ! empty( $data['technical_error'] ) ) : ?><details><summary><?php esc_html_e( 'Technical details', 'submission-inbox' ); ?></summary><pre><?php echo esc_html( $data['technical_error'] ); ?></pre></details><?php endif; ?></div>
						</article>
					<?php endforeach; ?>
				</div>
				<?php if ( $active_count + $recovering_count > count( $issues ) ) : ?><p class="subin-health-footnote"><?php esc_html_e( 'Showing the highest-priority issues. Open Email Log for the complete event history.', 'submission-inbox' ); ?></p><?php endif; ?>
			<?php endif; ?>
			<?php if ( $can_view_log ) : ?><div class="subin-health-section__footer"><a href="<?php echo esc_url( $this->email_log_url( array(), false ) ); ?>"><?php esc_html_e( 'Open complete Email Log', 'submission-inbox' ); ?></a></div><?php endif; ?>
		</section>
		<?php
	}

	/** Render only sources with activity; inactive integrations stay collapsed. */
	private function render_sources( array $report, $can_view_log ) {
		$active   = (array) ( $report['active_sources'] ?? array() );
		$all      = (array) ( $report['sources'] ?? array() );
		$inactive = array_filter(
			$all,
			static function ( array $source ): bool {
				return \SUBIN\Mail\EmailHealthService::STATE_NO_DATA === ( $source['state'] ?? '' );
			}
		);
		?>
		<section class="subin-health-section subin-health-sources" aria-labelledby="subin-health-sources-title">
			<div class="subin-health-section__heading"><div><h2 id="subin-health-sources-title"><?php esc_html_e( 'Sources in this view', 'submission-inbox' ); ?></h2><p><?php esc_html_e( 'Outcome counts follow the filters. Current health still considers every outcome in the source, form, and time scope so an “Accepted” filter cannot hide a problem.', 'submission-inbox' ); ?></p></div></div>
			<?php if ( ! empty( $active ) ) : ?>
				<div class="subin-health-source-table-wrap"><table class="widefat subin-health-source-table"><caption class="screen-reader-text"><?php esc_html_e( 'Email outcomes grouped by active source in the selected activity view.', 'submission-inbox' ); ?></caption><thead><tr><th scope="col"><?php esc_html_e( 'Source', 'submission-inbox' ); ?></th><th scope="col"><?php esc_html_e( 'Current health', 'submission-inbox' ); ?></th><th scope="col"><?php esc_html_e( 'Outcomes', 'submission-inbox' ); ?></th><th scope="col"><?php esc_html_e( 'Acceptance', 'submission-inbox' ); ?></th><th scope="col"><?php esc_html_e( 'Last event', 'submission-inbox' ); ?></th><th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Actions', 'submission-inbox' ); ?></span></th></tr></thead><tbody>
				<?php foreach ( $active as $source ) : ?>
					<?php /* translators: %d: number of email outcomes in the named category. */ ?>
					<tr class="subin-health-source-row subin-health-source-row--<?php echo esc_attr( sanitize_key( $source['state'] ?? '' ) ); ?>"><td><span class="subin-health-source-name"><i class="dashicons <?php echo esc_attr( $this->source_icon( $source['key'] ?? '' ) ); ?>" aria-hidden="true"></i><strong><?php echo esc_html( $source['name'] ?? '' ); ?></strong></span></td><td><?php SUBIN_View::badge( $this->state_label( $source['state'] ?? '' ), $this->state_badge_type( $source['state'] ?? '' ) ); ?></td><td><span class="subin-health-outcomes"><span class="is-sent"><?php echo esc_html( sprintf( __( '%d accepted', 'submission-inbox' ), absint( $source['sent'] ?? 0 ) ) ); ?></span><span class="is-failed"><?php echo esc_html( sprintf( __( '%d failed', 'submission-inbox' ), absint( $source['failed'] ?? 0 ) ) ); ?></span><span class="is-missing"><?php echo esc_html( sprintf( __( '%d missing', 'submission-inbox' ), absint( $source['no_email_generated'] ?? 0 ) ) ); ?></span><span class="is-unknown"><?php echo esc_html( sprintf( __( '%d unknown', 'submission-inbox' ), absint( $source['unknown'] ?? 0 ) ) ); ?></span></span></td><td><?php echo null === $source['acceptance_rate'] ? '—' : esc_html( number_format_i18n( (float) $source['acceptance_rate'], 1 ) . '%' ); ?></td><td><?php echo esc_html( $this->format_date( $source['latest_event_at'] ?? '' ) ); ?></td><td class="subin-health-source-actions"><?php if ( $can_view_log ) : ?><a href="<?php echo esc_url( $this->email_log_url_for_source( $source['key'] ?? '' ) ); ?>"><?php esc_html_e( 'Inspect', 'submission-inbox' ); ?></a><?php endif; ?></td></tr>
				<?php endforeach; ?>
				</tbody></table></div>
			<?php endif; ?>
			<?php if ( ! empty( $inactive ) ) : ?>
				<?php /* translators: %d: number of inactive email sources. */ ?>
				<details class="subin-health-inactive"><summary><?php echo esc_html( sprintf( _n( 'Show %d inactive source', 'Show %d inactive sources', count( $inactive ), 'submission-inbox' ), count( $inactive ) ) ); ?></summary><div><?php foreach ( $inactive as $source ) : ?><span><i class="dashicons <?php echo esc_attr( $this->source_icon( $source['key'] ?? '' ) ); ?>" aria-hidden="true"></i><?php echo esc_html( $source['name'] ?? '' ); ?><small><?php esc_html_e( 'No data', 'submission-inbox' ); ?></small></span><?php endforeach; ?></div></details>
			<?php endif; ?>
		</section>
		<?php
	}

	/** Site-wide overview copy for each lifecycle state. */
	private function overview_content( $state, array $signal ) {
		$active     = absint( $signal['active_issue_count'] ?? 0 );
		$recovering = absint( $signal['recovering_issue_count'] ?? 0 );
		$problems   = absint( $signal['problem_event_count'] ?? 0 );
		/* translators: %d: number of active email issues. */
		$active_label = sprintf( _n( '%d active issue', '%d active issues', $active, 'submission-inbox' ), $active );
		/* translators: %d: number of problematic email attempts. */
		$problem_label = sprintf( _n( '%d problem attempt', '%d problem attempts', $problems, 'submission-inbox' ), $problems );
		$content = array(
			/* translators: %1$s: active-issue label, %2$s: problem-attempt label. */
			\SUBIN\Mail\EmailHealthService::STATE_CRITICAL => array( 'title' => __( 'Email sending needs action now', 'submission-inbox' ), 'message' => sprintf( __( 'Current incident summary: %1$s across %2$s in the last 30 days.', 'submission-inbox' ), $active_label, $problem_label ) ),
			/* translators: %1$d: number of active email issues. */
			\SUBIN\Mail\EmailHealthService::STATE_DEGRADED => array( 'title' => __( 'Email sending needs attention', 'submission-inbox' ), 'message' => sprintf( _n( '%1$d active issue is based on unknown or inconsistent evidence.', '%1$d active issues are based on unknown or inconsistent evidence.', $active, 'submission-inbox' ), $active ) ),
			/* translators: %d: number of recovering email issues. */
			\SUBIN\Mail\EmailHealthService::STATE_RECOVERING => array( 'title' => __( 'Email sending is recovering', 'submission-inbox' ), 'message' => sprintf( _n( '%d issue has newer accepted handoffs and is being monitored before resolution.', '%d issues have newer accepted handoffs and are being monitored before resolution.', $recovering, 'submission-inbox' ), $recovering ) ),
			\SUBIN\Mail\EmailHealthService::STATE_HEALTHY => array( 'title' => __( 'No active sending problems detected', 'submission-inbox' ), 'message' => __( 'Recent email handoffs completed successfully. WordPress acceptance is evidence of handoff, not proof of inbox delivery.', 'submission-inbox' ) ),
			\SUBIN\Mail\EmailHealthService::STATE_NO_DATA => array( 'title' => __( 'Email Health needs its first signal', 'submission-inbox' ), 'message' => __( 'No email events exist in the rolling 30-day window, so the site cannot yet be classified as healthy or unhealthy.', 'submission-inbox' ) ),
			\SUBIN\Mail\EmailHealthService::STATE_UNKNOWN => array( 'title' => __( 'Email status cannot be confirmed', 'submission-inbox' ), 'message' => __( 'Only stale pending or unknown outcomes are available. Review the issue evidence and run a verification.', 'submission-inbox' ) ),
		);

		return $content[ $state ] ?? $content[ \SUBIN\Mail\EmailHealthService::STATE_UNKNOWN ];
	}

	/** Normalize an issue group for templates. */
	private function issue_data( $issue ) {
		$lifecycle = sanitize_key( $issue->lifecycle ?? \SUBIN\Mail\EmailHealthIncidentProjector::LIFECYCLE_ACTIVE );
		$lifecycle = in_array( $lifecycle, array( 'active', 'recovering', 'resolved' ), true ) ? $lifecycle : 'active';
		return array(
			'code'               => sanitize_key( $issue->issue_code ?? 'unknown_email_error' ),
			'title'              => sanitize_text_field( $issue->issue_title ?? __( 'Email sending issue', 'submission-inbox' ) ),
			'explanation'        => sanitize_text_field( $issue->issue_explanation ?? '' ),
			'recommended_action' => sanitize_text_field( $issue->recommended_action ?? '' ),
			'action_type'        => sanitize_key( $issue->action_type ?? 'email_log' ),
			'technical_error'    => $this->error_classifier->sanitize_technical_error( (string) ( $issue->technical_error ?? '' ) ),
			'occurrences'        => absint( $issue->occurrences ?? 0 ),
			'first_at'           => sanitize_text_field( $issue->first_at ?? '' ),
			'latest_at'          => sanitize_text_field( $issue->latest_at ?? '' ),
			'latest_recovery_at' => sanitize_text_field( $issue->latest_recovery_at ?? '' ),
			'status'             => sanitize_key( $issue->primary_status ?? 'unknown' ),
			'sources'            => sanitize_text_field( $issue->sources ?? '' ),
			'source_count'       => absint( $issue->source_count ?? 0 ),
			'recovered_sources'  => absint( $issue->recovered_source_count ?? 0 ),
			'recovery_acceptances' => absint( $issue->recovery_acceptance_count ?? 0 ),
			'required_acceptances' => max( 1, absint( $issue->required_acceptances ?? 3 ) ),
			'lifecycle'          => $lifecycle,
		);
	}

	/** Render the contextual fix action when the user has permission. */
	private function render_issue_primary_action( array $issue, $can_manage_sending ) {
		if ( empty( $issue ) ) {
			return;
		}
		$action = $issue['action_type'] ?? '';
		if ( 'settings_sending' === $action && $can_manage_sending ) {
			?><a class="button button-primary subin-btn subin-btn-primary" href="<?php echo esc_url( $this->sending_settings_url() ); ?>"><?php esc_html_e( 'Fix sending settings', 'submission-inbox' ); ?></a><?php
		} elseif ( 'form_notification_settings' === $action && \SUBIN\Security\Capabilities::can_current_user( \SUBIN\Security\Capabilities::MANAGE_FORMS ) ) {
			?><a class="button button-primary subin-btn subin-btn-primary" href="<?php echo esc_url( admin_url( 'admin.php?page=submission-inbox-forms' ) ); ?>"><?php esc_html_e( 'Check form settings', 'submission-inbox' ); ?></a><?php
		}
	}

	/** Render one configuration-check action with capability boundaries. */
	private function render_check_action( $action, $can_view_log, $can_manage_sending, $can_send_test ) {
		$action = sanitize_key( $action );
		if ( 'settings_sending' === $action && $can_manage_sending ) {
			?><a href="<?php echo esc_url( $this->sending_settings_url() ); ?>"><?php esc_html_e( 'Open settings', 'submission-inbox' ); ?></a><?php
		} elseif ( 'verify' === $action && $can_send_test ) {
			?><a href="<?php echo esc_url( $this->health_url() . '#subin-health-verify' ); ?>"><?php esc_html_e( 'Run test', 'submission-inbox' ); ?></a><?php
		} elseif ( 'email_log' === $action && $can_view_log ) {
			?><a href="<?php echo esc_url( $this->email_log_url() ); ?>"><?php esc_html_e( 'View log', 'submission-inbox' ); ?></a><?php
		}
	}

	/** Label for a diagnostic check. */
	private function check_status_label( $status ) {
		$labels = array( 'pass' => __( 'Pass', 'submission-inbox' ), 'warning' => __( 'Review', 'submission-inbox' ), 'fail' => __( 'Action needed', 'submission-inbox' ), 'info' => __( 'Info', 'submission-inbox' ) );
		return $labels[ sanitize_key( $status ) ] ?? $labels['info'];
	}

	/** Badge type for a diagnostic check. */
	private function check_badge_type( $status ) {
		$types = array( 'pass' => 'success', 'warning' => 'warning', 'fail' => 'danger', 'info' => 'info' );
		return $types[ sanitize_key( $status ) ] ?? 'info';
	}

	/** Icon for a diagnostic check. */
	private function check_icon( $status ) {
		$icons = array( 'pass' => 'dashicons-yes-alt', 'warning' => 'dashicons-info-outline', 'fail' => 'dashicons-warning', 'info' => 'dashicons-editor-help' );
		return $icons[ sanitize_key( $status ) ] ?? $icons['info'];
	}

	/** State label. */
	private function state_label( $state ) {
		$labels = array(
			'no_data'    => __( 'No data', 'submission-inbox' ),
			'healthy'    => __( 'Healthy', 'submission-inbox' ),
			'degraded'   => __( 'Needs attention', 'submission-inbox' ),
			'critical'   => __( 'Critical', 'submission-inbox' ),
			'recovering' => __( 'Recovering', 'submission-inbox' ),
			'unknown'    => __( 'Unknown', 'submission-inbox' ),
		);

		return $labels[ sanitize_key( $state ) ] ?? $labels['unknown'];
	}

	/** Badge type for a state. */
	private function state_badge_type( $state ) {
		$types = array( 'healthy' => 'success', 'recovering' => 'info', 'degraded' => 'warning', 'critical' => 'danger', 'no_data' => 'muted', 'unknown' => 'muted' );
		return $types[ sanitize_key( $state ) ] ?? 'muted';
	}

	/** Dashicon for a state. */
	private function state_icon( $state ) {
		$icons = array( 'healthy' => 'dashicons-yes-alt', 'recovering' => 'dashicons-update', 'degraded' => 'dashicons-info-outline', 'critical' => 'dashicons-warning', 'no_data' => 'dashicons-chart-line', 'unknown' => 'dashicons-editor-help' );
		return $icons[ sanitize_key( $state ) ] ?? $icons['unknown'];
	}

	/** Human label for the server-projected issue lifecycle. */
	private function issue_state_label( array $issue ) {
		return 'recovering' === ( $issue['lifecycle'] ?? '' ) ? __( 'Recovering', 'submission-inbox' ) : __( 'Active', 'submission-inbox' );
	}

	/** Badge type for issue lifecycle. */
	private function issue_badge_type( array $issue ) {
		return 'recovering' === ( $issue['lifecycle'] ?? '' ) ? 'info' : ( 'failed' === ( $issue['status'] ?? '' ) ? 'danger' : 'warning' );
	}

	/** Compact recovery evidence for one current incident. */
	private function issue_recovery_label( array $issue ) {
		$source_count = max( 1, absint( $issue['source_count'] ?? 0 ) );
		$recovered    = min( $source_count, absint( $issue['recovered_sources'] ?? 0 ) );
		if ( 'recovering' === ( $issue['lifecycle'] ?? '' ) ) {
			return sprintf(
				/* translators: 1: sources with a newer accepted event, 2: all affected sources. */
				__( '%1$d of %2$d sources have a newer accepted handoff', 'submission-inbox' ),
				$recovered,
				$source_count
			);
		}
		if ( $recovered > 0 ) {
			return sprintf(
				/* translators: 1: recovered sources, 2: all affected sources. */
				__( '%1$d of %2$d sources recovered; more evidence needed', 'submission-inbox' ),
				$recovered,
				$source_count
			);
		}

		return __( 'No newer accepted handoff yet', 'submission-inbox' );
	}

	/** Status filter for an issue group. */
	private function status_args_for_issue( array $issue ) {
		$status = sanitize_key( $issue['status'] ?? '' );
		return in_array( $status, array( 'failed', 'no_email_generated', 'unknown' ), true ) ? array( 'subin_status' => $status ) : array();
	}

	/** Build a Health URL while preserving the current scope. */
	private function health_url( array $overrides = array() ) {
		return add_query_arg( array_merge( $this->health_url_args(), $overrides ), admin_url( 'admin.php' ) );
	}

	/** Query args for the current Health scope. */
	private function health_url_args() {
		$filters = $this->active_filters;
		$args = array( 'page' => self::PAGE_SLUG );
		if ( ! empty( $filters['source'] ) ) {
			$args['subin_source'] = $filters['source'];
		}
		if ( ! empty( $filters['form_key'] ) ) {
			$args['subin_form'] = $filters['form_key'];
		}
		if ( ! empty( $filters['status'] ) ) {
			$args['subin_status'] = $filters['status'];
		}
		if ( ! empty( $filters['date_range'] ) && '30' !== $filters['date_range'] ) {
			$args['subin_date_range'] = $filters['date_range'];
		}
		if ( ! empty( $filters['date_from'] ) ) {
			$args['subin_date_from'] = $filters['date_from'];
		}
		if ( ! empty( $filters['date_to'] ) ) {
			$args['subin_date_to'] = $filters['date_to'];
		}

		return $args;
	}

	/** Email Log drill-down URL preserving compatible source/form/period filters. */
	private function email_log_url( array $args = array(), $preserve_scope = true ) {
		$args       = array_merge( array( 'page' => 'subin-email-log' ), $args );
		if ( ! $preserve_scope ) {
			$args['subin_date_range'] = $args['subin_date_range'] ?? '30';
			return add_query_arg( $args, admin_url( 'admin.php' ) );
		}
		$source_map = array( 'submission_inbox_forms' => 'submission_inbox_form', 'wordpress_core' => 'wp_mail', 'other_plugins' => 'plugin' );
		$source     = sanitize_key( $this->active_filters['source'] ?? '' );
		if ( '' !== $source && empty( $args['subin_source'] ) ) {
			$args['subin_source'] = $source_map[ $source ] ?? $source;
		}
		$provider = sanitize_key( $this->active_filters['provider'] ?? '' );
		$form_id  = sanitize_text_field( $this->active_filters['form_id'] ?? '' );
		if ( 'submission_inbox_form' === $provider && '' !== $form_id ) {
			$args['subin_form_id'] = $form_id;
		}
		$date_range = (string) ( $this->active_filters['date_range'] ?? '' );
		if ( in_array( $date_range, array( '7', '30' ), true ) ) {
			$args['subin_date_range'] = $date_range;
		}
		if ( ! empty( $this->active_filters['date_from'] ) ) {
			$args['subin_date_from'] = $this->active_filters['date_from'];
		}
		if ( ! empty( $this->active_filters['date_to'] ) ) {
			$args['subin_date_to'] = $this->active_filters['date_to'];
		}

		return add_query_arg( $args, admin_url( 'admin.php' ) );
	}

	/** Email Log URL for one source group. */
	private function email_log_url_for_source( $source ) {
		$map = array( 'submission_inbox_forms' => 'submission_inbox_form', 'wordpress_core' => 'wp_mail', 'other_plugins' => 'plugin' );
		$source = sanitize_key( $source );
		return $this->email_log_url( array( 'subin_source' => $map[ $source ] ?? $source ) );
	}

	/** SMTP settings URL. */
	private function sending_settings_url() {
		return admin_url( 'admin.php?page=subin-settings&subin_settings_tab=sending' );
	}

	/** Redirect a POST action to a clean, allowed Health URL. */
	private function redirect_after_action() {
		$this->active_filters = $this->filters_from_request();
		$url                  = $this->health_url();
		if ( ! headers_sent() ) {
			wp_safe_redirect( $url, 303 );
			exit;
		}

		wp_die(
			wp_kses_post(
				sprintf(
					/* translators: %s: Email Health URL. */
					__( 'The request was processed. <a href="%s">Return to Email Health</a>.', 'submission-inbox' ),
					esc_url( $url )
				)
			),
			esc_html__( 'Redirect', 'submission-inbox' ),
			array( 'response' => 303 )
		);
		exit;
	}

	/** Source names from a CSV list. */
	private function source_names_from_csv( $sources ) {
		$labels = $this->health->source_labels();
		$names  = array();
		foreach ( explode( ',', (string) $sources ) as $source ) {
			$source = sanitize_key( $source );
			if ( isset( $labels[ $source ] ) ) {
				$names[] = $labels[ $source ];
			}
		}

		return implode( ', ', array_unique( $names ) );
	}

	/** Render compact source chips for one incident. */
	private function render_source_chips( $sources ) {
		$labels   = $this->health->source_labels();
		$rendered = array();
		foreach ( explode( ',', (string) $sources ) as $source ) {
			$source = sanitize_key( $source );
			if ( '' === $source || isset( $rendered[ $source ] ) ) {
				continue;
			}
			$rendered[ $source ] = true;
			?><span><i class="dashicons <?php echo esc_attr( $this->source_icon( $source ) ); ?>" aria-hidden="true"></i><?php echo esc_html( $labels[ $source ] ?? __( 'Unknown source', 'submission-inbox' ) ); ?></span><?php
		}
	}

	/** Source icon. */
	private function source_icon( $source ) {
		$icons = array( 'submission_inbox_forms' => 'dashicons-feedback', 'contact_form_7' => 'dashicons-email', 'wpforms' => 'dashicons-forms', 'fluent_forms' => 'dashicons-forms', 'forminator' => 'dashicons-forms', 'ninja_forms' => 'dashicons-forms', 'wordpress_core' => 'dashicons-wordpress', 'other_plugins' => 'dashicons-admin-plugins', 'unknown' => 'dashicons-editor-help' );
		return $icons[ sanitize_key( $source ) ] ?? $icons['unknown'];
	}

	/** Format a stored UTC date using WordPress preferences. */
	private function format_date( $date ) {
		return $date ? mysql2date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $date ) : '—';
	}

	/** Format a stored UTC verification date in the site timezone. */
	private function format_gmt_date( $date ) {
		$date = sanitize_text_field( (string) $date );
		return $date ? get_date_from_gmt( $date, get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) : '—';
	}

	/** Short chart date. */
	private function format_short_date( $date ) {
		return $date ? mysql2date( 'M j', $date ) : '';
	}
}
