<?php
/**
 * Signed cart recovery URLs for abandoned-cart emails.
 *
 * @package CartCue
 */

namespace CartCue;

defined( 'ABSPATH' ) || exit;

final class CartRecovery {

	public static function init(): void {
		add_action( 'template_redirect', [ __CLASS__, 'maybe_restore_cart' ], 5 );
	}

	public static function signed_url( int $cart_id ): string {
		if ( $cart_id < 1 ) {
			return wc_get_cart_url();
		}

		$sig = self::signature( $cart_id );

		return add_query_arg(
			[
				'cartcue_recover' => (string) $cart_id,
				'cartcue_sig'     => $sig,
			],
			wc_get_checkout_url()
		);
	}

	public static function signature( int $cart_id ): string {
		return hash_hmac( 'sha256', (string) $cart_id, wp_salt( 'cartcue_recover' ) );
	}

	public static function verify( int $cart_id, string $sig ): bool {
		return hash_equals( self::signature( $cart_id ), $sig );
	}

	public static function maybe_restore_cart(): void {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$cart_id = isset( $_GET['cartcue_recover'] ) ? absint( wp_unslash( $_GET['cartcue_recover'] ) ) : 0;
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$sig = isset( $_GET['cartcue_sig'] ) ? sanitize_text_field( wp_unslash( $_GET['cartcue_sig'] ) ) : '';

		if ( ! $cart_id || ! $sig || ! self::verify( $cart_id, $sig ) ) {
			return;
		}

		if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
			return;
		}

		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$row = $wpdb->get_row(
			$wpdb->prepare(
				'SELECT * FROM %i WHERE id = %d AND status IN (%s, %s, %s)',
				DB::carts(),
				$cart_id,
				'active',
				'triggered',
				'checkout_started'
			),
			ARRAY_A
		);

		if ( ! $row || empty( $row['cart_contents'] ) ) {
			return;
		}

		$items = json_decode( $row['cart_contents'], true );
		if ( ! is_array( $items ) || empty( $items ) ) {
			return;
		}

		foreach ( $items as $item ) {
			$product_id   = (int) ( $item['product_id'] ?? 0 );
			$variation_id = (int) ( $item['variation_id'] ?? 0 );
			$qty          = max( 1, (int) ( $item['quantity'] ?? 1 ) );
			if ( ! $product_id ) {
				continue;
			}

			$in_cart = false;
			foreach ( WC()->cart->get_cart() as $cart_item ) {
				if ( (int) ( $cart_item['product_id'] ?? 0 ) === $product_id
					&& (int) ( $cart_item['variation_id'] ?? 0 ) === $variation_id ) {
					$in_cart = true;
					break;
				}
			}
			if ( ! $in_cart ) {
				WC()->cart->add_to_cart( $product_id, $qty, $variation_id );
			}
		}

		if ( ! empty( $row['email'] ) && is_email( $row['email'] ) ) {
			$customer = WC()->customer;
			if ( $customer ) {
				$customer->set_billing_email( $row['email'] );
				$customer->save();
			}
			if ( WC()->session ) {
				WC()->session->set( 'billing_email', $row['email'] );
			}
		}

		wp_safe_redirect( remove_query_arg( [ 'cartcue_recover', 'cartcue_sig' ] ) );
		exit;
	}

	/**
	 * Load cart row for variables / recovery.
	 *
	 * @return array<string,mixed>|null
	 */
	public static function get_cart_row( int $cart_id ): ?array {
		if ( $cart_id < 1 ) {
			return null;
		}

		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$row = $wpdb->get_row(
			$wpdb->prepare( 'SELECT * FROM %i WHERE id = %d', DB::carts(), $cart_id ),
			ARRAY_A
		);

		return $row ?: null;
	}
}
