<?php
/**
 * REST API Controller for Cart Recovery Customer Info.
 *
 * Handles customer information capture during checkout (email, first name, last name).
 *
 * @package EDD\Pro\CartRecovery\REST\Controllers
 * @copyright Copyright (c) 2026, Sandhills Development, LLC
 * @license https://opensource.org/licenses/GPL-3.0 GNU General Public License v3.0
 * @since 3.6.5
 */

namespace EDD\Pro\CartRecovery\REST\Controllers;

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

use EDD\REST\Security;
use EDD\Pro\CartRecovery\Snapshots\SnapshotPersistence;
use EDD\Pro\CartRecovery\Snapshots\SnapshotBuilder;
use EDD\Pro\CartRecovery\Journey\EventLogger;

/**
 * CustomerInfo controller class.
 *
 * @since 3.6.5
 */
final class CustomerInfo {

	/**
	 * Security instance.
	 *
	 * @since 3.6.5
	 * @var Security
	 */
	private Security $security;

	/**
	 * Constructor.
	 *
	 * @since 3.6.5
	 * @param Security $security Security instance.
	 */
	public function __construct( Security $security ) {
		$this->security = $security;
	}

	/**
	 * Handles customer info capture request.
	 *
	 * @since 3.6.5
	 * @param \WP_REST_Request $request Request object.
	 * @return \WP_REST_Response Response object.
	 */
	public function handle_customer_info( \WP_REST_Request $request ): \WP_REST_Response {
		// Check if ACR is enabled.
		if ( ! edd_get_option( 'acr_enabled', false ) ) {
			return new \WP_REST_Response(
				array( 'error' => 'Cart recovery is not enabled' ),
				403
			);
		}

		// Get parameters from request.
		$email      = $request->get_param( 'email' );
		$first_name = $request->get_param( 'first_name' );
		$last_name  = $request->get_param( 'last_name' );

		// At least one field must be provided.
		if ( empty( $email ) && empty( $first_name ) && empty( $last_name ) ) {
			return new \WP_REST_Response(
				array( 'success' => true ), // Return success silently to avoid console errors.
				200
			);
		}

		// Build customer data array to pass as override.
		$customer_data = array();

		if ( ! empty( $email ) ) {
			$customer_data['email'] = $email;
		}

		if ( ! empty( $first_name ) ) {
			$customer_data['first_name'] = $first_name;
		}

		if ( ! empty( $last_name ) ) {
			$customer_data['last_name'] = $last_name;
		}

		// Persist the cart snapshot with customer info passed as override.
		$snapshot_builder     = new SnapshotBuilder();
		$snapshot_persistence = new SnapshotPersistence( $snapshot_builder );
		$result               = $snapshot_persistence->persist_snapshot(
			array(
				'customer_data' => $customer_data,
			)
		);

		$timestamp = Security::get_current_timestamp();

		// Log journey event if cart was persisted.
		if ( is_array( $result ) && ! empty( $result['cart_id'] ) ) {
			$cart_id = (int) $result['cart_id'];

			// Check if this is a new cart or an update.
			$query           = new \EDD\Pro\CartRecovery\Database\Queries\JourneyEvent();
			$existing_events = $query->query(
				array(
					'cart_id'    => $cart_id,
					'event_type' => 'cart_created',
					'number'     => 1,
				)
			);

			$is_new_cart = empty( $existing_events );
			$event_type  = $is_new_cart ? 'cart_created' : 'cart_updated';

			$event_data = array(
				'cart_total' => edd_format_amount( edd_sanitize_amount( edd_get_cart_total() ) ),
				'item_count' => (int) edd_get_cart_quantity(),
			);

			if ( ! empty( $email ) ) {
				$event_data['email'] = $email;
			}

			if ( ! empty( $first_name ) || ! empty( $last_name ) ) {
				$event_data['customer_name'] = trim( ( $first_name ?? '' ) . ' ' . ( $last_name ?? '' ) );
			}

			$event_logger = new EventLogger();
			$event_logger->log_cart_event( $event_type, $cart_id, $event_data );

			return new \WP_REST_Response(
				array(
					'success'   => true,
					'cart_id'   => $cart_id,
					'token'     => $this->security->generate_token( $timestamp ),
					'timestamp' => $timestamp,
				),
				200
			);
		}

		// Cart not persisted (likely empty cart or missing identifiers).
		return new \WP_REST_Response(
			array(
				'success'   => false,
				'token'     => $this->security->generate_token( $timestamp ),
				'timestamp' => $timestamp,
			),
			200
		);
	}
}
