<?php
/**
 * Free-tier frontend dealer dashboard.
 *
 * Per ADR-18: both tiers have a frontend dashboard. Free covers
 * submit/edit/delete; Pro adds analytics + bulk actions.
 *
 * Visitors render the dashboard via the `[trx_ad_dealer_dashboard]`
 * shortcode. The current logged-in user's authored listings are shown
 * with edit/delete links and a "submit new listing" call-to-action.
 * Anonymous visitors get a login prompt.
 *
 * @package ThemeREX\AutoDealer
 * @version 1.0.0
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Frontend;

defined( 'ABSPATH' ) || exit;
use ThemeREX\AutoDealer\PostTypes\VehiclePostType;

/**
 * Shortcode renderer for the frontend dealer dashboard.
 */
final class DealerDashboard {

	/** Shortcode tag exposed to themes/page editors. */
	public const SHORTCODE = 'trx_ad_dealer_dashboard';

	/**
	 * Nonce action for the dashboard delete link. A FIXED action (no post ID
	 * embedded) so handleDeleteRequest() can verify the nonce before reading
	 * any other request input; per-listing authorization is enforced
	 * separately via current_user_can( 'delete_post', $id ).
	 */
	private const DELETE_NONCE_ACTION = 'trx_ad_delete_listing';

	/**
	 * Register hooks.
	 */
	public function register(): void {
		add_shortcode( self::SHORTCODE, array( $this, 'renderShortcode' ) );
		add_action( 'init', array( $this, 'handleDeleteRequest' ) );
	}

	/**
	 * Shortcode entry point.
	 *
	 * @param array<string,mixed>|string $atts Shortcode attributes.
	 * @return string
	 */
	public function renderShortcode( $atts = array() ): string {
		$atts = shortcode_atts(
			array(
				'per_page' => 10,
			),
			is_array( $atts ) ? $atts : array(),
			self::SHORTCODE
		);

		if ( ! is_user_logged_in() ) {
			return wp_kses( self::renderLoginPrompt(), \ThemeREX\AutoDealer\allowedHtml() );
		}

		// Escaped at the callback's return boundary -- WP outputs shortcode
		// return values directly (wp.org 2026-08 review round 4).
		return wp_kses(
			self::renderDashboard( get_current_user_id(), max( 1, (int) $atts['per_page'] ) ),
			\ThemeREX\AutoDealer\allowedHtml()
		);
	}

	/**
	 * Render the listing-management UI for a given user.
	 *
	 * @param int $user_id  WP user ID.
	 * @param int $per_page Listings per page.
	 * @return string
	 */
	public static function renderDashboard( int $user_id, int $per_page = 10 ): string {
		$paged = isset( $_GET['trx_ad_dashboard_page'] )
			? max( 1, (int) sanitize_text_field( wp_unslash( (string) $_GET['trx_ad_dashboard_page'] ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			: 1;

		$query = new \WP_Query(
			array(
				'author'         => $user_id,
				'post_type'      => VehiclePostType::POST_TYPE,
				'post_status'    => array( 'publish', 'pending', 'draft' ),
				'posts_per_page' => $per_page,
				'paged'          => $paged,
				'orderby'        => 'date',
				'order'          => 'DESC',
			)
		);

		ob_start();
		?>
		<section class="trx-ad-dashboard" data-trx-ad-dashboard>
			<header class="trx-ad-dashboard__header">
				<h2 class="trx-ad-dashboard__heading">
					<?php esc_html_e( 'Your Listings', 'trx-auto-dealer' ); ?>
				</h2>
				<a class="trx-ad-btn trx-ad-btn--primary" href="<?php echo esc_url( admin_url( 'post-new.php?post_type=' . VehiclePostType::POST_TYPE ) ); ?>">
					<?php esc_html_e( 'Submit a Listing', 'trx-auto-dealer' ); ?>
				</a>
			</header>

			<?php if ( ! $query->have_posts() ) : ?>
				<p class="trx-ad-dashboard__empty"><?php esc_html_e( "You haven't submitted any listings yet.", 'trx-auto-dealer' ); ?></p>
			<?php else : ?>
				<table class="trx-ad-dashboard__table">
					<thead>
						<tr>
							<th><?php esc_html_e( 'Title', 'trx-auto-dealer' ); ?></th>
							<th><?php esc_html_e( 'Status', 'trx-auto-dealer' ); ?></th>
							<th><?php esc_html_e( 'Date', 'trx-auto-dealer' ); ?></th>
							<th class="trx-ad-dashboard__actions-col"><?php esc_html_e( 'Actions', 'trx-auto-dealer' ); ?></th>
						</tr>
					</thead>
					<tbody>
						<?php
						while ( $query->have_posts() ) :
							$query->the_post();
							$post_id = (int) get_the_ID();
							?>
							<tr>
								<td>
									<a href="<?php echo esc_url( (string) get_permalink( $post_id ) ); ?>"><?php echo esc_html( get_the_title( $post_id ) ); ?></a>
								</td>
								<td>
									<span class="trx-ad-dashboard__status trx-ad-dashboard__status--<?php echo esc_attr( (string) get_post_status( $post_id ) ); ?>">
										<?php echo esc_html( ucfirst( (string) get_post_status( $post_id ) ) ); ?>
									</span>
								</td>
								<td><?php echo esc_html( (string) get_the_date( '', $post_id ) ); ?></td>
								<td class="trx-ad-dashboard__actions">
									<?php if ( current_user_can( 'edit_post', $post_id ) ) : ?>
										<a class="trx-ad-btn trx-ad-btn--ghost" href="<?php echo esc_url( (string) get_edit_post_link( $post_id ) ); ?>">
											<?php esc_html_e( 'Edit', 'trx-auto-dealer' ); ?>
										</a>
									<?php endif; ?>
									<?php if ( current_user_can( 'delete_post', $post_id ) ) : ?>
										<?php
										$delete_url = wp_nonce_url(
											add_query_arg( array( 'trx_ad_delete' => $post_id ), (string) get_permalink() ),
											self::DELETE_NONCE_ACTION
										);
										?>
										<a class="trx-ad-btn trx-ad-btn--danger" href="<?php echo esc_url( $delete_url ); ?>"
											data-trx-ad-confirm="<?php echo esc_attr( __( 'Permanently delete this listing?', 'trx-auto-dealer' ) ); ?>">
											<?php esc_html_e( 'Delete', 'trx-auto-dealer' ); ?>
										</a>
									<?php endif; ?>
								</td>
							</tr>
							<?php
						endwhile;
						wp_reset_postdata();
						?>
					</tbody>
				</table>

				<?php if ( $query->max_num_pages > 1 ) : ?>
					<nav class="trx-ad-dashboard__pagination" aria-label="<?php esc_attr_e( 'Dashboard pagination', 'trx-auto-dealer' ); ?>">
						<?php
						$base = remove_query_arg( 'trx_ad_dashboard_page' );
						for ( $i = 1; $i <= $query->max_num_pages; $i++ ) {
							$url   = add_query_arg( 'trx_ad_dashboard_page', $i, $base );
							$class = $i === $paged ? ' trx-ad-pagination__page--current' : '';
							printf(
								'<a class="trx-ad-pagination__page%s" href="%s">%d</a>',
								esc_attr( $class ),
								esc_url( $url ),
								(int) $i
							);
						}
						?>
					</nav>
				<?php endif; ?>
			<?php endif; ?>

			<?php
			/**
			 * Fires after the free dashboard renders. Pro hooks here to
			 * append analytics widgets, bulk-action toolbars, etc.
			 *
			 * @param int $user_id Current dashboard owner.
			 */
			do_action( 'trx_ad_dealer_dashboard_after', $user_id );
			?>
		</section>
		<?php
		return (string) ob_get_clean();
	}

	/**
	 * Login prompt for anonymous visitors.
	 */
	private static function renderLoginPrompt(): string {
		$login_url = wp_login_url( (string) ( wp_get_referer() ?: home_url( '/' ) ) );
		return sprintf(
			'<section class="trx-ad-dashboard trx-ad-dashboard--anon"><p>%1$s</p><p><a class="trx-ad-btn trx-ad-btn--primary" href="%2$s">%3$s</a></p></section>',
			esc_html__( 'Please log in to manage your listings.', 'trx-auto-dealer' ),
			esc_url( $login_url ),
			esc_html__( 'Log in', 'trx-auto-dealer' )
		);
	}

	/**
	 * Handle a `?trx_ad_delete=ID` request from the dashboard.
	 *
	 * Validates nonce + capability, soft-deletes via wp_trash_post (so the
	 * user can restore from admin if they regret it), then redirects back.
	 */
	public function handleDeleteRequest(): void {
		if ( is_admin() || ! isset( $_GET['trx_ad_delete'], $_GET['_wpnonce'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}

		// 1. Nonce first — verified before ANY other request input is read.
		// The action is a fixed string (see DELETE_NONCE_ACTION), so no
		// request value participates in building it.
		$nonce = sanitize_text_field( wp_unslash( (string) $_GET['_wpnonce'] ) );
		if ( ! wp_verify_nonce( $nonce, self::DELETE_NONCE_ACTION ) ) {
			wp_die( esc_html__( 'Invalid request.', 'trx-auto-dealer' ), 400 );
		}

		// 2. Validate the listing ID.
		$post_id = absint( wp_unslash( (string) $_GET['trx_ad_delete'] ) );
		if ( $post_id < 1 ) {
			wp_die( esc_html__( 'Invalid request.', 'trx-auto-dealer' ), 400 );
		}

		// 3. Authorization — per-listing capability, independent of the nonce.
		if ( ! current_user_can( 'delete_post', $post_id ) ) {
			wp_die( esc_html__( 'You are not allowed to delete this listing.', 'trx-auto-dealer' ), 403 );
		}

		// 4. Only vehicle listings can be deleted through this handler.
		$post = get_post( $post_id );
		if ( null === $post || VehiclePostType::POST_TYPE !== $post->post_type ) {
			return;
		}

		wp_trash_post( $post_id );

		wp_safe_redirect( remove_query_arg( array( 'trx_ad_delete', '_wpnonce' ) ) );
		exit;
	}
}
