<?php
/**
 * Service reminders admin screen: page render and row-action handlers.
 *
 * Renders the reminder worklist (a WP_List_Table with the Overdue / Due soon /
 * All status tabs) and processes the Mark handled and Dismiss row actions. Both
 * are nonce-protected GET links whose handlers verify a per-record nonce and the
 * manage-reminders capability, load and re-verify the reminder row before
 * mutating it, then Post/Redirect/Get back to the worklist with a success flag.
 * Render is capability-gated at the top so the whole surface is unreachable
 * without MANAGE_REMINDERS. Reminders are never hard-deleted; Mark handled and
 * Dismiss flip a terminal status only, keeping the row for vehicle history.
 *
 * @package WrenchPress
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class WrenchPress_Reminders_Admin_Page
 */
class WrenchPress_Reminders_Admin_Page {

	/**
	 * Admin page slug.
	 */
	const MENU_SLUG = 'wrenchpress-reminders';

	/**
	 * Per-record nonce base for the Mark handled action link. The reminder id is
	 * appended so each row carries a distinct nonce; the list table mints the
	 * matching link.
	 */
	const MARK_NONCE = 'wrenchpress_reminder_mark_';

	/**
	 * Per-record nonce base for the Dismiss action link. The reminder id is
	 * appended so each row carries a distinct nonce; the list table mints the
	 * matching link.
	 */
	const DISMISS_NONCE = 'wrenchpress_reminder_dismiss_';

	/**
	 * Dispatch the Mark handled and Dismiss row actions on page load (before
	 * output). Both are nonce-protected GET links; the specific handler each
	 * branch calls verifies its own nonce before any write.
	 *
	 * @return void
	 */
	public static function handle_load() {
		// phpcs:disable WordPress.Security.NonceVerification -- the specific handler each branch calls verifies its own nonce before any write.
		$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : '';
		// phpcs:enable WordPress.Security.NonceVerification

		if ( 'mark_handled' === $action ) {
			self::handle_mark_handled();
		} elseif ( 'dismiss' === $action ) {
			self::handle_dismiss();
		}
	}

	/**
	 * Verify the per-record nonce and capability, load and re-verify the row,
	 * then mark the reminder handled (PRG).
	 *
	 * The order (id read -> check_admin_referer -> current_user_can -> load and
	 * re-verify the row -> mark_status -> PRG) is the plugin-wide write contract.
	 * Loading and re-verifying the reminder before mutating mitigates a crafted
	 * request that targets another vehicle's reminder.
	 *
	 * @return void
	 */
	private static function handle_mark_handled() {
		$id = isset( $_GET['reminder'] ) ? absint( wp_unslash( $_GET['reminder'] ) ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce checked immediately below.

		check_admin_referer( self::MARK_NONCE . $id );

		if ( ! current_user_can( WrenchPress_Capabilities::MANAGE_REMINDERS ) ) {
			wp_die( esc_html__( 'You do not have permission to do that.', 'pitdesk-repair-crm' ) );
		}

		if ( $id > 0 ) {
			$reminder = WrenchPress_Reminders_Repository::get( $id );

			if ( $reminder ) {
				WrenchPress_Reminders_Repository::mark_status( $id, 'handled' );
			}
		}

		self::redirect_to_list( 'all', 'reminder_handled' );
	}

	/**
	 * Verify the per-record nonce and capability, load and re-verify the row,
	 * then dismiss the reminder (PRG). Dismiss removes the row from the worklist
	 * but retains it for vehicle history (D-07).
	 *
	 * @return void
	 */
	private static function handle_dismiss() {
		$id = isset( $_GET['reminder'] ) ? absint( wp_unslash( $_GET['reminder'] ) ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce checked immediately below.

		check_admin_referer( self::DISMISS_NONCE . $id );

		if ( ! current_user_can( WrenchPress_Capabilities::MANAGE_REMINDERS ) ) {
			wp_die( esc_html__( 'You do not have permission to do that.', 'pitdesk-repair-crm' ) );
		}

		if ( $id > 0 ) {
			$reminder = WrenchPress_Reminders_Repository::get( $id );

			if ( $reminder ) {
				WrenchPress_Reminders_Repository::mark_status( $id, 'dismissed' );
			}
		}

		self::redirect_to_list( 'all', 'reminder_dismissed' );
	}

	/**
	 * Redirect back to the worklist with a status view and a success flag, then
	 * exit (PRG).
	 *
	 * @param string $bucket Status view to land on (e.g. 'overdue').
	 * @param string $flag   Query flag for the notice.
	 * @return void
	 */
	private static function redirect_to_list( $bucket, $flag ) {
		wp_safe_redirect(
			add_query_arg(
				array(
					'page'   => self::MENU_SLUG,
					'status' => $bucket,
					$flag    => 1,
				),
				admin_url( 'admin.php' )
			)
		);
		exit;
	}

	/**
	 * Render the reminders worklist screen. Capability-gated at the top so the
	 * whole surface is unreachable without MANAGE_REMINDERS.
	 *
	 * @return void
	 */
	public static function render() {
		if ( ! current_user_can( WrenchPress_Capabilities::MANAGE_REMINDERS ) ) {
			wp_die( esc_html__( 'You do not have permission to do that.', 'pitdesk-repair-crm' ) );
		}

		self::render_list();
	}

	/**
	 * Render the worklist list table with its status-view tabs.
	 *
	 * The list table's views() must be printed explicitly (it is not emitted by
	 * display()); a hidden page and status input keep the active filter across the
	 * search form.
	 *
	 * @return void
	 */
	private static function render_list() {
		$list_table = new WrenchPress_Reminders_List_Table();
		$list_table->prepare_items();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only filter carried across the search form.
		$status = isset( $_GET['status'] ) ? sanitize_key( wp_unslash( $_GET['status'] ) ) : '';

		echo '<div class="wrap">';
		echo '<h1 class="wp-heading-inline">' . esc_html__( 'Reminders', 'pitdesk-repair-crm' ) . '</h1>';
		echo '<hr class="wp-header-end">';

		self::maybe_render_list_notice();

		// Status tabs with counts. Not auto-printed by display().
		$list_table->views();

		echo '<form method="get">';
		echo '<input type="hidden" name="page" value="' . esc_attr( self::MENU_SLUG ) . '" />';

		if ( '' !== $status ) {
			echo '<input type="hidden" name="status" value="' . esc_attr( $status ) . '" />';
		}

		$list_table->display();
		echo '</form>';

		echo '</div>';
	}

	/**
	 * Render the success / error admin notice for the worklist PRG flags.
	 *
	 * @return void
	 */
	private static function maybe_render_list_notice() {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended -- status flags come from our own PRG redirects.
		if ( isset( $_GET['reminder_handled'] ) ) {
			$message = __( 'Reminder marked handled.', 'pitdesk-repair-crm' );
			$class   = 'notice-success';
		} elseif ( isset( $_GET['reminder_dismissed'] ) ) {
			$message = __( 'Reminder dismissed.', 'pitdesk-repair-crm' );
			$class   = 'notice-success';
		} elseif ( isset( $_GET['reminder_error'] ) ) {
			$message = __( 'The reminder could not be saved. Please try again.', 'pitdesk-repair-crm' );
			$class   = 'notice-error';
		} else {
			return;
		}
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		echo '<div class="notice ' . esc_attr( $class ) . ' is-dismissible"><p>' . esc_html( $message ) . '</p></div>';
	}
}
