<?php
/**
 * Email Logs WP_List_Table.
 *
 * @package EmailLogs
 * @since 1.2.0
 */

namespace EmailLogs\Includes;

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

if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

/**
 * Default WordPress list table for email log entries.
 */
class EmailLogsListTable extends \WP_List_Table {

	private string $status_filter = '';

	private string $search = '';

	private string $provider_filter = '';

	public function __construct() {
		parent::__construct(
			[
				'singular' => 'email_log',
				'plural'   => 'email_logs',
				'ajax'     => false,
			]
		);
	}

	/**
	 * @return array<string, string>
	 */
	public function get_columns(): array {
		return [
			'cb'              => '<input type="checkbox" />',
			'subject'         => __( 'Subject', 'wp-powersuite' ),
			'to_email'        => __( 'To', 'wp-powersuite' ),
			'from_email'      => __( 'From', 'wp-powersuite' ),
			'status'          => __( 'Status', 'wp-powersuite' ),
			'delivery_status' => __( 'Delivery', 'wp-powersuite' ),
			'provider'        => __( 'Provider', 'wp-powersuite' ),
			'sent_date'       => __( 'Date', 'wp-powersuite' ),
		];
	}

	/**
	 * @return array<string, array{0:string,1:bool}>
	 */
	protected function get_sortable_columns(): array {
		return [
			'subject'    => [ 'subject', false ],
			'to_email'   => [ 'to_email', false ],
			'from_email' => [ 'from_email', false ],
			'status'     => [ 'status', false ],
			'provider'   => [ 'provider', false ],
			'sent_date'  => [ 'sent_date', true ],
		];
	}

	/**
	 * @return array<string, string>
	 */
	protected function get_bulk_actions(): array {
		return [
			'delete' => __( 'Delete', 'wp-powersuite' ),
		];
	}

	/**
	 * @return array<string, string>
	 */
	protected function get_views(): array {
		$counts  = EmailLogService::count_by_status();
		$current = $this->status_filter;
		$base    = \WP_PowerSuite\Core\NetworkScope::adminUrl( 'admin.php', [ 'page' => 'powersuite-email-logs' ] );
		if ( $this->search !== '' ) {
			$base = add_query_arg( 's', $this->search, $base );
		}
		if ( $this->provider_filter !== '' ) {
			$base = add_query_arg( 'provider', $this->provider_filter, $base );
		}

		$make = static function ( string $key, string $label, int $count, string $url, string $current_key ): string {
			$class = $current_key === $key ? 'current' : '';
			return sprintf(
				'<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
				esc_url( $url ),
				esc_attr( $class ),
				esc_html( $label ),
				esc_html( number_format_i18n( $count ) )
			);
		};

		$views = [
			'all'     => $make( '', __( 'All', 'wp-powersuite' ), $counts['all'], remove_query_arg( 'status', $base ), $current ),
			'sent'    => $make( 'sent', __( 'Sent', 'wp-powersuite' ), $counts['sent'], add_query_arg( 'status', 'sent', $base ), $current ),
			'failed'  => $make( 'failed', __( 'Failed', 'wp-powersuite' ), $counts['failed'], add_query_arg( 'status', 'failed', $base ), $current ),
			'pending' => $make( 'pending', __( 'Pending', 'wp-powersuite' ), $counts['pending'], add_query_arg( 'status', 'pending', $base ), $current ),
		];

		foreach (
			[
				'delivered'  => __( 'Delivered', 'wp-powersuite' ),
				'bounced'    => __( 'Bounced', 'wp-powersuite' ),
				'complained' => __( 'Spam complaint', 'wp-powersuite' ),
			] as $key => $label
		) {
			if ( (int) ( $counts[ $key ] ?? 0 ) > 0 || $current === $key ) {
				$views[ $key ] = $make( $key, $label, (int) $counts[ $key ], add_query_arg( 'status', $key, $base ), $current );
			}
		}

		return $views;
	}

	/**
	 * @param string $which
	 */
	protected function extra_tablenav( $which ): void {
		if ( $which !== 'top' ) {
			return;
		}
		$export_url = wp_nonce_url(
			add_query_arg( 'action', 'wpps_email_logs_export', admin_url( 'admin-post.php' ) ),
			'wpps_email_logs_export'
		);
		$empty_url = wp_nonce_url(
			\WP_PowerSuite\Core\NetworkScope::adminUrl(
				'admin.php',
				[
					'page'   => 'powersuite-email-logs',
					'action' => 'empty_logs',
				]
			),
			'wpps_email_logs_empty'
		);
		?>
		<div class="alignleft actions wpps-el-table-actions">
			<a href="<?php echo esc_url( $export_url ); ?>" class="button"><?php esc_html_e( 'Export CSV', 'wp-powersuite' ); ?></a>
			<a href="<?php echo esc_url( $empty_url ); ?>" class="button" onclick="return confirm('<?php echo esc_js( __( 'Delete all email logs? This cannot be undone.', 'wp-powersuite' ) ); ?>');"><?php esc_html_e( 'Delete All', 'wp-powersuite' ); ?></a>
		</div>
		<?php
	}

	/**
	 * @param object $item
	 */
	protected function column_cb( $item ): string {
		return sprintf( '<input type="checkbox" name="log_ids[]" value="%d" />', (int) $item->id );
	}

	/**
	 * @param object $item
	 */
	protected function column_subject( $item ): string {
		$subject = (string) ( $item->subject ?? '' );
		if ( $subject === '' ) {
			$subject = __( '(No subject)', 'wp-powersuite' );
		}

		$delete_url = wp_nonce_url(
			add_query_arg(
				[
					'page'    => 'powersuite-email-logs',
					'action'  => 'delete',
					'log_ids' => [ (int) $item->id ],
				],
				\WP_PowerSuite\Core\NetworkScope::adminUrl( 'admin.php' )
			),
			'bulk-email_logs'
		);

		$actions = [
			'view'   => sprintf(
				'<a href="#" class="wpps-el-view-log" data-id="%d">%s</a>',
				(int) $item->id,
				esc_html__( 'View', 'wp-powersuite' )
			),
			'delete' => sprintf(
				'<a href="%s" class="submitdelete" onclick="return confirm(%s);">%s</a>',
				esc_url( $delete_url ),
				esc_attr( wp_json_encode( __( 'Delete this log entry?', 'wp-powersuite' ) ) ),
				esc_html__( 'Delete', 'wp-powersuite' )
			),
		];

		if ( EmailLogService::can_resend_log( $item ) ) {
			$resend_url = wp_nonce_url(
				add_query_arg(
					[
						'page'   => 'powersuite-email-logs',
						'action' => 'resend',
						'log_id' => (int) $item->id,
					],
					\WP_PowerSuite\Core\NetworkScope::adminUrl( 'admin.php' )
				),
				'wpps_email_logs_resend_' . (int) $item->id
			);
			$actions['resend'] = sprintf( '<a href="%s">%s</a>', esc_url( $resend_url ), esc_html__( 'Resend', 'wp-powersuite' ) );
		}

		return sprintf(
			'<strong><a href="#" class="row-title wpps-el-view-log" data-id="%d">%s</a></strong>%s',
			(int) $item->id,
			esc_html( $subject ),
			$this->row_actions( $actions )
		);
	}

	/**
	 * @param object $item
	 * @param string $column_name
	 * @return string
	 */
	protected function column_default( $item, $column_name ) {
		switch ( $column_name ) {
			case 'to_email':
				return '<span class="wpps-el-mono">' . esc_html( (string) ( $item->to_email ?? '' ) ) . '</span>';
			case 'from_email':
				$from = (string) ( $item->from_email ?? '' );
				if ( $from === '' && ! empty( $item->headers ) ) {
					$from = EmailLogService::extract_from_email( (string) $item->headers );
				}
				return $from !== ''
					? '<span class="wpps-el-mono">' . esc_html( $from ) . '</span>'
					: '<span class="wpps-el-muted">&mdash;</span>';
			case 'status':
				$status    = sanitize_key( (string) ( $item->status ?? 'pending' ) );
				$transport = sanitize_key( (string) ( $item->transport ?? '' ) );
				if ( $transport === 'simulation' ) {
					return '<span class="wpps-el-badge wpps-el-badge--pending">' . esc_html__( 'Simulated', 'wp-powersuite' ) . '</span>';
				}
				return sprintf(
					'<span class="wpps-el-badge wpps-el-badge--%s">%s</span>',
					esc_attr( $status ),
					esc_html( ucfirst( $status ) )
				);
			case 'delivery_status':
				$delivery = sanitize_key( (string) ( $item->delivery_status ?? '' ) );
				if ( $delivery === '' ) {
					return '<span class="wpps-el-muted">&mdash;</span>';
				}
				return sprintf(
					'<span class="wpps-el-badge wpps-el-delivery--%s">%s</span>',
					esc_attr( $delivery ),
					esc_html( EmailLogService::label_for_delivery_status( $delivery ) )
				);
			case 'provider':
				$provider  = sanitize_key( (string) ( $item->provider ?? '' ) );
				$transport = sanitize_key( (string) ( $item->transport ?? '' ) );
				$meta      = [];
				if ( $provider !== '' ) {
					$meta[] = '<span class="wpps-el-provider">' . esc_html( $provider ) . '</span>';
				}
				// Only show transport when it adds info (e.g. sendgrid · api, not smtp · smtp).
				if ( $transport !== '' && $transport !== $provider ) {
					$meta[] = '<span class="wpps-el-transport">' . esc_html( $transport ) . '</span>';
				}
				if ( ! empty( $item->retry_count ) ) {
					$meta[] = esc_html( sprintf( /* translators: %d: retries */ __( 'Retries: %d', 'wp-powersuite' ), (int) $item->retry_count ) );
				}
				if ( ! empty( $item->fallback_used ) ) {
					$meta[] = esc_html__( 'Fallback', 'wp-powersuite' );
				}
				return $meta !== [] ? '<span class="wpps-el-meta">' . implode( ' · ', $meta ) . '</span>' : '<span class="wpps-el-muted">&mdash;</span>';
			case 'sent_date':
				$ts = strtotime( (string) ( $item->sent_date ?? '' ) );
				return $ts
					? '<span class="wpps-el-date">' . esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $ts ) ) . '</span>'
					: '<span class="wpps-el-muted">&mdash;</span>';
			default:
				return '';
		}
	}

	public function prepare_items(): void {
		$this->status_filter   = isset( $_REQUEST['status'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['status'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$this->search          = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( (string) $_REQUEST['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$this->provider_filter = isset( $_REQUEST['provider'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['provider'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		$per_page     = $this->get_items_per_page( 'email_logs_per_page', 20 );
		$current_page = $this->get_pagenum();
		$orderby      = isset( $_REQUEST['orderby'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['orderby'] ) ) : 'sent_date'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$order        = isset( $_REQUEST['order'] ) ? strtolower( sanitize_text_field( wp_unslash( (string) $_REQUEST['order'] ) ) ) : 'desc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$allowed_by   = [ 'subject', 'to_email', 'from_email', 'status', 'provider', 'sent_date', 'id' ];
		if ( ! in_array( $orderby, $allowed_by, true ) ) {
			$orderby = 'sent_date';
		}
		$order = $order === 'asc' ? 'ASC' : 'DESC';

		$result = EmailLogService::get_logs(
			[
				'search'   => $this->search,
				'status'   => $this->status_filter,
				'provider' => $this->provider_filter,
				'limit'    => $per_page,
				'offset'   => ( $current_page - 1 ) * $per_page,
				'orderby'  => $orderby,
				'order'    => $order,
			]
		);

		$this->items = $result['items'];
		$this->_column_headers = [
			$this->get_columns(),
			[],
			$this->get_sortable_columns(),
			'subject',
		];

		$this->set_pagination_args(
			[
				'total_items' => (int) $result['total'],
				'per_page'    => $per_page,
				'total_pages' => (int) ceil( max( 1, (int) $result['total'] ) / max( 1, $per_page ) ),
			]
		);
	}

	/**
	 * Process bulk/row delete actions.
	 */
	public function process_bulk_action(): void {
		$action = $this->current_action();
		if ( $action !== 'delete' ) {
			return;
		}

		check_admin_referer( 'bulk-' . $this->_args['plural'] );

		$ids = [];
		if ( isset( $_REQUEST['log_ids'] ) && is_array( $_REQUEST['log_ids'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			$ids = array_map( 'absint', wp_unslash( $_REQUEST['log_ids'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		} elseif ( isset( $_REQUEST['log_id'] ) ) {
			$ids = [ absint( wp_unslash( $_REQUEST['log_id'] ) ) ];
		}

		$status   = isset( $_REQUEST['status'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['status'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$search   = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( (string) $_REQUEST['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$provider = isset( $_REQUEST['provider'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['provider'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		$deleted  = EmailLogService::delete_logs( $ids );
		$redirect = \WP_PowerSuite\Core\NetworkScope::adminUrl(
			'admin.php',
			[
				'page'    => 'powersuite-email-logs',
				'deleted' => $deleted,
			]
		);
		if ( $status !== '' ) {
			$redirect = add_query_arg( 'status', $status, $redirect );
		}
		if ( $search !== '' ) {
			$redirect = add_query_arg( 's', $search, $redirect );
		}
		if ( $provider !== '' ) {
			$redirect = add_query_arg( 'provider', $provider, $redirect );
		}
		wp_safe_redirect( $redirect );
		exit;
	}
}
