<?php
/**
 * Privacy for Cart Recovery
 *
 * Handles WordPress events related to privacy settings and data export.
 *
 * @package EDD\Pro\CartRecovery\Admin
 * @copyright Copyright (c) 2026, Sandhills Development, LLC
 * @license https://opensource.org/licenses/GPL-2.0 GNU Public License
 * @since   3.6.5
 */

declare(strict_types=1);

namespace EDD\Pro\CartRecovery\Admin;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

use EDD\EventManagement\SubscriberInterface;
use EDD\Pro\CartRecovery\Database\Queries\RecoveryCart;
use EDD\Pro\CartRecovery\Database\Queries\RecoveryEmail;
use EDD\Pro\CartRecovery\Journey\Repository as JourneyRepository;

/**
 * Privacy Event Subscriber class.
 *
 * Subscribes to WordPress events related to privacy settings and data export.
 * When a user requests their privacy data, we export the cart recovery data.
 *
 * @since 3.6.5
 */
class Privacy implements SubscriberInterface {

	/**
	 * The cart query.
	 *
	 * @var RecoveryCart
	 */
	private $cart_query;

	/**
	 * The email query.
	 *
	 * @var RecoveryEmail
	 */
	private $email_query;

	/**
	 * The journey repository.
	 *
	 * @var JourneyRepository
	 */
	private $journey_repo;

	/**
	 * Constructor.
	 *
	 * @since 3.6.5
	 */
	public function __construct() {
		$this->cart_query   = new RecoveryCart();
		$this->email_query  = new RecoveryEmail();
		$this->journey_repo = new JourneyRepository();
	}

	/**
	 * Returns an array of events that this subscriber wants to listen to.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	public static function get_subscribed_events() {
		return array(
			'wp_privacy_personal_data_exporters' => 'register_cart_recovery_exporter',
			'wp_privacy_personal_data_erasers'   => 'register_cart_recovery_eraser',
		);
	}

	/**
	 * Register the cart recovery exporter.
	 *
	 * @since 3.6.5
	 * @param array $exporters The exporters to register.
	 * @return array
	 */
	public function register_cart_recovery_exporter( $exporters ) {
		$exporters[] = array(
			'exporter_friendly_name' => __( 'Cart Recovery', 'easy-digital-downloads' ),
			'callback'               => array( $this, 'export_cart_recovery_data' ),
		);
		return $exporters;
	}

	/**
	 * Export the cart recovery data.
	 *
	 * @since 3.6.5
	 * @param string $email_address The email address to export data for.
	 * @param int    $page          The page number for pagination.
	 * @return array
	 */
	public function export_cart_recovery_data( $email_address, $page = 1 ) {
		$carts = $this->get_carts_for_email( $email_address );

		$export_items = array();

		foreach ( $carts as $cart ) {
			// Build cart data.
			$cart_data = array(
				array(
					'name'  => __( 'Cart ID', 'easy-digital-downloads' ),
					'value' => $cart->id,
				),
				array(
					'name'  => __( 'Email', 'easy-digital-downloads' ),
					'value' => $cart->email,
				),
				array(
					'name'  => __( 'Session ID', 'easy-digital-downloads' ),
					'value' => $cart->session_id,
				),
				array(
					'name'  => __( 'Cart Total', 'easy-digital-downloads' ),
					'value' => $cart->cart_total . ' ' . $cart->currency,
				),
				array(
					'name'  => __( 'Status', 'easy-digital-downloads' ),
					'value' => $cart->status,
				),
			);

			// Add optional fields if they exist.
			if ( ! empty( $cart->customer_id ) ) {
				$cart_data[] = array(
					'name'  => __( 'Customer ID', 'easy-digital-downloads' ),
					'value' => $cart->customer_id,
				);
			}

			if ( ! empty( $cart->ip_address ) ) {
				$cart_data[] = array(
					'name'  => __( 'IP Address', 'easy-digital-downloads' ),
					'value' => $cart->ip_address,
				);
			}

			if ( ! empty( $cart->user_agent ) ) {
				$cart_data[] = array(
					'name'  => __( 'User Agent', 'easy-digital-downloads' ),
					'value' => $cart->user_agent,
				);
			}

			if ( ! empty( $cart->browser_fingerprint ) ) {
				$cart_data[] = array(
					'name'  => __( 'Browser Fingerprint', 'easy-digital-downloads' ),
					'value' => $cart->browser_fingerprint,
				);
			}

			if ( ! empty( $cart->timezone ) ) {
				$cart_data[] = array(
					'name'  => __( 'Timezone', 'easy-digital-downloads' ),
					'value' => $cart->timezone,
				);
			}

			if ( ! empty( $cart->referrer_url ) ) {
				$cart_data[] = array(
					'name'  => __( 'Referrer URL', 'easy-digital-downloads' ),
					'value' => $cart->referrer_url,
				);
			}

			if ( ! empty( $cart->discount_applied ) ) {
				$cart_data[] = array(
					'name'  => __( 'Discount Applied', 'easy-digital-downloads' ),
					'value' => $cart->discount_applied,
				);
			}

			if ( ! empty( $cart->date_abandoned ) ) {
				$cart_data[] = array(
					'name'  => __( 'Date Abandoned', 'easy-digital-downloads' ),
					'value' => $cart->date_abandoned,
				);
			}

			if ( ! empty( $cart->date_recovered ) ) {
				$cart_data[] = array(
					'name'  => __( 'Date Recovered', 'easy-digital-downloads' ),
					'value' => $cart->date_recovered,
				);
			}

			if ( ! empty( $cart->date_unsubscribed ) ) {
				$cart_data[] = array(
					'name'  => __( 'Date Unsubscribed', 'easy-digital-downloads' ),
					'value' => $cart->date_unsubscribed,
				);
			}

			if ( ! empty( $cart->order_id ) ) {
				$cart_data[] = array(
					'name'  => __( 'Order ID', 'easy-digital-downloads' ),
					'value' => $cart->order_id,
				);
			}

			$cart_data[] = array(
				'name'  => __( 'Recovery Email Count', 'easy-digital-downloads' ),
				'value' => $cart->recovery_email_count,
			);

			if ( ! empty( $cart->last_recovery_email ) ) {
				$cart_data[] = array(
					'name'  => __( 'Last Recovery Email', 'easy-digital-downloads' ),
					'value' => $cart->last_recovery_email,
				);
			}

			$cart_data[] = array(
				'name'  => __( 'Date Created', 'easy-digital-downloads' ),
				'value' => $cart->date_created,
			);

			// Add cart to export items.
			$export_items[] = array(
				'group_id'    => 'edd_cart_recovery_carts',
				'group_label' => __( 'Cart Recovery - Abandoned Carts', 'easy-digital-downloads' ),
				'item_id'     => 'cart-' . $cart->id,
				'data'        => $cart_data,
			);

			// Get recovery emails for this cart.
			$emails = $this->email_query->query(
				array(
					'cart_id' => $cart->id,
				)
			);

			if ( ! empty( $emails ) ) {
				foreach ( $emails as $email ) {
					$email_data = array(
						array(
							'name'  => __( 'Email ID', 'easy-digital-downloads' ),
							'value' => $email->id,
						),
						array(
							'name'  => __( 'Cart ID', 'easy-digital-downloads' ),
							'value' => $email->cart_id,
						),
						array(
							'name'  => __( 'Email Subject', 'easy-digital-downloads' ),
							'value' => $email->email_subject,
						),
						array(
							'name'  => __( 'Delivery Status', 'easy-digital-downloads' ),
							'value' => $email->delivery_status,
						),
					);

					if ( ! empty( $email->discount_code ) ) {
						$email_data[] = array(
							'name'  => __( 'Discount Code', 'easy-digital-downloads' ),
							'value' => $email->discount_code,
						);
					}

					if ( ! empty( $email->date_sent ) ) {
						$email_data[] = array(
							'name'  => __( 'Date Sent', 'easy-digital-downloads' ),
							'value' => $email->date_sent,
						);
					}

					if ( ! empty( $email->date_opened ) ) {
						$email_data[] = array(
							'name'  => __( 'Date Opened', 'easy-digital-downloads' ),
							'value' => $email->date_opened,
						);
					}

					if ( ! empty( $email->date_clicked ) ) {
						$email_data[] = array(
							'name'  => __( 'Date Clicked', 'easy-digital-downloads' ),
							'value' => $email->date_clicked,
						);
					}

					if ( ! empty( $email->date_converted ) ) {
						$email_data[] = array(
							'name'  => __( 'Date Converted', 'easy-digital-downloads' ),
							'value' => $email->date_converted,
						);
					}

					if ( ! empty( $email->date_used ) ) {
						$email_data[] = array(
							'name'  => __( 'Date Used', 'easy-digital-downloads' ),
							'value' => $email->date_used,
						);
					}

					if ( ! empty( $email->bounce_reason ) ) {
						$email_data[] = array(
							'name'  => __( 'Bounce Reason', 'easy-digital-downloads' ),
							'value' => $email->bounce_reason,
						);
					}

					$email_data[] = array(
						'name'  => __( 'Date Created', 'easy-digital-downloads' ),
						'value' => $email->date_created,
					);

					$export_items[] = array(
						'group_id'    => 'edd_cart_recovery_emails',
						'group_label' => __( 'Cart Recovery - Recovery Emails', 'easy-digital-downloads' ),
						'item_id'     => 'recovery-email-' . $email->id,
						'data'        => $email_data,
					);
				}
			}

			// Get journey events for this cart.
			$journey_events = $this->journey_repo->get_cart_journey( $cart->id );

			if ( ! empty( $journey_events ) ) {
				foreach ( $journey_events as $event ) {
					$event_data = array(
						array(
							'name'  => __( 'Event ID', 'easy-digital-downloads' ),
							'value' => $event->id,
						),
						array(
							'name'  => __( 'Cart ID', 'easy-digital-downloads' ),
							'value' => $event->cart_id,
						),
						array(
							'name'  => __( 'Event Type', 'easy-digital-downloads' ),
							'value' => $event->event_type,
						),
					);

					if ( ! empty( $event->email_id ) ) {
						$event_data[] = array(
							'name'  => __( 'Email ID', 'easy-digital-downloads' ),
							'value' => $event->email_id,
						);
					}

					if ( ! empty( $event->event_data ) ) {
						$event_data[] = array(
							'name'  => __( 'Event Data', 'easy-digital-downloads' ),
							'value' => $event->event_data,
						);
					}

					if ( ! empty( $event->user_agent ) ) {
						$event_data[] = array(
							'name'  => __( 'User Agent', 'easy-digital-downloads' ),
							'value' => $event->user_agent,
						);
					}

					if ( ! empty( $event->ip_address ) ) {
						$event_data[] = array(
							'name'  => __( 'IP Address', 'easy-digital-downloads' ),
							'value' => $event->ip_address,
						);
					}

					$event_data[] = array(
						'name'  => __( 'Date Created', 'easy-digital-downloads' ),
						'value' => $event->date_created,
					);

					$export_items[] = array(
						'group_id'    => 'edd_cart_recovery_journey',
						'group_label' => __( 'Cart Recovery - Journey Events', 'easy-digital-downloads' ),
						'item_id'     => 'journey-event-' . $event->id,
						'data'        => $event_data,
					);
				}
			}
		}

		return array(
			'data' => $export_items,
			'done' => true,
		);
	}

	/**
	 * Register the cart recovery eraser.
	 *
	 * @since 3.6.5
	 * @param array $erasers The erasers to register.
	 * @return array
	 */
	public function register_cart_recovery_eraser( $erasers ) {
		$erasers[] = array(
			'eraser_friendly_name' => __( 'Cart Recovery', 'easy-digital-downloads' ),
			'callback'             => array( $this, 'remove_cart_recovery_data' ),
		);

		return $erasers;
	}

	/**
	 * Remove the cart recovery data.
	 *
	 * @since 3.6.5
	 * @param string $email_address The email address to remove the data for.
	 * @param int    $page          The page number for pagination.
	 * @return array
	 */
	public function remove_cart_recovery_data( $email_address, $page = 1 ) {
		$carts = $this->get_carts_for_email( $email_address );

		if ( empty( $carts ) ) {
			return array(
				'items_removed'  => false,
				'items_retained' => false,
				'messages'       => array(),
				'done'           => true,
			);
		}

		$items_removed  = false;
		$items_retained = false;
		$messages       = array();

		foreach ( $carts as $cart ) {
			// Delete journey events first.
			$deleted_events = $this->journey_repo->delete_cart_events( $cart->id );
			if ( $deleted_events > 0 ) {
				$items_removed = true;
			} elseif ( false === $deleted_events ) {
				$items_retained = true;
				$messages[]     = sprintf(
					/* translators: %d: Cart ID */
					__( 'Failed to delete journey events for cart with ID %d', 'easy-digital-downloads' ),
					$cart->id
				);
			}

			// Delete recovery emails.
			$emails = $this->email_query->query(
				array(
					'cart_id' => $cart->id,
				)
			);

			if ( ! empty( $emails ) ) {
				foreach ( $emails as $email ) {
					$deleted = $this->email_query->delete_item( $email->id );
					if ( $deleted ) {
						$items_removed = true;
					} else {
						$items_retained = true;
						$messages[]     = sprintf(
							/* translators: %d: Email ID */
							__( 'Failed to delete recovery email with ID %d', 'easy-digital-downloads' ),
							$email->id
						);
					}
				}
			}

			// Delete the cart.
			$deleted = $this->cart_query->delete_item( $cart->id );
			if ( $deleted ) {
				$items_removed = true;
			} else {
				$items_retained = true;
				$messages[]     = sprintf(
					/* translators: %d: Cart ID */
					__( 'Failed to delete abandoned cart with ID %d', 'easy-digital-downloads' ),
					$cart->id
				);
			}
		}

		return array(
			'items_removed'  => $items_removed,
			'items_retained' => $items_retained,
			'messages'       => $messages,
			'done'           => true,
		);
	}

	/**
	 * Get the carts for an email address.
	 *
	 * @since 3.6.5
	 * @param string $email_address The email address to get the carts for.
	 * @return array
	 */
	private function get_carts_for_email( string $email_address ): array {
		return $this->cart_query->query(
			array(
				'email' => $email_address,
			)
		);
	}
}
