<?php
/**
 * Basic Forms - Entries List Table
 *
 * @package BasicForms
 * @since 1.0.0
 */

namespace BasicForms;

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

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

/**
 * Entries List Table for Basic Forms admin.
 */
class EntriesListTable extends \WP_List_Table {

	private string $table_name;

	public function __construct() {
		global $wpdb;
		$this->table_name = $wpdb->prefix . 'wpps_form_entries';

		parent::__construct( [
			'singular' => 'entry',
			'plural'   => 'entries',
			'ajax'     => false,
		] );
	}

	/** @return array<string, string> */
	public function get_columns(): array {
		return [
			'cb'     => '<input type="checkbox" />',
			'id'     => 'ID',
			'form'   => __( 'Form', 'wp-powersuite' ),
			'name'   => __( 'Name', 'wp-powersuite' ),
			'email'  => __( 'Email', 'wp-powersuite' ),
			'date'   => __( 'Date', 'wp-powersuite' ),
			'status' => __( 'Status', 'wp-powersuite' ),
		];
	}

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

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

	/** @return array<string, string> */
	protected function get_views(): array {
		global $wpdb;
		$filter_status = isset( $_GET['status_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['status_filter'] ) ) : '';
		$filter_form = isset( $_GET['form_filter'] ) ? (int) $_GET['form_filter'] : 0;
		$base = add_query_arg( [ 'page' => 'powersuite-basic-forms', 'view' => 'entries' ], admin_url( 'admin.php' ) );
		if ( $filter_form ) {
			$base = add_query_arg( 'form_filter', $filter_form, $base );
		}
		$where_form = $filter_form ? $wpdb->prepare( ' AND form_id = %d', $filter_form ) : '';
		$total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$this->table_name} WHERE 1=1{$where_form}" );
		$unread = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$this->table_name} WHERE status = 'unread'{$where_form}" );
		$read = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$this->table_name} WHERE status = 'read'{$where_form}" );
		return [
			'all'    => '<a href="' . esc_url( $base ) . '" class="' . ( $filter_status === '' ? 'current' : '' ) . '">' . sprintf( esc_html__( 'All %s', 'wp-powersuite' ), '<span class="count">(' . number_format_i18n( $total ) . ')</span>' ) . '</a>',
			'unread' => '<a href="' . esc_url( add_query_arg( 'status_filter', 'unread', $base ) ) . '" class="' . ( $filter_status === 'unread' ? 'current' : '' ) . '">' . sprintf( esc_html__( 'Unread %s', 'wp-powersuite' ), '<span class="count">(' . number_format_i18n( $unread ) . ')</span>' ) . '</a>',
			'read'   => '<a href="' . esc_url( add_query_arg( 'status_filter', 'read', $base ) ) . '" class="' . ( $filter_status === 'read' ? 'current' : '' ) . '">' . sprintf( esc_html__( 'Read %s', 'wp-powersuite' ), '<span class="count">(' . number_format_i18n( $read ) . ')</span>' ) . '</a>',
		];
	}

	/** @return array<string, array> */
	public function get_sortable_columns(): array {
		return [
			'id'     => [ 'id', false ],
			'form'   => [ 'form_id', false ],
			'name'   => [ 'user_name', false ],
			'email'  => [ 'user_email', false ],
			'date'   => [ 'date_created', true ],
			'status' => [ 'status', false ],
		];
	}

	/** @param object $item */
	public function column_default( $item, $column_name ) {
		switch ( $column_name ) {
			case 'id':
				return '<strong>' . esc_html( (string) $item->id ) . '</strong>';
			case 'form':
				$form = get_post( (int) $item->form_id );
				return $form ? esc_html( $form->post_title ) : esc_html__( 'Unknown', 'wp-powersuite' );
			case 'name':
				return esc_html( $item->user_name ?? '' );
			case 'email':
				return esc_html( $item->user_email ?? '' );
			case 'date':
				return esc_html( gmdate( 'M j, Y g:i a', strtotime( $item->date_created ) ) );
			case 'status':
				$class = 'status-' . esc_attr( $item->status ?? 'unread' );
				$text = ( $item->status ?? 'unread' ) === 'unread' ? __( 'Unread', 'wp-powersuite' ) : __( 'Read', 'wp-powersuite' );
				return '<span class="wpps-bf-status-badge ' . $class . '">' . esc_html( $text ) . '</span>';
			default:
				return '';
		}
	}

	/** @param object $item */
	public function column_id( $item ): string {
		$filter_form = isset( $_GET['form_filter'] ) ? (int) $_GET['form_filter'] : 0;
		$filter_status = isset( $_GET['status_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['status_filter'] ) ) : '';

		$base_url = admin_url( 'admin.php?page=powersuite-basic-forms&view=entries' );
		if ( $filter_form ) {
			$base_url = add_query_arg( 'form_filter', $filter_form, $base_url );
		}
		if ( $filter_status ) {
			$base_url = add_query_arg( 'status_filter', $filter_status, $base_url );
		}

		$actions = [
			'view' => '<button type="button" class="wpps-bf-view-entry" data-entry-id="' . esc_attr( (string) $item->id ) . '">' . esc_html__( 'View', 'wp-powersuite' ) . '</button>',
		];
		if ( ( $item->status ?? 'unread' ) === 'unread' ) {
			$actions['mark_read'] = '<a href="' . esc_url( wp_nonce_url( $base_url . '&mark_read_entry=' . $item->id, 'mark_read_entry_' . $item->id ) ) . '">' . esc_html__( 'Mark as Read', 'wp-powersuite' ) . '</a>';
		} else {
			$actions['mark_unread'] = '<a href="' . esc_url( wp_nonce_url( $base_url . '&mark_unread_entry=' . $item->id, 'mark_unread_entry_' . $item->id ) ) . '">' . esc_html__( 'Mark as Unread', 'wp-powersuite' ) . '</a>';
		}
		$actions['delete'] = '<a href="' . esc_url( wp_nonce_url( $base_url . '&delete_entry=' . $item->id, 'delete_entry_' . $item->id ) ) . '" onclick="return confirm(\'' . esc_js( __( 'Delete this entry?', 'wp-powersuite' ) ) . '\')">' . esc_html__( 'Delete', 'wp-powersuite' ) . '</a>';

		return sprintf(
			'<strong><button type="button" class="wpps-bf-view-entry" data-entry-id="%s">%s</button></strong>%s',
			esc_attr( (string) $item->id ),
			esc_html( (string) $item->id ),
			$this->row_actions( $actions )
		);
	}

	/** @param string $which */
	protected function extra_tablenav( $which ): void {
		if ( $which !== 'top' ) {
			return;
		}

		$forms = get_posts( [ 'post_type' => 'wpps_form', 'posts_per_page' => -1 ] );
		$filter_form = isset( $_GET['form_filter'] ) ? (int) $_GET['form_filter'] : 0;
		$filter_status = isset( $_GET['status_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['status_filter'] ) ) : '';
		?>
		<div class="alignleft actions">
			<select name="form_filter" id="wpps-bf-form-filter">
				<option value="0"><?php esc_html_e( 'All Forms', 'wp-powersuite' ); ?></option>
				<?php foreach ( $forms as $form ) : ?>
					<option value="<?php echo (int) $form->ID; ?>" <?php selected( $filter_form, $form->ID ); ?>><?php echo esc_html( $form->post_title ); ?></option>
				<?php endforeach; ?>
			</select>
			<select name="status_filter" id="wpps-bf-status-filter">
				<option value=""><?php esc_html_e( 'All Statuses', 'wp-powersuite' ); ?></option>
				<option value="unread" <?php selected( $filter_status, 'unread' ); ?>><?php esc_html_e( 'Unread', 'wp-powersuite' ); ?></option>
				<option value="read" <?php selected( $filter_status, 'read' ); ?>><?php esc_html_e( 'Read', 'wp-powersuite' ); ?></option>
			</select>
			<input type="submit" class="button" value="<?php esc_attr_e( 'Filter', 'wp-powersuite' ); ?>">
		</div>
		<div class="alignleft actions">
			<a href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin.php?page=powersuite-basic-forms&view=entries&action=export_csv&form_filter=' . $filter_form . '&status_filter=' . $filter_status ), 'export_entries_csv' ) ); ?>" class="button"><?php esc_html_e( 'Export CSV', 'wp-powersuite' ); ?></a>
		</div>
		<?php
	}

	public function prepare_items(): void {
		global $wpdb;

		$columns = $this->get_columns();
		$hidden = [];
		$sortable = $this->get_sortable_columns();
		$this->_column_headers = [ $columns, $hidden, $sortable ];

		$per_page = 20;
		$current_page = $this->get_pagenum();

		$orderby_input = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'date_created';
		$order_input = isset( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'DESC';

		$allowed_orderby = [ 'id', 'form_id', 'user_name', 'user_email', 'date_created', 'status' ];
		$orderby = in_array( $orderby_input, $allowed_orderby, true ) ? $orderby_input : 'date_created';
		$order = strtoupper( $order_input ) === 'ASC' ? 'ASC' : 'DESC';

		$filter_form = isset( $_GET['form_filter'] ) ? (int) $_GET['form_filter'] : 0;
		$filter_status = isset( $_GET['status_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['status_filter'] ) ) : '';
		if ( $filter_status !== '' && ! in_array( $filter_status, [ 'read', 'unread' ], true ) ) {
			$filter_status = '';
		}

		$where_conditions = [];
		if ( $filter_form ) {
			$where_conditions[] = $wpdb->prepare( 'form_id = %d', $filter_form );
		}
		if ( $filter_status ) {
			$where_conditions[] = $wpdb->prepare( 'status = %s', $filter_status );
		}
		$search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
		if ( $search !== '' ) {
			$like = '%' . $wpdb->esc_like( $search ) . '%';
			$where_conditions[] = $wpdb->prepare( '( user_name LIKE %s OR user_email LIKE %s OR payload LIKE %s )', $like, $like, $like );
		}
		$where = ! empty( $where_conditions ) ? ' WHERE ' . implode( ' AND ', $where_conditions ) : '';

		$total_items = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$this->table_name}{$where}" );
		$offset = ( $current_page - 1 ) * $per_page;
		$this->items = $wpdb->get_results( $wpdb->prepare(
			"SELECT * FROM {$this->table_name}{$where} ORDER BY {$orderby} {$order} LIMIT %d OFFSET %d",
			$per_page,
			$offset
		) );

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

	public function no_items(): void {
		echo esc_html__( 'No entries found.', 'wp-powersuite' );
	}

	/** @param object $item */
	public function single_row( $item ): void {
		$class = ( $item->status ?? '' ) === 'unread' ? 'entry-unread' : '';
		echo '<tr' . ( $class ? ' class="' . esc_attr( $class ) . '"' : '' ) . '>';
		$this->single_row_columns( $item );
		echo '</tr>';
	}
}
