<?php

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
/**
 * The admin-specific functionality of the plugin.
 *
 * @link       https://webequipe.com
 * @since      1.0.0
 *
 * @package    Webequipe_Spin_Win_Wheel
 * @subpackage Webequipe_Spin_Win_Wheel/admin
 */

/**
 * List Table Class for Winners
 */
if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

/**
 * Class webequipe_sww_Winner_List
 */
class Webequipe_Spin_Win_Wheel_Winner_List extends WP_List_Table {

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

	/**
	 * Message to show if no designation found
	 *
	 * @return void
	 */
	public function no_items() {
		esc_html_e( 'No spin found', 'webequipe-spin-win-wheel' );
	}

	/**
	 * Get the column names
	 */
	public function get_columns() {
		return [
			'cb'         => '<input type="checkbox" />',
			'email'      => __( 'Email', 'webequipe-spin-win-wheel' ),
			'name'       => __( 'Name', 'webequipe-spin-win-wheel' ),
			'phone'      => __( 'Phone', 'webequipe-spin-win-wheel' ),
			'spin_title' => __( 'Spin', 'webequipe-spin-win-wheel' ),
			'spin_label' => __( 'Label', 'webequipe-spin-win-wheel' ),
			'spin_value' => __( 'Value', 'webequipe-spin-win-wheel' ),
			'claim'      => __( 'Claim Status', 'webequipe-spin-win-wheel' ),
			'created_at' => __( 'Date', 'webequipe-spin-win-wheel' ),
		];
	}

	/**
	 * Get sortable columns
	 */
	public function get_sortable_columns() {
		return [
			'email'      => [ 'email', true ],
			'name'       => [ 'name', true ],
			'phone'      => [ 'phone', true ],
			'spin_label' => [ 'spin_label', true ],
			'spin_value' => [ 'spin_value', true ],
			'claim'      => [ 'claim', true ],
			'created_at' => [ 'created_at', true ],
		];
	}

	/**
	 * Print column headers with nonce for sorting links.
	 *
	 * @param bool $with_id Whether to set the id attribute or not.
	 * @return void
	 */
	public function print_column_headers( $with_id = true ) {
		parent::print_column_headers( $with_id );

		// Add nonce to sorting links via JavaScript.
		$nonce = wp_create_nonce( 'wsww_winner_list_sort' );
		
		// Collect script content to be added via wp_add_inline_script().
		ob_start();
		?>
		(function() {
			var nonce = <?php echo wp_json_encode( $nonce ); ?>;
			var links = document.querySelectorAll( '.wp-list-table thead th.sortable a, .wp-list-table thead th.sorted a' );
			links.forEach( function( link ) {
				if ( link.href ) {
					try {
						var url = new URL( link.href, window.location.href );
						if ( url.searchParams.has( 'orderby' ) || url.searchParams.has( 'order' ) ) {
							url.searchParams.set( 'wsww_winner_list_sort_nonce', nonce );
							link.href = url.toString();
						}
					} catch ( e ) {
						// Fallback for older browsers.
						if ( link.href.indexOf( 'orderby' ) !== -1 || link.href.indexOf( 'order=' ) !== -1 ) {
							var separator = link.href.indexOf( '?' ) !== -1 ? '&' : '?';
							link.href = link.href + separator + 'wsww_winner_list_sort_nonce=' + encodeURIComponent( nonce );
						}
					}
				}
			});
		})();
		<?php
		$script_content = ob_get_clean();
		
		// Store script content to be added via wp_add_inline_script() in admin_footer.
		if ( class_exists( 'Webequipe_Spin_Win_Wheel_Admin' ) ) {
			Webequipe_Spin_Win_Wheel_Admin::add_admin_inline_script_content( $script_content );
		}
	}

	/**
	 * Set the bulk actions
	 */
	public function get_bulk_actions() {
		return [
			'trash' => __( 'Move to Trash', 'webequipe-spin-win-wheel' ),
		];
	}

    /**
     * Process bulk actions safely.
     *
     * @return void
     */
    public function process_bulk_action() {
        if ( 'trash' === $this->current_action() ) {

            // Verify the bulk action nonce generated by WP_List_Table.
            check_admin_referer( 'bulk-' . $this->_args['plural'] );

            // Sanitize POST input properly.
            $winner_ids_raw = filter_input( INPUT_POST, 'winner_id', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
            $winner_ids     = [];

            if ( ! empty( $winner_ids_raw ) && is_array( $winner_ids_raw ) ) {
                foreach ( $winner_ids_raw as $id ) {
                    $winner_ids[] = absint( $id );
                }
            }

            if ( ! empty( $winner_ids ) ) {
                global $wpdb;

                $ids_for_sql = array_values( array_filter( array_map( 'absint', $winner_ids ) ) );
                $deleted_count = 0;

                if ( ! empty( $ids_for_sql ) ) {
                    foreach ( $ids_for_sql as $winner_id ) {
                        $deleted = $wpdb->delete(
                            $wpdb->prefix . 'spin_emails',
                            [ 'id' => $winner_id ],
                            [ '%d' ]
                        );

                        if ( false !== $deleted ) {
                            $deleted_count += (int) $deleted;
                        }
                    }
                }

                if ( $deleted_count > 0 ) {
                    $count = $deleted_count;

                    /* translators: %s: number of winners deleted. */
                    $text = _n(
                        '%s winner deleted successfully.',
                        '%s winners deleted successfully.',
                        $count,
                        'webequipe-spin-win-wheel'
                    );

                    $message = sprintf( $text, esc_html( number_format_i18n( $count ) ) );

                    printf(
                        '<div class="notice notice-success"><p>%s</p></div>',
                        esc_html( $message )
                    );
                }
            }
        }
    }


	/**
	 * Add filters above the table
	 *
	 * @param string $which The table position.
	 */
	public function extra_tablenav( $which ) {
		if ( 'top' === $which ) {
			global $wpdb;

			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Admin list-table source query.
			$spin_posts = $wpdb->get_results( "SELECT id, spin_title FROM {$wpdb->prefix}spin_posts WHERE deleted != 1 ORDER BY spin_title ASC" );

			// Verify nonce before processing request vars.
			$has_valid_nonce = isset( $_REQUEST['wsww_winner_filters_nonce'] )
				&& wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['wsww_winner_filters_nonce'] ) ), 'wsww_winner_filters' );

			$selected_spin = ( $has_valid_nonce && isset( $_REQUEST['filter_spin_id'] ) ) ? absint( wp_unslash( $_REQUEST['filter_spin_id'] ) ) : '';
			$count_args    = [];
			if ( $selected_spin ) {
				$count_args['spin_id'] = $selected_spin;
			}
			$total_winners = (int) webequipe_sww_winner_count( $count_args );
			$export_url    = wp_nonce_url( admin_url( 'admin-post.php?action=wsww_export_winners' ), 'wsww_export_winners' );
			?>
			<div class="alignleft actions wsww-winner-actions-left">
				<?php wp_nonce_field( 'wsww_winner_filters', 'wsww_winner_filters_nonce' ); ?>
				<select name="filter_spin_id" id="filter_spin_id">
					<option value=""><?php esc_html_e( 'All Spin Posts', 'webequipe-spin-win-wheel' ); ?></option>
					<?php foreach ( $spin_posts as $spin ) : ?>
						<option value="<?php echo esc_attr( $spin->id ); ?>" <?php selected( $selected_spin, $spin->id ); ?>>
							<?php echo esc_html( $spin->spin_title ); ?>
						</option>
					<?php endforeach; ?>
				</select>

				<input type="submit" name="filter_action" id="post-query-submit" class="button"
					value="<?php esc_attr_e( 'Filter', 'webequipe-spin-win-wheel' ); ?>" />

				<?php if ( $selected_spin ) : ?>
					<a href="<?php echo esc_url( admin_url( 'admin.php?page=wsww-spin-winner' ) ); ?>" class="button">
						<?php esc_html_e( 'Clear Filters', 'webequipe-spin-win-wheel' ); ?>
					</a>
				<?php endif; ?>

				<a href="<?php echo esc_url( $export_url ); ?>" class="button button-primary">
					<?php esc_html_e( 'Export to CSV', 'webequipe-spin-win-wheel' ); ?>
				</a>
			</div>

			<div class="alignright actions wsww-winner-actions-right">
				<span class="displaying-num wsww-winner-count">
					<?php
					/* translators: %s: winner count */
					$winner_count_label = _n( '%s winner', '%s winners', $total_winners, 'webequipe-spin-win-wheel' );
					printf(
						esc_html( $winner_count_label ),
						esc_html( number_format_i18n( $total_winners ) )
					);
					?>
				</span>
			</div>
			<?php
		}
	}

	/**
	 * Default column values
	 *
	 * @param object $item
	 * @param string $column_name
	 * @return string
	 */
	protected function column_default( $item, $column_name ) {
		switch ( $column_name ) {
			case 'phone':
				return isset( $item->phone ) ? esc_html( $item->phone ) : '';

			case 'spin_title':
				if ( isset( $item->spin_id ) ) {
					$spin_post = webequipe_sww_get_spin( $item->spin_id );
					return $spin_post ? esc_html( $spin_post->spin_title ) : 'N/A';
				}
				return 'N/A';

			case 'spin_value':
				$display_value = 'N/A';
				if ( isset( $item->spin_id ) ) {
					$spin_post = webequipe_sww_get_spin( $item->spin_id );
					if ( $spin_post && isset( $spin_post->spins ) ) {
						$spins_data = json_decode( $spin_post->spins, true );
						if ( is_array( $spins_data ) ) {
							foreach ( $spins_data as $spin_item ) {
								if ( isset( $spin_item['spin_label'] ) && $spin_item['spin_label'] === $item->spin_label ) {
									$display_value = isset( $spin_item['spin_value'] ) && '' !== $spin_item['spin_value']
										? (string) $spin_item['spin_value']
										: 'N/A';
									break;
								}
							}
						}
					}
				}

				// Append coupon code if present (for coupon rewards).
				$coupon_code = isset( $item->coupon_code ) ? trim( (string) $item->coupon_code ) : '';
				if ( '' !== $coupon_code ) {
					if ( 'N/A' === $display_value ) {
						$display_value = $coupon_code;
					} else {
						$display_value = sprintf( '%s (%s)', $display_value, $coupon_code );
					}
				}

				return esc_html( $display_value );

			case 'claim':
				$claim_status = isset( $item->claim ) ? $item->claim : 'no';
				$status_class = ( 'yes' === $claim_status ) ? 'claim-yes' : 'claim-no';
				return '<span class="' . esc_attr( $status_class ) . '">' . esc_html( ucfirst( $claim_status ) ) . '</span>';

			case 'created_at':
				return esc_html(
					webequipe_sww_format_mysql_datetime_display(
						isset( $item->created_at ) ? $item->created_at : null
					)
				);

			default:
				return isset( $item->$column_name ) ? esc_html( $item->$column_name ) : '';
		}
	}

	/**
	 * Render the "email" column
	 *
	 * @param object $item
	 * @return string
	 */
	public function column_email( $item ) {
		$actions = [];

		$actions['delete'] = sprintf(
			'<a href="%s" class="submitdelete" onclick="return confirm(\'%s\');" title="%s">%s</a>',
			esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=wsww-winner-delete&id=' . $item->id ), 'wsww-winner-delete' ) ),
			esc_js( __( 'Are you sure?', 'webequipe-spin-win-wheel' ) ),
			esc_attr( $item->id ),
			esc_html__( 'Delete', 'webequipe-spin-win-wheel' )
		);

		return sprintf(
			'<a href="%1$s"><strong>%2$s</strong></a> %3$s',
			esc_url( wp_nonce_url( admin_url( 'admin.php?page=wsww-spin-winner&action=view&id=' . $item->id ), 'wsww_spin_action' ) ),
			esc_html( $item->email ),
			$this->row_actions( $actions )
		);
	}

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

	/**
	 * Prepare table items
	 */
	public function prepare_items() {
		$column   = $this->get_columns();
		$hidden   = [];
		$sortable = $this->get_sortable_columns();

		$this->_column_headers = [ $column, $hidden, $sortable ];

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

		$args = [
			'number' => $per_page,
			'offset' => $offset,
		];

		// Verify nonce before processing sorting parameters.
		$has_valid_sort_nonce = isset( $_REQUEST['wsww_winner_list_sort_nonce'] )
			&& wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['wsww_winner_list_sort_nonce'] ) ), 'wsww_winner_list_sort' );

		if ( $has_valid_sort_nonce && isset( $_REQUEST['orderby'] ) && isset( $_REQUEST['order'] ) ) {
			$requested_orderby = sanitize_key( wp_unslash( $_REQUEST['orderby'] ) );
			$requested_order   = strtolower( sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) );

			$allowed_orderby = array_keys( $sortable );
			$allowed_order   = [ 'asc', 'desc' ];

			if ( in_array( $requested_orderby, $allowed_orderby, true ) ) {
				$args['orderby'] = $requested_orderby;
			}

			if ( in_array( $requested_order, $allowed_order, true ) ) {
				$args['order'] = $requested_order;
			}
		}

		$filter_nonce_ok = isset( $_REQUEST['wsww_winner_filters_nonce'] )
			&& wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['wsww_winner_filters_nonce'] ) ), 'wsww_winner_filters' );

		if ( $filter_nonce_ok && isset( $_REQUEST['filter_spin_id'] ) && '' !== $_REQUEST['filter_spin_id'] ) {
			$args['spin_id'] = intval( wp_unslash( $_REQUEST['filter_spin_id'] ) );
		}

		$this->items = webequipe_sww_get_winners( $args );

		$count_args = [];
		if ( $filter_nonce_ok && isset( $_REQUEST['filter_spin_id'] ) && '' !== $_REQUEST['filter_spin_id'] ) {
			$count_args['spin_id'] = intval( wp_unslash( $_REQUEST['filter_spin_id'] ) );
		}

		$this->set_pagination_args(
			[
				'total_items' => webequipe_sww_winner_count( $count_args ),
				'per_page'    => $per_page,
			]
		);
	}
}
