<?php
/**
 * Branded marketing unsubscribe confirmation page.
 *
 * @package CartCue
 */

namespace CartCue;

defined( 'ABSPATH' ) || exit;

final class Unsubscribe {

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

	/**
	 * Signed one-click URL for the given email (used in {{shop.unsubscribe_url}}).
	 */
	public static function signed_url( string $email ): string {
		$email = strtolower( trim( $email ) );
		if ( ! is_email( $email ) ) {
			return '';
		}

		$encoded = rawurlencode( base64_encode( $email ) );
		$sig     = hash_hmac( 'sha256', $email, wp_salt( 'cartcue_unsub' ) );

		return add_query_arg(
			[
				'cartcue_unsubscribe' => '1',
				'e'                   => $encoded,
				'sig'                 => $sig,
			],
			home_url( '/' )
		);
	}

	public static function is_suppressed( string $email ): bool {
		$email = strtolower( trim( $email ) );
		if ( '' === $email || ! is_email( $email ) ) {
			return false;
		}
		$cache_key = 'cartcue_supp_' . md5( $email );
		$cached    = wp_cache_get( $cache_key, 'cartcue' );
		if ( false !== $cached ) {
			return (bool) $cached;
		}
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- cached below.
		$hit = (int) $wpdb->get_var(
			$wpdb->prepare(
				'SELECT 1 FROM %i WHERE email = %s AND status = 0 LIMIT 1',
				DB::consents(),
				$email
			)
		);
		wp_cache_set( $cache_key, $hit, 'cartcue', HOUR_IN_SECONDS );
		return (bool) $hit;
	}

	public static function maybe_handle_request(): void {
		if ( empty( $_GET['cartcue_unsubscribe'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}

		$encoded = isset( $_GET['e'] ) ? sanitize_text_field( wp_unslash( $_GET['e'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$sig     = isset( $_GET['sig'] ) ? sanitize_text_field( wp_unslash( $_GET['sig'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$request_method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : '';
		$is_one_click_post = 'POST' === strtoupper( $request_method )
			&& isset( $_POST['List-Unsubscribe'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
			&& 'One-Click' === sanitize_text_field( wp_unslash( $_POST['List-Unsubscribe'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

		$raw = base64_decode( rawurldecode( $encoded ), true );
		if ( ! is_string( $raw ) || ! is_email( $raw ) ) {
			self::render_page(
				__( 'Invalid link', 'cartcue-sales-automation' ),
				__( 'This unsubscribe link is invalid or has expired.', 'cartcue-sales-automation' ),
				false
			);
		}

		$email  = strtolower( trim( $raw ) );
		$expect = hash_hmac( 'sha256', $email, wp_salt( 'cartcue_unsub' ) );
		if ( ! hash_equals( $expect, $sig ) ) {
			self::render_page(
				__( 'Invalid link', 'cartcue-sales-automation' ),
				__( 'This unsubscribe link is invalid or has expired.', 'cartcue-sales-automation' ),
				false
			);
		}

		if ( $is_one_click_post ) {
			self::suppress( $email );
			status_header( 200 );
			nocache_headers();
			exit;
		}

		if ( 'POST' === strtoupper( $request_method ) ) {
			check_admin_referer( 'cartcue_unsubscribe_reason', 'cartcue_unsub_nonce' );
			$reason = sanitize_key( wp_unslash( $_POST['cartcue_unsub_reason'] ?? '' ) );
			$other  = sanitize_text_field( wp_unslash( $_POST['cartcue_unsub_other'] ?? '' ) );
			$wf_id  = absint( wp_unslash( $_POST['cartcue_unsub_wf'] ?? 0 ) );
			if ( UnsubscribeReasons::is_valid_reason( $reason ) ) {
				UnsubscribeReasons::save( $email, $reason, $other, $wf_id );
				JourneyRecorder::record( $email, 'unsubscribed', UnsubscribeReasons::format_label( [ 'reason' => $reason, 'other_text' => $other ] ), $wf_id );
			}
			self::suppress( $email );
			self::render_page(
				__( 'You are unsubscribed', 'cartcue-sales-automation' ),
				__( 'You will no longer receive marketing emails from this store. Thank you for your feedback.', 'cartcue-sales-automation' ),
				true
			);
		}

		if ( self::is_suppressed( $email ) ) {
			self::render_page(
				__( 'You are unsubscribed', 'cartcue-sales-automation' ),
				__( 'You will no longer receive marketing emails from this store.', 'cartcue-sales-automation' ),
				true
			);
		}

		if ( ! empty( $_GET['skip_reason'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			self::suppress( $email );
			self::render_page(
				__( 'You are unsubscribed', 'cartcue-sales-automation' ),
				__( 'You will no longer receive marketing emails from this store.', 'cartcue-sales-automation' ),
				true
			);
		}

		self::render_reason_form( $email, $encoded, $sig );
	}

	private static function render_reason_form( string $email, string $encoded, string $sig ): void {
		$shop_name = get_bloginfo( 'name' );
		$shop_url  = home_url( '/' );
		$logo_url  = Variables::get_store_logo_url();
		$brand     = '#534AB7';
		$labels    = UnsubscribeReasons::reason_labels();
		$wf_id     = isset( $_GET['wf'] ) ? absint( wp_unslash( $_GET['wf'] ) ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		status_header( 200 );
		nocache_headers();
		header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );

		echo '<!DOCTYPE html><html lang="' . esc_attr( get_bloginfo( 'language' ) ) . '"><head>';
		echo '<meta charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
		echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
		echo '<title>' . esc_html__( 'Unsubscribe', 'cartcue-sales-automation' ) . ' — ' . esc_html( $shop_name ) . '</title>';
		echo '<style>
			body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#f5f4fa;color:#1a1830}
			.cc-unsub{max-width:480px;margin:48px auto;padding:0 16px}
			.cc-unsub__card{background:#fff;border-radius:14px;border:1px solid #e5e4f0;overflow:hidden;box-shadow:0 8px 32px rgba(83,74,183,.08)}
			.cc-unsub__header{background:' . esc_attr( $brand ) . ';color:#fff;padding:28px 24px;text-align:center}
			.cc-unsub__body{padding:28px 24px}
			.cc-unsub__title{margin:0 0 8px;font-size:20px;font-weight:600}
			.cc-unsub__msg{margin:0 0 16px;color:#666;line-height:1.5;font-size:15px}
			.cc-unsub__option{display:block;margin:8px 0;font-size:14px}
			.cc-unsub__other{width:100%;margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;display:none}
			.cc-unsub__btn{display:inline-block;background:' . esc_attr( $brand ) . ';color:#fff;border:0;text-decoration:none;padding:11px 22px;border-radius:8px;font-weight:500;font-size:14px;cursor:pointer;margin-top:12px}
			.cc-unsub__skip{display:block;margin-top:16px;font-size:13px;color:#888;text-align:center}
		</style></head><body>';
		echo '<div class="cc-unsub"><div class="cc-unsub__card">';
		echo '<div class="cc-unsub__header"><p class="cc-unsub__shop">' . esc_html( $shop_name ) . '</p></div>';
		echo '<div class="cc-unsub__body">';
		echo '<h1 class="cc-unsub__title">' . esc_html__( 'Unsubscribe', 'cartcue-sales-automation' ) . '</h1>';
		echo '<p class="cc-unsub__msg">' . esc_html__( 'Sorry to see you go. Would you mind telling us why? (Optional)', 'cartcue-sales-automation' ) . '</p>';
		echo '<form method="post">';
		wp_nonce_field( 'cartcue_unsubscribe_reason', 'cartcue_unsub_nonce' );
		echo '<input type="hidden" name="cartcue_unsub_wf" value="' . esc_attr( (string) $wf_id ) . '">';
		foreach ( $labels as $key => $label ) {
			echo '<label class="cc-unsub__option"><input type="radio" name="cartcue_unsub_reason" value="' . esc_attr( $key ) . '"> ' . esc_html( $label ) . '</label>';
		}
		echo '<textarea class="cc-unsub__other" name="cartcue_unsub_other" rows="3" placeholder="' . esc_attr__( 'Tell us more…', 'cartcue-sales-automation' ) . '"></textarea>';
		echo '<button type="submit" class="cc-unsub__btn">' . esc_html__( 'Confirm unsubscribe', 'cartcue-sales-automation' ) . '</button>';
		echo '</form>';
		echo '<a class="cc-unsub__skip" href="' . esc_url(
			add_query_arg(
				[
					'cartcue_unsubscribe' => '1',
					'e'                   => $encoded,
					'sig'                 => $sig,
					'skip_reason'         => '1',
				],
				home_url( '/' )
			)
		) . '">' . esc_html__( 'Skip and unsubscribe now', 'cartcue-sales-automation' ) . '</a>';
		echo '<p style="margin-top:20px;text-align:center"><a href="' . esc_url( $shop_url ) . '">' . esc_html__( 'Continue to the shop', 'cartcue-sales-automation' ) . '</a></p>';
		echo '</div></div></div>';
		echo '<script>document.querySelectorAll(\'input[name=cartcue_unsub_reason]\').forEach(function(r){r.addEventListener(\'change\',function(){document.querySelector(\'.cc-unsub__other\').style.display=r.value===\'other\'?\'block\':\'none\';});});</script>';
		echo '</body></html>';
		exit;
	}

	private static function render_page( string $title, string $message, bool $success ): void {
		$shop_name = get_bloginfo( 'name' );
		$shop_url  = home_url( '/' );
		$logo_url  = Variables::get_store_logo_url();
		$brand     = '#534AB7';

		status_header( 200 );
		nocache_headers();
		header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );

		echo '<!DOCTYPE html><html lang="' . esc_attr( get_bloginfo( 'language' ) ) . '"><head>';
		echo '<meta charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
		echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
		echo '<title>' . esc_html( $title ) . ' — ' . esc_html( $shop_name ) . '</title>';
		echo '<style>
			body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#f5f4fa;color:#1a1830}
			.cc-unsub{max-width:480px;margin:48px auto;padding:0 16px}
			.cc-unsub__card{background:#fff;border-radius:14px;border:1px solid #e5e4f0;overflow:hidden;box-shadow:0 8px 32px rgba(83,74,183,.08)}
			.cc-unsub__header{background:' . esc_attr( $brand ) . ';color:#fff;padding:28px 24px;text-align:center}
			.cc-unsub__logo{max-height:48px;max-width:180px;margin-bottom:12px}
			.cc-unsub__shop{font-size:13px;opacity:.9;margin:0}
			.cc-unsub__body{padding:28px 24px;text-align:center}
			.cc-unsub__icon{font-size:40px;margin-bottom:12px}
			.cc-unsub__title{margin:0 0 8px;font-size:20px;font-weight:600}
			.cc-unsub__msg{margin:0 0 20px;color:#666;line-height:1.5;font-size:15px}
			.cc-unsub__btn{display:inline-block;background:' . esc_attr( $brand ) . ';color:#fff;text-decoration:none;padding:11px 22px;border-radius:8px;font-weight:500;font-size:14px}
		</style></head><body>';
		echo '<div class="cc-unsub"><div class="cc-unsub__card">';
		echo '<div class="cc-unsub__header">';
		if ( $logo_url ) {
			echo '<img class="cc-unsub__logo" src="' . esc_url( $logo_url ) . '" alt="' . esc_attr( $shop_name ) . '">';
		}
		echo '<p class="cc-unsub__shop">' . esc_html( $shop_name ) . '</p></div>';
		echo '<div class="cc-unsub__body">';
		echo '<div class="cc-unsub__icon">' . ( $success ? '✓' : '!' ) . '</div>';
		echo '<h1 class="cc-unsub__title">' . esc_html( $title ) . '</h1>';
		echo '<p class="cc-unsub__msg">' . esc_html( $message ) . '</p>';
		echo '<a class="cc-unsub__btn" href="' . esc_url( $shop_url ) . '">' . esc_html__( 'Continue to the shop', 'cartcue-sales-automation' ) . '</a>';
		echo '</div></div></div></body></html>';
		exit;
	}

	private static function suppress( string $email ): void {
		global $wpdb;
		$now = current_time( 'mysql' );
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- consent upsert on unsubscribe.
		$wpdb->query(
			$wpdb->prepare(
				'INSERT INTO %i (email, status, source, granted_at)
				 VALUES (%s, 0, %s, %s)
				 ON DUPLICATE KEY UPDATE status = 0, source = VALUES(source), granted_at = VALUES(granted_at)',
				DB::consents(),
				$email,
				'unsubscribe',
				$now
			)
		);
		wp_cache_set( 'cartcue_supp_' . md5( $email ), 1, 'cartcue', HOUR_IN_SECONDS );
	}
}
