<?php
/**
 * 404 Monitor — Admin List Table
 *
 * Extends WP_List_Table to render the 404 log entries
 * with pagination, sorting, search, and bulk actions.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Monitor404;

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

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

class AdminTable extends \WP_List_Table {

	/**
	 * Total items found.
	 *
	 * @var int
	 */
	private $total_items = 0;

	/**
	 * Constructor.
	 */
	public function __construct() {
		parent::__construct(
			array(
				'singular' => __( '404 Log', 'seovault-ai' ),
				'plural'   => __( '404 Logs', 'seovault-ai' ),
				'ajax'     => false,
				'screen'   => 'seovault-ai-general',
			)
		);
	}

	/**
	 * Get columns for the list table.
	 *
	 * @return array
	 */
	public function get_columns() {
		return array(
			'cb'             => '<label class="seovaultseo-check"><input type="checkbox" /><span></span></label>',
			'uri'            => __( 'URL', 'seovault-ai' ),
			'times_accessed' => __( 'Hits', 'seovault-ai' ),
			'referer'        => __( 'Referrer', 'seovault-ai' ),
			'user_agent'     => __( 'User Agent', 'seovault-ai' ),
			'accessed'       => __( 'Last Accessed', 'seovault-ai' ),
			'actions_col'    => __( 'Actions', 'seovault-ai' ),
		);
	}

	/**
	 * Get sortable columns.
	 *
	 * @return array
	 */
	public function get_sortable_columns() {
		return array(
			'uri'            => array( 'uri', false ),
			'times_accessed' => array( 'times_accessed', true ),
			'accessed'       => array( 'accessed', true ),
		);
	}

	/**
	 * Get bulk actions.
	 *
	 * @return array
	 */
	public function get_bulk_actions() {
		return array(
			'delete' => __( 'Delete', 'seovault-ai' ),
		);
	}

	/**
	 * Default column renderer.
	 *
	 * @param array  $item        Row data.
	 * @param string $column_name Column name.
	 * @return string
	 */
	public function column_default( $item, $column_name ) {
		switch ( $column_name ) {
			case 'uri':
				$uri  = esc_html( $item['uri'] );
				$url  = home_url( '/' ) . ltrim( $item['uri'], '/' );
				$link = '<a href="' . esc_url( $url ) . '" target="_blank" rel="noopener noreferrer">' . $uri . '</a>';
				return $link;

			case 'times_accessed':
				return '<strong>' . esc_html( number_format_i18n( (int) $item['times_accessed'] ) ) . '</strong>';

			case 'referer':
				if ( empty( $item['referer'] ) ) {
					return '&mdash;';
				}
				return '<a href="' . esc_url( $item['referer'] ) . '" target="_blank" rel="noopener noreferrer">' . esc_html( wp_parse_url( $item['referer'], PHP_URL_HOST ) ?: $item['referer'] ) . '</a>';

			case 'user_agent':
				if ( empty( $item['user_agent'] ) ) {
					return '&mdash;';
				}
				$ua = $item['user_agent'];
				if ( strlen( $ua ) > 80 ) {
					$ua = substr( $ua, 0, 77 ) . '...';
				}
				return '<span title="' . esc_attr( $item['user_agent'] ) . '">' . esc_html( $ua ) . '</span>';

			case 'accessed':
				return esc_html( mysql2date( 'Y-m-d H:i:s', $item['accessed'] ) );

			case 'actions_col':
				$redirect_url = wp_nonce_url(
					add_query_arg(
						array(
							'page'   => 'seovault-ai-general',
							'tab'    => 'vtab-404-monitor',
							'action' => 'redirect',
							'log'    => (int) $item['id'],
						),
						admin_url( 'admin.php' )
					),
					'seovaultseo_404_redirect_' . $item['id']
				);
				$delete_url   = wp_nonce_url(
					add_query_arg(
						array(
							'page'   => 'seovault-ai-general',
							'tab'    => 'vtab-404-monitor',
							'action' => 'delete',
							'log'    => (int) $item['id'],
						),
						admin_url( 'admin.php' )
					),
					'seovaultseo_404_delete_' . $item['id']
				);

				$actions = array(
					'<a href="' . esc_url( $redirect_url ) . '" class="button button-small">' . esc_html__( 'Redirect', 'seovault-ai' ) . '</a>',
					'<a href="' . esc_url( $delete_url ) . '" style="color:#a00;" data-seovaultseo-confirm="' . esc_attr__( 'Delete this log entry?', 'seovault-ai' ) . '">' . esc_html__( 'Delete', 'seovault-ai' ) . '</a>',
				);

				return implode( ' | ', $actions );

			default:
				return esc_html( $item[ $column_name ] ?? '' );
		}
	}

	/**
	 * Render the checkbox column.
	 *
	 * @param array $item Row data.
	 * @return string
	 */
	public function column_cb( $item ) {
		return sprintf(
			'<label class="seovaultseo-check"><input type="checkbox" name="log[]" value="%d" /><span></span></label>',
			(int) $item['id']
		);
	}

	/**
	 * Prepare items for display.
	 */
	public function prepare_items() {
		$per_page = $this->get_items_per_page( 'seovaultseo_404_monitor_per_page', 20 );

		// Handle bulk action.
		$this->process_bulk_action();

		// Get current page.
		// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Admin list table pagination/sort/search; capability checked on page.
		$paged = isset( $_GET['paged'] ) ? max( 1, absint( wp_unslash( $_GET['paged'] ) ) ) : 1;

		// Get sorting.
		$orderby = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'id';
		$order   = isset( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'DESC';

		// Get search.
		$search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		$result = Db::get_logs(
			array(
				'orderby' => $orderby,
				'order'   => $order,
				'limit'   => $per_page,
				'paged'   => $paged,
				'search'  => $search,
			)
		);

		$this->items       = $result['logs'];
		$this->total_items = (int) $result['count'];

		$this->set_pagination_args(
			array(
				'total_items' => $this->total_items,
				'per_page'    => $per_page,
				'total_pages' => max( 1, ceil( $this->total_items / $per_page ) ),
			)
		);

		$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
	}

	/**
	 * Process bulk and single actions.
	 */
	private function process_bulk_action() {
		$action = $this->current_action();

		if ( ! $action ) {
			return;
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		// Verify the bulk nonce before reading identifiers or mutating the table.
		$nonce = isset( $_REQUEST['_wpnonce'] )
			? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) )
			: '';
		if ( '' === $nonce || ! wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) ) {
			return;
		}

		if ( 'delete' === $action ) {
			$ids = isset( $_REQUEST['log'] ) ? array_map( 'absint', (array) wp_unslash( $_REQUEST['log'] ) ) : array();
			if ( ! empty( $ids ) ) {
				$count = Db::delete_log( $ids );
				add_settings_error(
					'seovault_seo_404',
					'deleted',
					sprintf(
						/* translators: %d: number of deleted entries */
						_n( '%d log entry deleted.', '%d log entries deleted.', $count, 'seovault-ai' ),
						$count
					),
					'updated'
				);
			}
		}
	}

	/**
	 * Override bulk actions dropdown to add the custom select class.
	 *
	 * @param string $which Top or bottom.
	 */
	public function bulk_actions( $which = '' ) {
		if ( is_null( $this->_actions ) ) {
			$actions = array();
			foreach ( $this->get_bulk_actions() as $key => $value ) {
				$actions[ $key ] = is_array( $value ) ? $value['label'] : $value;
			}
			$this->_actions = $actions;
		}

		$two = '';
		if ( empty( $this->_actions ) ) {
			return;
		}
		if ( 'top' === $which || 'bottom' === $which ) {
			$two = '2';
		}
		?>
		<label for="bulk-action-selector-<?php echo esc_attr( $which ); ?>" class="screen-reader-text"><?php esc_html_e( 'Select bulk action', 'seovault-ai' ); ?></label>
		<select name="action<?php echo esc_attr( $two ); ?>" id="bulk-action-selector-<?php echo esc_attr( $which ); ?>" class="seovaultseo-select seovaultseo-select-small">
			<option value="-1"><?php esc_html_e( 'Bulk actions', 'seovault-ai' ); ?></option>
			<?php foreach ( $this->_actions as $key => $value ) : ?>
				<option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $value ); ?></option>
			<?php endforeach; ?>
		</select>
		<?php
		submit_button( __( 'Apply', 'seovault-ai' ), 'action', '', false, array( 'id' => "doaction$two" ) );
		echo "\n";
	}

	/**
	 * Display a search box.
	 *
	 * @param string $text     Button text.
	 * @param string $input_id Input ID.
	 */
	public function search_box( $text, $input_id ) {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended -- WP_List_Table search box; value escaped in output below.
		$s = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : '';
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
		?>
		<p class="search-box">
			<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_html( $text ); ?>:</label>
			<input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s" value="<?php echo esc_attr( $s ); ?>" />
			<?php submit_button( $text, '', '', false, array( 'id' => 'search-submit' ) ); ?>
		</p>
		<?php
	}
}
