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

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

/**
 * Renders the email log.
 */
class SUBIN_EmailLogPage {
	const PER_PAGE = 20;

	/**
	 * Mail event repository.
	 *
	 * @var \SUBIN\MailLog\MailEventRepository
	 */
	private $events;

	/**
	 * Email error classifier.
	 *
	 * @var \SUBIN\Mail\EmailErrorClassifier
	 */
	private $error_classifier;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->events           = new \SUBIN\MailLog\MailEventRepository();
		$this->error_classifier = new \SUBIN\Mail\EmailErrorClassifier();
	}

	/**
	 * Render page.
	 *
	 * @return void
	 */
	public function render() {
		if ( ! current_user_can( SUBIN_AdminMenu::CAPABILITY ) ) {
			wp_die( esc_html__( 'You do not have permission to perform this action.', 'submission-inbox' ) );
		}

		$filters     = $this->get_filters_from_request();
		$paged       = max( 1, SUBIN_Request::get_absint( 'paged', 1 ) );
		$total       = $this->events->count_events( $filters );
		$total_pages = max( 1, (int) ceil( $total / self::PER_PAGE ) );
		$paged       = min( $paged, $total_pages );

		$events = $this->events->get_paginated_events(
			array_merge(
				$filters,
				array(
					'per_page' => self::PER_PAGE,
					'offset'   => ( $paged - 1 ) * self::PER_PAGE,
				)
			)
		);
		$export_url = $this->export_url( $filters );

		SUBIN_View::page_header(
			__( 'Email Log', 'submission-inbox' ),
			__( 'Review emails sent through WordPress and their sending status.', 'submission-inbox' ),
			array(
				'primary_action'    => array(
					'label' => __( 'Email Status', 'submission-inbox' ),
					'url'   => admin_url( 'admin.php?page=subin-email-status' ),
				),
				'secondary_actions' => array(
					array(
						'label' => __( 'Export CSV', 'submission-inbox' ),
						'url'   => $export_url,
					),
				),
				'wrapper_class'     => 'subin-email-log-page',
			)
		);

		settings_errors( 'subin_messages' );
		$this->render_summary_cards( $filters );
		$this->render_filters( $filters );
		$this->render_events_table( $events, $total, $filters );
		$this->render_pagination( $total, $paged, $filters );
		SUBIN_View::page_footer();
	}

	/**
	 * Handle CSV export before the admin page sends HTML.
	 *
	 * @return void
	 */
	public function handle_export_request() {
		if ( ! current_user_can( SUBIN_AdminMenu::CAPABILITY ) ) {
			return;
		}

		$this->maybe_export( $this->get_filters_from_request() );
	}

	/**
	 * Render summary cards.
	 *
	 * @return void
	 */
	private function render_summary_cards( array $filters = array() ) {
		$total   = $this->events->count_events( $filters );
		$sent    = $this->events->count_events( array_merge( $filters, array( 'status' => 'sent' ) ) );
		$failed  = $this->events->count_events( array_merge( $filters, array( 'status' => 'failed' ) ) );
		$missing = $this->events->count_events( array_merge( $filters, array( 'status' => 'no_email_generated' ) ) );
		$unknown = max( 0, $total - $sent - $failed - $missing );
		$cards = array(
			array( 'key' => 'total', 'label' => __( 'Total emails', 'submission-inbox' ), 'value' => $total, 'icon' => 'dashicons-email-alt2' ),
			array( 'key' => 'sent', 'label' => __( 'Sent by WordPress', 'submission-inbox' ), 'value' => $sent, 'icon' => 'dashicons-yes-alt' ),
			array( 'key' => 'failed', 'label' => __( 'Failed', 'submission-inbox' ), 'value' => $failed, 'icon' => 'dashicons-warning' ),
			array( 'key' => 'unknown', 'label' => __( 'Unknown', 'submission-inbox' ), 'value' => $unknown, 'icon' => 'dashicons-info-outline' ),
		);
		?>
		<div class="subin-summary-grid subin-email-log-summary">
			<?php foreach ( $cards as $card ) : ?>
				<div class="subin-summary-card">
					<span class="<?php echo esc_attr( 'subin-status-icon subin-status-icon--' . sanitize_html_class( $card['key'] ) . ' dashicons ' . $card['icon'] ); ?>" aria-hidden="true"></span>
					<span class="subin-summary-value"><?php echo esc_html( (string) absint( $card['value'] ) ); ?></span>
					<span class="subin-summary-label"><?php echo esc_html( $card['label'] ); ?></span>
				</div>
			<?php endforeach; ?>
		</div>
		<?php
	}

	/**
	 * Render filters and search.
	 *
	 * @param array<string,mixed> $filters Active filters.
	 * @return void
	 */
	private function render_filters( array $filters ) {
		$show_advanced_filters = SUBIN_Request::query_has( 'subin_date_from' ) || SUBIN_Request::query_has( 'subin_date_to' );
		?>
		<div class="subin-filter-panel">
			<form method="get" action="" class="subin-filter-form">
				<input type="hidden" name="page" value="subin-email-log" />
				<div class="subin-filter-main subin-filter-main--log">
					<div class="subin-filter-field subin-filter-field--search">
						<label for="subin-email-log-search"><?php esc_html_e( 'Search', 'submission-inbox' ); ?></label>
						<input type="search" id="subin-email-log-search" name="s" value="<?php echo esc_attr( $filters['search'] ); ?>" placeholder="<?php esc_attr_e( 'Search email events', 'submission-inbox' ); ?>" />
					</div>
					<div class="subin-filter-field">
						<label for="subin-event-status"><?php esc_html_e( 'Status', 'submission-inbox' ); ?></label>
						<select id="subin-event-status" name="subin_status">
							<option value=""><?php esc_html_e( 'All', 'submission-inbox' ); ?></option>
							<option value="sent" <?php selected( $filters['status'], 'sent' ); ?>><?php esc_html_e( 'Sent 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', 'submission-inbox' ); ?></option>
						</select>
					</div>
					<div class="subin-filter-field">
						<label for="subin-source"><?php esc_html_e( 'Source', 'submission-inbox' ); ?></label>
						<select id="subin-source" name="subin_source">
							<option value=""><?php esc_html_e( 'All sources', 'submission-inbox' ); ?></option>
							<option value="wp_mail" <?php selected( $filters['source'], 'wp_mail' ); ?>><?php esc_html_e( 'WordPress Core', 'submission-inbox' ); ?></option>
							<option value="submission_inbox_form" <?php selected( $filters['source'], 'submission_inbox_form' ); ?>><?php esc_html_e( 'Submission Inbox Forms', 'submission-inbox' ); ?></option>
							<option value="submission_inbox_auto_reply" <?php selected( $filters['source'], 'submission_inbox_auto_reply' ); ?>><?php esc_html_e( 'Auto-reply', 'submission-inbox' ); ?></option>
							<option value="contact_form_7" <?php selected( $filters['source'], 'contact_form_7' ); ?>><?php esc_html_e( 'Contact Form 7', 'submission-inbox' ); ?></option>
							<option value="wpforms" <?php selected( $filters['source'], 'wpforms' ); ?>><?php esc_html_e( 'WPForms', 'submission-inbox' ); ?></option>
							<option value="fluent_forms" <?php selected( $filters['source'], 'fluent_forms' ); ?>><?php esc_html_e( 'Fluent Forms', 'submission-inbox' ); ?></option>
							<option value="forminator" <?php selected( $filters['source'], 'forminator' ); ?>><?php esc_html_e( 'Forminator', 'submission-inbox' ); ?></option>
							<option value="ninja_forms" <?php selected( $filters['source'], 'ninja_forms' ); ?>><?php esc_html_e( 'Ninja Forms', 'submission-inbox' ); ?></option>
							<option value="plugin" <?php selected( $filters['source'], 'plugin' ); ?>><?php esc_html_e( 'Other plugins', 'submission-inbox' ); ?></option>
							<option value="unknown" <?php selected( $filters['source'], 'unknown' ); ?>><?php esc_html_e( 'Unknown', 'submission-inbox' ); ?></option>
						</select>
					</div>
					<div class="subin-filter-field">
						<label for="subin-date-range"><?php esc_html_e( 'Date range', 'submission-inbox' ); ?></label>
						<select id="subin-date-range" name="subin_date_range">
							<option value="" <?php selected( $filters['date_range'], '' ); ?>><?php esc_html_e( 'All time', 'submission-inbox' ); ?></option>
							<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>
						</select>
					</div>
					<div class="subin-filter-actions">
						<button type="submit" class="button subin-btn subin-btn-primary"><?php esc_html_e( 'Filter', 'submission-inbox' ); ?></button>
						<a class="button subin-btn" href="<?php echo esc_url( $this->list_url( array(), 1 ) ); ?>"><?php esc_html_e( 'Reset', 'submission-inbox' ); ?></a>
					</div>
				</div>
				<details class="subin-advanced-filters subin-filter-advanced"<?php echo $show_advanced_filters ? ' open' : ''; ?>>
					<summary class="subin-filter-toggle"><?php esc_html_e( 'Advanced', 'submission-inbox' ); ?></summary>
					<div class="subin-advanced-filters__grid">
						<div class="subin-filter-field">
							<label for="subin-date-from"><?php esc_html_e( 'From date', 'submission-inbox' ); ?></label>
							<input type="date" id="subin-date-from" name="subin_date_from" value="<?php echo esc_attr( $filters['date_from'] ); ?>" />
						</div>
						<div class="subin-filter-field">
							<label for="subin-date-to"><?php esc_html_e( 'To date', 'submission-inbox' ); ?></label>
							<input type="date" id="subin-date-to" name="subin_date_to" value="<?php echo esc_attr( $filters['date_to'] ); ?>" />
						</div>
					</div>
				</details>
			</form>
		</div>
		<?php
	}

	/**
	 * Render events table.
	 *
	 * @param array<int,object>   $events Events.
	 * @param int                 $total Total.
	 * @param array<string,mixed> $filters Filters.
	 * @return void
	 */
	private function render_events_table( array $events, $total, array $filters ) {
		if ( empty( $events ) ) {
			if ( $this->has_active_filters( $filters ) || $total > 0 ) {
				SUBIN_View::empty_state( __( 'No email events match the current filters', 'submission-inbox' ), __( 'Try changing the filters or clearing the search.', 'submission-inbox' ) );
			} else {
				SUBIN_View::empty_state( __( 'No email events yet', 'submission-inbox' ), __( 'Emails sent through WordPress will appear here after logging starts.', 'submission-inbox' ) );
			}
			return;
		}
		?>
		<div class="subin-log-table-card">
			<table class="widefat subin-log-table">
				<thead>
					<tr>
						<th><?php esc_html_e( 'Date', 'submission-inbox' ); ?></th>
						<th><?php esc_html_e( 'Recipient', 'submission-inbox' ); ?></th>
						<th>
							<?php esc_html_e( 'Subject', 'submission-inbox' ); ?>
						</th>
						<th><?php esc_html_e( 'Source', 'submission-inbox' ); ?></th>
						<th><?php esc_html_e( 'Status', 'submission-inbox' ); ?></th>
						<th>
							<?php esc_html_e( 'Related lead', 'submission-inbox' ); ?>
						</th>
						<th><?php esc_html_e( 'Error', 'submission-inbox' ); ?></th>
						<th><?php esc_html_e( 'Actions', 'submission-inbox' ); ?></th>
					</tr>
				</thead>
				<tbody>
					<?php foreach ( $events as $event ) : ?>
						<?php $this->render_event_row( $event ); ?>
					<?php endforeach; ?>
				</tbody>
			</table>
		</div>
		<?php
	}

	/**
	 * Render one event row.
	 *
	 * @param object $event Event.
	 * @return void
	 */
	private function render_event_row( $event ) {
		$status       = sanitize_key( $event->status ?? 'unknown' );
		$error        = sanitize_textarea_field( $event->error_message ?? '' );
		$issue        = ( 'failed' === $status && '' !== $error ) ? $this->error_classifier->classify( $error ) : array();
		$safe_error   = '' !== $error ? $this->error_classifier->sanitize_technical_error( $error ) : '';
		$filter_error = ! empty( $issue['technical_error'] ) ? $issue['technical_error'] : $safe_error;
		?>
		<tr class="<?php echo 'failed' === $status ? 'subin-row-failed' : ''; ?>">
			<td><?php echo esc_html( $this->format_date( $event->created_at ) ); ?></td>
			<td><span class="subin-truncate"><?php echo esc_html( $event->to_email ); ?></span></td>
			<td>
				<span class="subin-log-subject"><?php echo esc_html( $event->subject ? $event->subject : __( 'No subject', 'submission-inbox' ) ); ?></span>
				<?php if ( ! empty( $event->message_hash ) ) : ?>
					<span class="subin-log-subtext">
						<?php echo esc_html( substr( (string) $event->message_hash, 0, 12 ) ); ?>
					</span>
				<?php endif; ?>
			</td>
			<td>
				<span class="subin-source-pill"><?php echo esc_html( $this->source_label_for_event( $event ) ); ?></span>
				<?php if ( 'submission_inbox_auto_reply' === sanitize_key( $event->source ?? '' ) ) : ?>
					<span class="subin-event-type-pill"><?php esc_html_e( 'Auto-reply', 'submission-inbox' ); ?></span>
				<?php endif; ?>
			</td>
			<td><?php $this->status_badge( $status ); ?></td>
			<td><?php $this->render_related_lead( $event ); ?></td>
			<td>
				<?php if ( ! empty( $issue ) ) : ?>
					<span class="subin-log-error"><?php echo esc_html( $issue['title'] ); ?></span>
					<?php if ( '' !== $issue['technical_error'] ) : ?>
						<span class="subin-log-subtext"><?php echo esc_html( wp_trim_words( $issue['technical_error'], 14 ) ); ?></span>
					<?php endif; ?>
					<span class="subin-log-subtext"><?php echo esc_html( $issue['recommended_action'] ); ?></span>
				<?php elseif ( '' !== $safe_error ) : ?>
					<span class="subin-log-error"><?php echo esc_html( wp_trim_words( $safe_error, 16 ) ); ?></span>
				<?php else : ?>
					<span class="subin-muted"><?php esc_html_e( 'No error', 'submission-inbox' ); ?></span>
				<?php endif; ?>
			</td>
			<td>
				<div class="subin-row-actions">
					<a class="subin-action-chip" href="<?php echo esc_url( admin_url( 'admin.php?page=subin-email-log&s=' . absint( $event->id ) ) ); ?>"><?php esc_html_e( 'View details', 'submission-inbox' ); ?></a>
					<?php if ( ! empty( $event->lead_id ) ) : ?>
						<a class="subin-action-chip" href="<?php echo esc_url( $this->lead_detail_url( absint( $event->lead_id ) ) ); ?>"><?php esc_html_e( 'View lead', 'submission-inbox' ); ?></a>
					<?php endif; ?>
					<?php if ( 'failed' === $status ) : ?>
						<a class="subin-action-chip subin-action-chip-warning" href="<?php echo esc_url( admin_url( 'admin.php?page=subin-email-log&subin_status=failed&s=' . rawurlencode( $filter_error ) ) ); ?>"><?php esc_html_e( 'Filter similar', 'submission-inbox' ); ?></a>
					<?php endif; ?>
				</div>
			</td>
		</tr>
		<?php
	}

	/**
	 * Render related lead cell.
	 *
	 * @param object $event Event.
	 * @return void
	 */
	private function render_related_lead( $event ) {
		if ( empty( $event->lead_id ) ) {
			echo '<span class="subin-muted">' . esc_html__( 'No lead', 'submission-inbox' ) . '</span>';
			return;
		}

		if ( empty( $event->linked_lead_id ) ) {
			echo '<span class="subin-muted">' . esc_html__( 'Deleted lead', 'submission-inbox' ) . '</span>';
			return;
		}

		$label = ! empty( $event->lead_form_name ) ? $event->lead_form_name : '#' . absint( $event->lead_id );
		?>
		<a class="subin-related-lead" href="<?php echo esc_url( $this->lead_detail_url( absint( $event->lead_id ) ) ); ?>"><?php echo esc_html( $label ); ?></a>
		<?php
	}

	/**
	 * Export filtered email events when requested.
	 *
	 * @param array<string,mixed> $filters Filters.
	 * @return void
	 */
	private function maybe_export( array $filters ) {
		if ( 'email_log' !== sanitize_key( wp_unslash( $_GET['subin_export'] ?? '' ) ) ) {
			return;
		}

		if ( ! isset( $_GET['subin_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['subin_export_nonce'] ) ), 'subin_export_email_log' ) ) {
			add_settings_error( 'subin_messages', 'subin_export_invalid', __( 'Security check failed. Please try again.', 'submission-inbox' ), 'error' );
			return;
		}

		$limit  = 5000;
		$events = $this->events->get_events_for_export( $filters, $limit );
		$rows   = array(
			array(
				'Event ID',
				'Lead ID',
				'Date',
				'To',
				'From',
				'Subject',
				'Source',
				'Status',
				'Error Message',
			),
		);

		foreach ( $events as $event ) {
			$rows[] = array(
				$event->id,
				$event->lead_id,
				$event->created_at,
				$event->to_email,
				$event->from_email,
				$event->subject,
				$this->source_label_for_event( $event ),
				$this->status_label( $event->status ),
				$this->error_classifier->sanitize_technical_error( (string) $event->error_message ),
			);
		}

		if ( count( $events ) >= $limit ) {
			$rows[] = array( 'Export limited to 5000 rows.' );
		}

		$exporter = new \SUBIN\Export\CsvExporter();
		$exporter->export_email_events( $rows, 'submission-inbox-email-log-' . gmdate( 'Y-m-d' ) . '.csv' );
	}

	/**
	 * Get request filters.
	 *
	 * @return array<string,string>
	 */
	private function get_filters_from_request() {
		$status       = SUBIN_Request::get_key( 'subin_status' );
		$source       = SUBIN_Request::get_key( 'subin_source' );
		$date_range   = SUBIN_Request::get_key( 'subin_date_range' );
		$date_from    = $this->sanitize_date( SUBIN_Request::get_text( 'subin_date_from' ) );
		$date_to      = $this->sanitize_date( SUBIN_Request::get_text( 'subin_date_to' ) );

		return array(
			'status'       => in_array( $status, array( 'sent', 'failed', 'no_email_generated', 'unknown' ), true ) ? $status : '',
			'source'       => in_array( $source, array( 'wp_mail', 'submission_inbox_form', 'submission_inbox_auto_reply', 'contact_form_7', 'wpforms', 'fluent_forms', 'forminator', 'ninja_forms', 'plugin', 'unknown' ), true ) ? $source : '',
			'date_range'   => in_array( $date_range, array( '7', '30' ), true ) ? $date_range : '',
			'date_from'    => $date_from,
			'date_to'      => $date_to,
			'search'       => SUBIN_Request::get_text( 's' ),
		);
	}

	/**
	 * Sanitize date input.
	 *
	 * @param mixed $date Date.
	 * @return string
	 */
	private function sanitize_date( $date ) {
		$date = sanitize_text_field( wp_unslash( $date ) );
		if ( 1 !== preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date ) ) {
			return '';
		}

		$parts = explode( '-', $date );

		return checkdate( absint( $parts[1] ), absint( $parts[2] ), absint( $parts[0] ) ) ? $date : '';
	}

	/**
	 * Check active filters.
	 *
	 * @param array<string,mixed> $filters Filters.
	 * @return bool
	 */
	private function has_active_filters( array $filters ) {
		return '' !== implode( '', array_map( 'strval', $filters ) );
	}

	/**
	 * Build URL args from filters.
	 *
	 * @param array<string,mixed> $filters Filters.
	 * @return array<string,string>
	 */
	private function url_args_from_filters( array $filters ) {
		return array_filter(
			array(
				'page'             => 'subin-email-log',
				'subin_status'       => $filters['status'] ?? '',
				'subin_source'       => $filters['source'] ?? '',
				'subin_date_range'   => $filters['date_range'] ?? '',
				'subin_date_from'    => $filters['date_from'] ?? '',
				'subin_date_to'      => $filters['date_to'] ?? '',
				's'                => $filters['search'] ?? '',
			)
		);
	}

	/**
	 * Render pagination.
	 *
	 * @param int    $total Total rows.
	 * @param int    $paged Current page.
	 * @param array<string,mixed> $filters Filters.
	 * @return void
	 */
	private function render_pagination( $total, $paged, array $filters ) {
		$total_pages = max( 1, (int) ceil( $total / self::PER_PAGE ) );

		if ( $total_pages <= 1 ) {
			return;
		}

		echo '<nav class="subin-pagination" aria-label="' . esc_attr__( 'Email log pagination', 'submission-inbox' ) . '">';
		/* translators: 1: current page number, 2: total page count. */
		echo '<span class="subin-pagination__info">' . esc_html( sprintf( __( 'Page %1$d of %2$d', 'submission-inbox' ), absint( $paged ), absint( $total_pages ) ) ) . '</span>';
		echo '<div class="subin-pagination__links">';
		echo wp_kses_post(
			paginate_links(
				array(
					'base'      => add_query_arg( 'paged', '%#%', $this->list_url( $filters, 1 ) ),
					'format'    => '',
					'current'   => $paged,
					'total'     => $total_pages,
					'prev_text' => __( 'Previous', 'submission-inbox' ),
					'next_text' => __( 'Next', 'submission-inbox' ),
				)
			)
		);
		echo '</div></nav>';
	}

	/**
	 * Build list URL.
	 *
	 * @param array<string,mixed> $filters Filters.
	 * @param int                 $paged Page.
	 * @return string
	 */
	private function list_url( array $filters, $paged ) {
		$args = $this->url_args_from_filters( $filters );
		if ( $paged > 1 ) {
			$args['paged'] = $paged;
		}

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

	/**
	 * Export URL for current filters.
	 *
	 * @param array<string,mixed> $filters Filters.
	 * @return string
	 */
	private function export_url( array $filters ) {
		return wp_nonce_url(
			add_query_arg( array_merge( $this->url_args_from_filters( $filters ), array( 'subin_export' => 'email_log' ) ), admin_url( 'admin.php' ) ),
			'subin_export_email_log',
			'subin_export_nonce'
		);
	}

	/**
	 * Lead detail URL.
	 *
	 * @param int $lead_id Lead ID.
	 * @return string
	 */
	private function lead_detail_url( $lead_id ) {
		return add_query_arg(
			array(
				'page'    => SUBIN_AdminMenu::MENU_SLUG,
				'action'  => 'view',
				'lead_id' => absint( $lead_id ),
			),
			admin_url( 'admin.php' )
		);
	}

	/**
	 * Render mail status badge.
	 *
	 * @param string $status Status.
	 * @return void
	 */
	private function status_badge( $status ) {
		SUBIN_View::badge( $this->status_label( $status ), $this->badge_type_for_status( $status ) );
	}

	/**
	 * Badge type for status.
	 *
	 * @param string $status Status.
	 * @return string
	 */
	private function badge_type_for_status( $status ) {
		if ( in_array( $status, array( 'sent', 'detected' ), true ) ) {
			return 'success';
		}

		if ( 'failed' === $status ) {
			return 'danger';
		}

		if ( 'no_email_generated' === $status ) {
			return 'warning';
		}

		return 'muted';
	}

	/**
	 * Email event status label.
	 *
	 * @param string $status Status.
	 * @return string
	 */
	private function status_label( $status ) {
		$labels = array(
			'sent'    => __( 'Sent by WordPress', 'submission-inbox' ),
			'failed'  => __( 'Failed', 'submission-inbox' ),
			'no_email_generated' => __( 'No email generated', 'submission-inbox' ),
			'pending' => __( 'Unknown', 'submission-inbox' ),
			'unknown' => __( 'Unknown', 'submission-inbox' ),
		);

		return $labels[ $status ] ?? __( 'Unknown', 'submission-inbox' );
	}

	/**
	 * Source label.
	 *
	 * @param string $source Source.
	 * @return string
	 */
	private function source_label( $source ) {
		$labels = array(
			'wp_mail'           => __( 'WordPress Core', 'submission-inbox' ),
			'wordpress'         => __( 'WordPress Core', 'submission-inbox' ),
			'submission_inbox_form' => __( 'Submission Inbox Forms', 'submission-inbox' ),
			'submission_inbox_auto_reply' => __( 'Auto-reply', 'submission-inbox' ),
			'contact_form_7'    => __( 'Contact Form 7', 'submission-inbox' ),
			'wpforms'           => __( 'WPForms', 'submission-inbox' ),
			'fluent_forms'      => __( 'Fluent Forms', 'submission-inbox' ),
			'forminator'        => __( 'Forminator', 'submission-inbox' ),
			'ninja_forms'       => __( 'Ninja Forms', 'submission-inbox' ),
			'plugin'            => __( 'Other plugins', 'submission-inbox' ),
			'unknown_source'    => __( 'Unknown source', 'submission-inbox' ),
			'unknown'           => __( 'Unknown', 'submission-inbox' ),
		);

		return $labels[ $source ] ?? __( 'Unknown', 'submission-inbox' );
	}

	/**
	 * Source label for an event, using linked lead data when available.
	 *
	 * @param object $event Event.
	 * @return string
	 */
	private function source_label_for_event( $event ) {
		if ( 'submission_inbox_auto_reply' === sanitize_key( $event->source ?? '' ) ) {
			if ( ! empty( $event->lead_provider ) ) {
				return $this->source_label( $event->lead_provider );
			}

			return $this->source_label( 'unknown_source' );
		}

		if ( ! empty( $event->lead_provider ) ) {
			return $this->source_label( $event->lead_provider );
		}

		return $this->source_label( $event->source );
	}

	/**
	 * Format date.
	 *
	 * @param string $date Date.
	 * @return string
	 */
	private function format_date( $date ) {
		if ( empty( $date ) ) {
			return '';
		}

		return mysql2date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $date );
	}
}
