<?php
/**
 * Cart Abandonment Tracker with Cron Jobs
 *
 * This class handles cart abandonment tracking using WordPress cron jobs
 * to detect when users abandon their carts even after closing the browser.
 *
 * @package WPNTS\Inc
 */

namespace WPNTS\Inc;

use WPNTS\Inc\Database\DB;

defined('ABSPATH') || die('Hey, what are you doing here? You silly human!');

/**
 * Cart Abandonment Tracker Class
 *
 * @since 1.0.0
 */
class CartAbandonmentTracker {

	/**
	 * Constructor
	 */
	public function __construct() {
		// Hook into cart events
		add_action('woocommerce_add_to_cart', [$this, 'track_cart_activity'], 10, 6);
		add_action('woocommerce_cart_item_removed', [$this, 'track_cart_removal'], 10, 2);
		add_action('woocommerce_before_cart_item_quantity_zero', [$this, 'track_cart_removal'], 10, 2);
		
		// Schedule abandonment checks
		add_action('wp_loaded', [$this, 'schedule_abandonment_checks']);
		add_action('wpnts_check_cart_abandonment', [$this, 'process_cart_abandonment']);
		add_action('wpnts_cleanup_old_cart_sessions', [$this, 'cleanup_old_sessions']);
		
		// AJAX handlers for cart tracking
		add_action('wp_ajax_wpnts_track_cart_session', [$this, 'track_cart_session']);
		add_action('wp_ajax_nopriv_wpnts_track_cart_session', [$this, 'track_cart_session']);
		
		// Clean up on order completion
		add_action('woocommerce_checkout_order_processed', [$this, 'clear_cart_session'], 10, 1);
	}

	/**
	 * Schedule abandonment check cron jobs
	 */
	public function schedule_abandonment_checks() {
		// Schedule every 5 minutes to check for abandoned carts
		if (!wp_next_scheduled('wpnts_check_cart_abandonment')) {
			wp_schedule_event(time(), 'wpnts_five_minutes', 'wpnts_check_cart_abandonment');
		}
		
		// Schedule daily cleanup of old sessions
		if (!wp_next_scheduled('wpnts_cleanup_old_cart_sessions')) {
			wp_schedule_event(time(), 'daily', 'wpnts_cleanup_old_cart_sessions');
		}
	}

	/**
	 * Track when items are added to cart
	 */
	public function track_cart_activity($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
		$this->update_cart_session([
			'action' => 'add_to_cart',
			'product_id' => $product_id,
			'quantity' => $quantity,
			'variation_id' => $variation_id
		]);
	}

	/**
	 * Track when items are removed from cart
	 */
	public function track_cart_removal($cart_item_key, $cart) {
		$cart_item = $cart->get_cart_item($cart_item_key);
		if ($cart_item) {
			$this->update_cart_session([
				'action' => 'remove_from_cart',
				'product_id' => $cart_item['product_id'],
				'quantity' => $cart_item['quantity']
			]);
		}
	}

	/**
	 * Update cart session data
	 */
	private function update_cart_session($activity_data = []) {
		$session_key = $this->get_session_key();
		if (!$session_key) {
			return;
		}

		$cart_data = $this->get_current_cart_data();
		$user_data = $this->get_current_user_data();
		
		// Only track if cart has items or user has shown engagement
		if (empty($cart_data['items']) && empty($activity_data)) {
			return;
		}

		$session_data = [
			'session_key' => $session_key,
			'user_id' => get_current_user_id(),
			'user_email' => $user_data['email'],
			'user_name' => $user_data['name'],
			'cart_contents' => json_encode($cart_data),
			'last_activity' => current_time('mysql'),
			'ip_address' => isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '',
			'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
			'page_url' => isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : '',
			'activity_data' => json_encode($activity_data),
			'status' => 'active',
		];

		$this->save_cart_session($session_data);
		
		
	}

	/**
	 * Get current cart data
	 */
	private function get_current_cart_data() {
		if (!function_exists('WC') || !WC()->cart) {
			return ['items' => [], 'total' => 0];
		}

		$cart = WC()->cart;
		$items = [];
		$total = 0;

		foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
			$product = $cart_item['data'];
			$line_total = isset($cart_item['line_total']) ? $cart_item['line_total'] : ($product->get_price() * $cart_item['quantity']);
			
			$items[] = [
				'product_id' => $cart_item['product_id'],
				'variation_id' => $cart_item['variation_id'] ?? 0,
				'quantity' => $cart_item['quantity'],
				'name' => $product->get_name(),
				'price' => $product->get_price(),
				'total' => $line_total
			];
			$total += $line_total;
		}

		return [
			'items' => $items,
			'total' => $total,
			'item_count' => $cart->get_cart_contents_count()
		];
	}

	/**
	 * Get current user data
	 */
	private function get_current_user_data() {
		$user_data = ['email' => '', 'name' => ''];
		
		// Try logged-in user first
		if (is_user_logged_in()) {
			$user = wp_get_current_user();
			$user_data['email'] = $user->user_email;
			$user_data['name'] = $user->display_name;
		}
		
		// Try WooCommerce customer data
		if (function_exists('WC') && WC()->customer) {
			$customer = WC()->customer;
			if (empty($user_data['email'])) {
				$user_data['email'] = $customer->get_billing_email();
			}
			if (empty($user_data['name'])) {
				$first_name = $customer->get_billing_first_name();
				$last_name = $customer->get_billing_last_name();
				$user_data['name'] = trim($first_name . ' ' . $last_name);
			}
		}

		return $user_data;
	}

	/**
	 * Get or create session key
	 */
	private function get_session_key() {
		// Try to get from cookie first
		if ( isset($_COOKIE['wpnts_cart_session']) ) {
			return sanitize_text_field(wp_unslash($_COOKIE['wpnts_cart_session']));
		}

		// Try to get from WooCommerce session
		if ( function_exists('WC') && WC()->session ) {
			$wc_session_key = WC()->session->get_customer_id();
			if ( $wc_session_key ) {
				$session_key = 'wpnts_wc_' . $wc_session_key;
				// Set cookie for frontend tracking
				setcookie('wpnts_cart_session', $session_key, time() + ( 30 * 24 * 60 * 60 ), '/');
				return $session_key;
			}
		}

		// Create new session key
		$session_key = 'wpnts_' . time() . '_' . wp_generate_password(8, false);
		setcookie('wpnts_cart_session', $session_key, time() + ( 30 * 24 * 60 * 60 ), '/');

		return $session_key;
	}

	/**
	 * Save cart session to database
	 */
	private function save_cart_session($session_data) {
		global $wpdb;
		
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		// Create table if it doesn't exist
		$this->create_cart_sessions_table();
		
		// Check if session exists
		$existing = $wpdb->get_row($wpdb->prepare(
			"SELECT id FROM $table_name WHERE session_key = %s",
			$session_data['session_key']
		));
		
		if ($existing) {
			// Update existing session
			$wpdb->update(
				$table_name,
				$session_data,
				['id' => $existing->id],
				['%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'],
				['%d']
			);
		} else {
			// Insert new session
			$wpdb->insert(
				$table_name,
				$session_data,
				['%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s']
			);
		}
	}

	/**
	 * Create cart sessions table
	 */
	private function create_cart_sessions_table() {
		global $wpdb;
		
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		$charset_collate = $wpdb->get_charset_collate();
		
		$sql = "CREATE TABLE IF NOT EXISTS $table_name (
			id int(11) NOT NULL AUTO_INCREMENT,
			session_key varchar(255) NOT NULL,
			user_id bigint(20) DEFAULT 0,
			user_email varchar(191) DEFAULT '',
			user_name varchar(255) DEFAULT '',
			cart_contents longtext,
			last_activity datetime DEFAULT CURRENT_TIMESTAMP,
			ip_address varchar(45) DEFAULT '',
			user_agent text,
			page_url varchar(500) DEFAULT '',
			activity_data text,
			status varchar(50) DEFAULT 'active',
			created_at datetime DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY (id),
			UNIQUE KEY session_key (session_key),
			KEY user_id (user_id),
			KEY user_email (user_email),
			KEY last_activity (last_activity),
			KEY status (status)
		) $charset_collate;";
		
		require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
		dbDelta($sql);
	}

	/**
	 * Process cart abandonment (runs via cron every 5 minutes)
	 */
	public function process_cart_abandonment() {
		global $wpdb;
		
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		// Get abandonment delay from settings (default 30 minutes)
		$schedules_int = get_option('wpnts_schedules_interval_woocommerce_settings');
		$schedules_interval = json_decode($schedules_int, true);
		$abandonment_delay = $schedules_interval['cart_abandonment_minutes'] ?? 30;
		
		// Find sessions that are abandoned (no activity for X minutes)
		$cutoff_time = date('Y-m-d H:i:s', strtotime("-{$abandonment_delay} minutes"));
		
		$abandoned_sessions = $wpdb->get_results($wpdb->prepare(
			"SELECT * FROM $table_name 
			 WHERE status = 'active' 
			 AND last_activity < %s 
			 AND cart_contents IS NOT NULL 
			 AND cart_contents != ''
			 ORDER BY last_activity ASC
			 LIMIT 50", // Process in batches to avoid performance issues
			$cutoff_time
		));
		
		foreach ($abandoned_sessions as $session) {
			$this->process_abandoned_session($session);
		}
	}

	/**
	 * Process a single abandoned session
	 */
	private function process_abandoned_session($session) {
		global $wpdb;
		
		$cart_contents = json_decode($session->cart_contents, true);
		
		// Skip if cart is empty
		if (empty($cart_contents['items'])) {
			$this->mark_session_processed($session->id);
			return;
		}
		
		// Check if user has completed an order since this session
		if ($this->user_has_recent_order($session)) {
			$this->mark_session_completed($session->id);
			return;
		}
		
		// Create incomplete order record
		$incomplete_order_data = [
			'session_key' => $session->session_key,
			'user_id' => $session->user_id,
			'email' => $session->user_email,
			'name' => $session->user_name,
			'phone' => '',
			'address' => '',
			'product_ids' => json_encode(array_column($cart_contents['items'], 'product_id')),
			'product_names' => json_encode(array_column($cart_contents['items'], 'name')),
			'product_links' => json_encode([]),
			'cart_data' => $session->cart_contents,
			'total_amount' => $cart_contents['total'] ?? 0,
			'cart_interactions' => $session->activity_data ?? '[]',
			'is_abandonment' => true,
			'time_on_checkout' => 0,
			'ip' => $session->ip_address,
			'user_agent' => $session->user_agent,
		];
		
		$wpnts_db_instance = new DB();
		$incomplete_order_id = $wpnts_db_instance->save_incomplete_order($incomplete_order_data);
		
		if ($incomplete_order_id) {
			
			$this->mark_session_abandoned($session->id);
		} 
	}

	/**
	 * Check if user has completed an order recently
	 */
	private function user_has_recent_order($session) {
		if (empty($session->user_email) && $session->user_id == 0) {
			return false;
		}
		
		$args = [
			'limit' => 5,
			'status' => ['completed', 'processing', 'on-hold'],
			'date_created' => '>' . $session->last_activity,
		];
		
		if ($session->user_id > 0) {
			$args['customer_id'] = $session->user_id;
		} elseif (!empty($session->user_email)) {
			$args['billing_email'] = $session->user_email;
		}
		
		$orders = wc_get_orders($args);
		return !empty($orders);
	}

	/**
	 * Mark session as processed
	 */
	private function mark_session_processed($session_id) {
		global $wpdb;
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		$wpdb->update(
			$table_name,
			['status' => 'processed'],
			['id' => $session_id],
			['%s'],
			['%d']
		);
	}

	/**
	 * Mark session as completed (user made purchase)
	 */
	private function mark_session_completed($session_id) {
		global $wpdb;
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		$wpdb->update(
			$table_name,
			['status' => 'completed'],
			['id' => $session_id],
			['%s'],
			['%d']
		);
	}

	/**
	 * Mark session as abandoned
	 */
	private function mark_session_abandoned($session_id) {
		global $wpdb;
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		$wpdb->update(
			$table_name,
			['status' => 'abandoned'],
			['id' => $session_id],
			['%s'],
			['%d']
		);
	}

	/**
	 * Clear cart session when order is completed
	 */
	public function clear_cart_session($order_id) {
		$session_key = $this->get_session_key();
		if (!$session_key) {
			return;
		}
		
		global $wpdb;
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		$wpdb->update(
			$table_name,
			['status' => 'completed'],
			['session_key' => $session_key],
			['%s'],
			['%s']
		);
		
		// Clear the cookie
		setcookie('wpnts_cart_session', '', time() - 3600, '/');
		
	}

	/**
	 * AJAX handler for frontend cart session tracking
	 */
	public function track_cart_session() {
		// Verify nonce
		if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'wpnts_cart_session')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			return;
		}
		
		$activity_data = isset($_POST['activity']) ? sanitize_text_field( wp_unslash($_POST['activity']) ) : [];
		$this->update_cart_session($activity_data);
		
		wp_send_json_success(['message' => 'Cart session tracked']);
	}

	/**
	 * Cleanup old cart sessions (runs daily)
	 */
	public function cleanup_old_sessions() {
		global $wpdb;
		
		$table_name = $wpdb->prefix . 'wpnts_cart_sessions';
		
		// Delete sessions older than 30 days
		$cutoff_date = date('Y-m-d H:i:s', strtotime('-30 days'));
		
		$deleted = $wpdb->query($wpdb->prepare(
			"DELETE FROM $table_name WHERE created_at < %s",
			$cutoff_date
		));
		
	}
}