<?php
/**
 * Reward Failure Admin Notice.
 *
 * Displays admin notices for failed reward transactions and provides
 * AJAX handlers for dismissing failures and manually issuing coupons.
 *
 * @package Ugcify\Admin
 */

namespace Ugcify\Admin;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class RewardFailureNotice
 */
class RewardFailureNotice {

	/**
	 * Constructor — registers hooks.
	 */
	public function __construct() {
		add_action( 'admin_notices', array( $this, 'render_failure_notices' ) );
		add_action( 'wp_ajax_ugcify_dismiss_reward_failure', array( $this, 'handle_dismiss' ) );
		add_action( 'wp_ajax_ugcify_manual_issue_coupon', array( $this, 'handle_manual_issue' ) );
	}

	/**
	 * Render admin notices for any un-retried or double-failed reward transactions.
	 *
	 * @return void
	 */
	public function render_failure_notices(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$failures = get_option( 'ugcify_reward_failures', array() );
		if ( empty( $failures ) ) {
			return;
		}

		foreach ( $failures as $index => $failure ) {
			$this->render_single_notice( $index, $failure );
		}
	}

	/**
	 * Render a single notice for one failure record.
	 *
	 * - If $failure['retried'] === false: yellow warning — auto-retry pending.
	 * - If $failure['retried'] === true: red error — retry failed, manual action required.
	 *
	 * @param int   $index   Array index of the failure record.
	 * @param array $failure Failure record data.
	 * @return void
	 */
	private function render_single_notice( int $index, array $failure ): void {
		$type  = $failure['retried'] ? 'error' : 'warning';
		$label = $failure['retried']
			? __( 'Reward failed after retry — manual action required', 'ugcify' )
			: __( 'Reward transaction failed — auto-retry scheduled', 'ugcify' );

		$nonce   = wp_create_nonce( 'ugcify_reward_failure_' . $index );
		$dismiss = admin_url( 'admin-ajax.php?action=ugcify_dismiss_reward_failure&index=' . $index . '&_wpnonce=' . $nonce );
		?>
		<div class="notice notice-<?php echo esc_attr( $type ); ?> is-dismissible">
			<p>
				<strong><?php echo esc_html( $label ); ?></strong><br>
				<?php
				printf(
					/* translators: 1: review ID, 2: user email, 3: reason */
					esc_html__( 'Review #%1$s · Customer: %2$s · Reason: %3$s', 'ugcify' ),
					esc_html( $failure['review_id'] ),
					esc_html( $failure['user_email'] ),
					esc_html( $failure['reason'] )
				);
				?>
			</p>
			<?php if ( $failure['retried'] ) : ?>
			<p>
				<button class="button button-primary"
						data-action="ugcify_manual_issue_coupon"
						data-review="<?php echo esc_attr( $failure['review_id'] ); ?>"
						data-email="<?php echo esc_attr( $failure['user_email'] ); ?>"
						data-index="<?php echo esc_attr( $index ); ?>"
						data-nonce="<?php echo esc_attr( wp_create_nonce( 'ugcify_manual_issue_' . $index ) ); ?>">
					<?php esc_html_e( 'Manually issue coupon', 'ugcify' ); ?>
				</button>
				&nbsp;
				<a href="<?php echo esc_url( $dismiss ); ?>"><?php esc_html_e( 'Dismiss', 'ugcify' ); ?></a>
			</p>
			<?php endif; ?>
		</div>
		<?php
	}

	/**
	 * AJAX: dismiss a specific failure record.
	 *
	 * @return void
	 */
	public function handle_dismiss(): void {
		$index = absint( $_GET['index'] ?? -1 ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Index is used only to construct the nonce action; nonce verifies the full request below.
		check_admin_referer( 'ugcify_reward_failure_' . $index );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( -1 );
		}

		$failures = get_option( 'ugcify_reward_failures', array() );
		if ( isset( $failures[ $index ] ) ) {
			array_splice( $failures, $index, 1 );
			update_option( 'ugcify_reward_failures', array_values( $failures ), false );
		}

		wp_safe_redirect( wp_get_referer() ?: admin_url() );
		exit;
	}

	/**
	 * AJAX: manually issue a coupon for a specific failure record.
	 *
	 * @return void
	 */
	public function handle_manual_issue(): void {
		$index = absint( $_POST['index'] ?? -1 ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Index is used only to construct the nonce action; nonce verifies the full request below.
		check_ajax_referer( 'ugcify_manual_issue_' . $index );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'forbidden', 403 );
		}

		$failures = get_option( 'ugcify_reward_failures', array() );
		$failure  = $failures[ $index ] ?? null;

		if ( ! $failure ) {
			wp_send_json_error( 'not_found' );
		}

		$coupon_code = \Ugcify\Rewards\RewardCoupon::generate_for_review(
			absint( $failure['review_id'] ),
			sanitize_email( $failure['user_email'] )
		);

		if ( $coupon_code ) {
			array_splice( $failures, $index, 1 );
			update_option( 'ugcify_reward_failures', array_values( $failures ), false );
			wp_send_json_success( array( 'coupon_code' => $coupon_code ) );
		} else {
			wp_send_json_error( 'coupon_generation_failed' );
		}
	}
}
