<?php
/**
 * Email order actions.
 *
 * @package FoodOrd
 */

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

/**
 * Adds a track-order action to the customer processing-order email.
 */
class Foodord_Email_Order_Actions {
	/**
	 * Query flag used for email-based track links.
	 */
	const TRACK_EMAIL_FLAG = 'foodord_track_email';

	/**
	 * Register hooks.
	 */
	public function __construct() {
		add_action( 'woocommerce_email_before_order_table', array( $this, 'render_track_order_button' ), 8, 4 );
		add_filter( 'woocommerce_email_styles', array( $this, 'append_email_styles' ), 10, 2 );
		add_filter( 'woocommerce_order_received_verify_known_shoppers', array( $this, 'maybe_allow_email_track_guest_access' ) );
		add_filter( 'woocommerce_order_email_verification_required', array( $this, 'maybe_skip_track_order_email_verification' ), 10, 3 );
	}

	/**
	 * Output the track-order action for processing emails.
	 *
	 * @param mixed $order         WooCommerce order object.
	 * @param mixed $sent_to_admin Whether the email is sent to the store admin.
	 * @param mixed $plain_text    Whether the email is plain text.
	 * @param mixed $email         WooCommerce email instance.
	 */
	public function render_track_order_button( $order, $sent_to_admin, $plain_text, $email ) {
		if ( ! $this->should_render_track_order_action( $order, $sent_to_admin, $email ) ) {
			return;
		}

		$track_url = $this->get_track_order_url( $order );
		if ( '' === $track_url ) {
			return;
		}

		if ( $plain_text ) {
			echo "\n" . esc_html__( 'Track your order:', 'foodord' ) . ' ' . esc_url_raw( $track_url ) . "\n\n";
			return;
		}
		?>
		<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation" class="foodord-email-order-actions">
			<tr>
				<td class="foodord-email-order-actions__cell">
					<a class="foodord-email-order-actions__button" href="<?php echo esc_url( $track_url ); ?>">
						<?php esc_html_e( 'Track Order', 'foodord' ); ?>
						<span class="foodord-email-order-actions__icon" aria-hidden="true">
							<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" role="presentation">
								<path d="M3 9L9 3" stroke="#ffffff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
								<path d="M4.5 3H9V7.5" stroke="#ffffff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
							</svg>
						</span>
					</a>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Append custom button styles to WooCommerce emails.
	 *
	 * @param string $css   Email CSS.
	 * @param mixed  $email WooCommerce email instance.
	 * @return string
	 */
	public function append_email_styles( $css, $email ) {
		if ( ! $this->is_processing_order_email( $email ) ) {
			return $css;
		}

		$css .= '
.email-introduction {
	padding-bottom: 8px;
}

.email-introduction p:last-child {
	margin-bottom: 0;
}

.email-introduction + .foodord-email-order-actions {
	margin-top: 0;
}

.foodord-email-order-actions {
	margin: 0 0 18px;
	mso-table-lspace: 0;
	mso-table-rspace: 0;
}

.foodord-email-order-actions__cell {
	padding: 0 0 10px;
}

.foodord-email-order-actions__button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 14px 22px;
	border-radius: 999px;
	background: #111827;
	border: 1px solid #111827;
	color: #ffffff !important;
	font-size: 14px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: 0.01em;
	text-decoration: none;
}

.foodord-email-order-actions__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 12px;
	height: 12px;
	line-height: 0;
}
';

		return $css;
	}

	/**
	 * Decide whether the action should be rendered.
	 *
	 * @param mixed $order         WooCommerce order object.
	 * @param mixed $sent_to_admin Whether the email is sent to the store admin.
	 * @param mixed $email         WooCommerce email instance.
	 * @return bool
	 */
	private function should_render_track_order_action( $order, $sent_to_admin, $email ) {
		if ( ! is_a( $order, 'WC_Order' ) ) {
			return false;
		}

		if ( $sent_to_admin ) {
			return false;
		}

		return $this->is_processing_order_email( $email );
	}

	/**
	 * Check if the email is the customer processing-order email.
	 *
	 * @param mixed $email WooCommerce email instance.
	 * @return bool
	 */
	private function is_processing_order_email( $email ) {
		return is_object( $email ) && isset( $email->id ) && 'customer_processing_order' === $email->id;
	}

	/**
	 * Build the customer-facing tracking URL.
	 *
	 * @param WC_Order $order WooCommerce order object.
	 * @return string
	 */
	private function get_track_order_url( $order ) {
		$track_url = '';

		if ( is_object( $order ) && method_exists( $order, 'get_checkout_order_received_url' ) ) {
			$track_url = $order->get_checkout_order_received_url();
			if ( '' !== $track_url ) {
				$track_url = add_query_arg( self::TRACK_EMAIL_FLAG, '1', $track_url );
			}
		}

		/**
		 * Filter the tracking URL used in the customer processing-order email.
		 *
		 * @param string   $track_url Track-order URL.
		 * @param WC_Order $order     WooCommerce order object.
		 */
		$track_url = apply_filters( 'foodord_processing_order_email_track_url', $track_url, $order );

		return is_string( $track_url ) ? $track_url : '';
	}

	/**
	 * Allow valid email-track links to open without forcing account login.
	 *
	 * @param bool $verify_known_shoppers Whether known shoppers must log in.
	 * @return bool
	 */
	public function maybe_allow_email_track_guest_access( $verify_known_shoppers ) {
		if ( ! $verify_known_shoppers ) {
			return false;
		}

		return $this->get_track_order_request_order() ? false : (bool) $verify_known_shoppers;
	}

	/**
	 * Skip order-email verification for valid email-track links.
	 *
	 * @param bool     $required Whether verification is required.
	 * @param WC_Order $order    WooCommerce order object.
	 * @param string   $context  Verification context.
	 * @return bool
	 */
	public function maybe_skip_track_order_email_verification( $required, $order, $context ) {
		if ( ! $required || 'order-received' !== $context || ! is_a( $order, 'WC_Order' ) ) {
			return (bool) $required;
		}

		$request_order = $this->get_track_order_request_order();
		if ( $request_order && (int) $request_order->get_id() === (int) $order->get_id() ) {
			return false;
		}

		return (bool) $required;
	}

	/**
	 * Resolve the current email-track request order when the link is valid.
	 *
	 * @return WC_Order|false
	 */
	private function get_track_order_request_order() {
		$flag = filter_input( INPUT_GET, self::TRACK_EMAIL_FLAG, FILTER_SANITIZE_FULL_SPECIAL_CHARS );
		$flag = is_string( $flag ) ? sanitize_text_field( wp_unslash( $flag ) ) : '';
		if ( '' === $flag ) {
			return false;
		}

		$order_id  = absint( get_query_var( 'order-received' ) );
		$order_key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
		$order_key = is_string( $order_key ) ? wc_clean( wp_unslash( $order_key ) ) : '';

		if ( $order_id <= 0 || '' === $order_key ) {
			return false;
		}

		$order = wc_get_order( $order_id );
		if ( ! is_a( $order, 'WC_Order' ) ) {
			return false;
		}

		if ( ! hash_equals( $order->get_order_key(), $order_key ) ) {
			return false;
		}

		return $order;
	}
}
