<?php
/**
 * WordPress privacy tools for CartNinja tracking data.
 *
 * @package CartNinjaRecovery
 */

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

class CARTNINJA_Privacy {

	const PAGE_SIZE = 50;

	public function register_exporter( $exporters ) {
		$exporters['cartninja-recovery'] = array(
			'exporter_friendly_name' => __( 'CartNinja Recovery', 'cartninja-recovery-for-woocommerce' ),
			'callback'               => array( $this, 'export_personal_data' ),
		);

		return $exporters;
	}

	public function register_eraser( $erasers ) {
		$erasers['cartninja-recovery'] = array(
			'eraser_friendly_name' => __( 'CartNinja Recovery', 'cartninja-recovery-for-woocommerce' ),
			'callback'             => array( $this, 'erase_personal_data' ),
		);

		return $erasers;
	}

	public function export_personal_data( $email_address, $page = 1 ) {
		global $wpdb;

		$email_address = sanitize_email( $email_address );
		$page          = max( 1, absint( $page ) );

		if ( ! is_email( $email_address ) ) {
			return array(
				'data' => array(),
				'done' => true,
			);
		}

		$rows = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT id, email, phone, customer_country_code, customer_country_name,
					status, cart_contents, cart_total, currency, consented_at, consent_source,
					cart_updated_at, created_at
				FROM {$wpdb->prefix}cartninja_carts
				WHERE email = %s
				ORDER BY id ASC
				LIMIT %d OFFSET %d",
				$email_address,
				self::PAGE_SIZE,
				( $page - 1 ) * self::PAGE_SIZE
			),
			ARRAY_A
		);

		$data = array();

		foreach ( $rows as $row ) {
			$data[] = array(
				'group_id'    => 'cartninja-recovery',
				'group_label' => __( 'Cart recovery data', 'cartninja-recovery-for-woocommerce' ),
				'item_id'     => 'cartninja-cart-' . absint( $row['id'] ),
				'data'        => array(
					array(
						'name'  => __( 'Email address', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_email( $row['email'] ),
					),
					array(
						'name'  => __( 'Phone number', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_text_field( $row['phone'] ),
					),
					array(
						'name'  => __( 'Country', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_text_field( trim( $row['customer_country_name'] . ' ' . $row['customer_country_code'] ) ),
					),
					array(
						'name'  => __( 'Cart status', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_key( $row['status'] ),
					),
					array(
						'name'  => __( 'Cart contents', 'cartninja-recovery-for-woocommerce' ),
						'value' => $this->format_cart_contents( $row['cart_contents'] ),
					),
					array(
						'name'  => __( 'Cart total', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_text_field( $row['currency'] . ' ' . $row['cart_total'] ),
					),
					array(
						'name'  => __( 'Consent recorded', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_text_field( trim( $row['consented_at'] . ' ' . $row['consent_source'] ) ),
					),
					array(
						'name'  => __( 'Reminder history', 'cartninja-recovery-for-woocommerce' ),
						'value' => $this->format_notification_history( absint( $row['id'] ) ),
					),
					array(
						'name'  => __( 'Created', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_text_field( $row['created_at'] ),
					),
					array(
						'name'  => __( 'Last updated', 'cartninja-recovery-for-woocommerce' ),
						'value' => sanitize_text_field( $row['cart_updated_at'] ),
					),
				),
			);
		}

		return array(
			'data' => $data,
			'done' => count( $rows ) < self::PAGE_SIZE,
		);
	}

	public function erase_personal_data( $email_address, $page = 1 ) {
		global $wpdb;

		$email_address = sanitize_email( $email_address );

		if ( ! is_email( $email_address ) ) {
			return array(
				'items_removed'  => false,
				'items_retained' => false,
				'messages'       => array( __( 'A valid email address is required.', 'cartninja-recovery-for-woocommerce' ) ),
				'done'           => true,
			);
		}

		$cart_ids = $wpdb->get_col(
			$wpdb->prepare(
				"SELECT id FROM {$wpdb->prefix}cartninja_carts WHERE email = %s ORDER BY id ASC LIMIT %d",
				$email_address,
				self::PAGE_SIZE
			)
		);
		$cart_ids = array_values( array_filter( array_map( 'absint', $cart_ids ) ) );

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

		$this->delete_generated_coupons( $cart_ids );
		$this->delete_rows( $wpdb->prefix . 'cartninja_notifications', 'cart_id', $cart_ids );

		if ( $this->table_exists( $wpdb->prefix . 'cartninja_cart_sequence_progress' ) ) {
			$this->delete_rows( $wpdb->prefix . 'cartninja_cart_sequence_progress', 'cart_id', $cart_ids );
		}

		$this->delete_rows( $wpdb->prefix . 'cartninja_carts', 'id', $cart_ids );

		$remaining = (int) $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}cartninja_carts WHERE email = %s",
				$email_address
			)
		);

		return array(
			'items_removed'  => true,
			'items_retained' => false,
			'messages'       => array( __( 'Cart recovery records and associated reminder history were removed.', 'cartninja-recovery-for-woocommerce' ) ),
			'done'           => 0 === $remaining,
		);
	}

	public function add_privacy_policy_content() {
		if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
			return;
		}

		$content = '<p>' . esc_html__( 'CartNinja stores cart contents and pseudonymous request identifiers to detect cart abandonment and limit abuse. It stores an email address or phone number only after the shopper explicitly agrees to cart recovery reminders, together with the consent time and source. The data is removed according to the retention settings configured by the site administrator.', 'cartninja-recovery-for-woocommerce' ) . '</p>';

		wp_add_privacy_policy_content(
			__( 'CartNinja Recovery for WooCommerce', 'cartninja-recovery-for-woocommerce' ),
			wp_kses_post( $content )
		);
	}

	private function format_cart_contents( $cart_contents ) {
		$items = json_decode( (string) $cart_contents, true );

		if ( ! is_array( $items ) ) {
			return '';
		}

		$summary = array();

		foreach ( $items as $item ) {
			$name     = isset( $item['product_name'] ) ? sanitize_text_field( $item['product_name'] ) : '';
			$quantity = isset( $item['quantity'] ) ? max( 1, absint( $item['quantity'] ) ) : 1;

			if ( '' !== $name ) {
				$summary[] = sprintf( '%s x %d', $name, $quantity );
			}
		}

		return implode( ', ', $summary );
	}

	private function format_notification_history( $cart_id ) {
		global $wpdb;

		$rows = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT channel, recipient, message_sent, status, scheduled_at, sent_at, clicked_at
				FROM {$wpdb->prefix}cartninja_notifications
				WHERE cart_id = %d
				ORDER BY id ASC",
				absint( $cart_id )
			),
			ARRAY_A
		);
		$history = array();

		foreach ( $rows as $row ) {
			$history[] = sprintf(
				'%1$s | %2$s | %3$s | %4$s | %5$s',
				sanitize_key( $row['channel'] ),
				sanitize_text_field( $row['status'] ),
				sanitize_text_field( $row['recipient'] ),
				sanitize_textarea_field( $row['message_sent'] ),
				sanitize_text_field( $row['sent_at'] ? $row['sent_at'] : $row['scheduled_at'] )
			);
		}

		return implode( "\n", $history );
	}

	private function delete_generated_coupons( $cart_ids ) {
		global $wpdb;

		foreach ( $cart_ids as $cart_id ) {
			$coupon_ids = $wpdb->get_col(
				$wpdb->prepare(
					"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s",
					'_cartninja_cart_id',
					(string) absint( $cart_id )
				)
			);

			foreach ( $coupon_ids as $coupon_id ) {
				wp_delete_post( absint( $coupon_id ), true );
			}
		}
	}

	private function delete_rows( $table, $column, $ids ) {
		global $wpdb;

		$allowed_tables = array(
			$wpdb->prefix . 'cartninja_notifications',
			$wpdb->prefix . 'cartninja_cart_sequence_progress',
			$wpdb->prefix . 'cartninja_carts',
		);
		$allowed_columns = array( 'cart_id', 'id' );

		if ( ! in_array( $table, $allowed_tables, true ) || ! in_array( $column, $allowed_columns, true ) ) {
			return;
		}

		$placeholders = implode( ',', array_fill( 0, count( $ids ), '%d' ) );
		$wpdb->query(
			$wpdb->prepare(
				"DELETE FROM {$table} WHERE {$column} IN ({$placeholders})",
				$ids
			)
		);
	}

	private function table_exists( $table ) {
		global $wpdb;

		return $table === $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
	}
}
