<?php

namespace CommerceBird\API;

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

use CommerceBird\Admin\Traits\LogWriter;
use WP_REST_Response;

class CreateOrderWebhook {

	use Api;
	use LogWriter;

	private static string $endpoint = 'create-woo-order';


	public function __construct() {
		register_rest_route(
			self::$namespace,
			self::$endpoint,
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'handle' ),
				'permission_callback' => array( $this, 'permission_check' ),
			)
		);
	}

	/**
	 * @param $address
	 *
	 * @return array
	 */
	public function format_address( $address ): array {
		if ( array_key_exists( 'attention', $address ) ) {
			$names      = explode( ' ', $address['attention'] );
			$first_name = $names[0] ?? '';
			$last_name  = $names[1] ?? '';
		}
		return array(
			'first_name' => $this->normalize_customer_text( $first_name ?? '' ),
			'last_name'  => $this->normalize_customer_text( $last_name ?? '' ),
			'address_1'  => $this->normalize_customer_text( $address['address'] ?? '' ),
			'address_2'  => $this->normalize_customer_text( $address['street2'] ?? '' ),
			'city'       => $this->normalize_customer_text( $address['city'] ?? '' ),
			'state'      => $this->normalize_customer_text( $address['state_code'] ?? '' ),
			'postcode'   => $this->normalize_customer_text( $address['zip'] ?? '' ),
			'country'    => $this->normalize_customer_text( $address['country_code'] ?? '' ),
			'phone'      => $this->normalize_customer_text( $address['phone'] ?? '' ),
		);
	}

	private function normalize_customer_text( $value ): string {
		if ( ! is_scalar( $value ) ) {
			return '';
		}

		$normalized = remove_accents( (string) $value );
		$normalized = preg_replace( '/[^\x20-\x7E]/', '', $normalized );

		if ( null === $normalized ) {
			$normalized = '';
		}

		return trim( sanitize_text_field( $normalized ) );
	}

	private function process( array $order_data ): WP_REST_Response {
		$response = new WP_REST_Response();

		// Check if the order data is valid.
		if ( empty( $order_data ) || empty( $order_data['salesorder'] ) ) {
			$response->set_data( $this->empty_response );
			$response->set_status( 404 );
			return $response;
		}

		// Validate salesorder_id exists.
		if ( ! isset( $order_data['salesorder']['salesorder_id'] ) || empty( $order_data['salesorder']['salesorder_id'] ) ) {
			/* translators: %1$s: Store name */
			$message      = sprintf( __( 'Zoho order could not be created in your store %1$s because of missing order ID.', 'commercebird' ), get_bloginfo( 'name' ) );
			$common_class = new \CMBIRD_Common_Functions();
			$common_class->send_email( __( 'Zoho Order Sync', 'commercebird' ), $message );
			$response->set_status( 500 );
			$response->set_data( $message );
			return $response;
		}

		$allowed_keys = array(
			'salesorder_id',
			'salesorder_number',
			'customer_id',
			'customer_name',
			'billing_address',
			'shipping_address',
			'delivery_method',
			'currency_code',
			'line_items',
			'contact_person_details',
			'shipping_charge',
			'order_status',
			'paid_status',
			'invoiced_status',
			'total',
			'discount',
			'discount_total',
			'discount_percent',
			'notes',
			'salesperson_name',
			'reference_number',
		);

		$order_data                 = array_intersect_key( $order_data['salesorder'], array_flip( $allowed_keys ) );
		$billing_address            = $this->format_address( $order_data['billing_address'] );
		$shipping_address           = $this->format_address( $order_data['shipping_address'] );
		$billing_company            = $this->normalize_customer_text( $order_data['customer_name'] ?? '' );
		$billing_address['company'] = $billing_company;

		$zoho_contact = array();

		// Always fetch full contact details from Zoho API when customer_id is available,.
		// since the webhook payload omits company_name, first_name, and last_name.
		if ( ! empty( $order_data['customer_id'] ) ) {
			$zoho_contact = $this->get_zoho_contact_details( $order_data['customer_id'] );
			if ( ! empty( $zoho_contact ) ) {
				$order_data['contact_person_details'] = $zoho_contact;
			}
		}

		// Handle customer creation/update.
		$customer     = null;
		$contact_data = $zoho_contact[0] ?? ( $order_data['contact_person_details'][0] ?? null );
		if ( isset( $contact_data['email'] ) ) {
			$customer_mail = $contact_data['email'];
			$first_name    = $this->normalize_customer_text( $contact_data['first_name'] ?? '' );
			$last_name     = $this->normalize_customer_text( $contact_data['last_name'] ?? '' );
			$company_name  = $this->normalize_customer_text( $contact_data['company_name'] ?? '' );
			$eu_vat_number = $contact_data['company_id'] ?? '';
			if ( '' === $company_name ) {
				$company_name = $billing_company;
			}
			$customer = get_user_by( 'email', $customer_mail );
			if ( empty( $customer ) ) {
				$customer_id = wc_create_new_customer(
					$customer_mail,
					'',
					'',
					array(
						'role'       => 'customer',
						'first_name' => $first_name,
						'last_name'  => $last_name,
					)
				);
				$wc_customer = new \WC_Customer( $customer_id );
				// Set billing details.
				$wc_customer->set_billing_first_name( $first_name );
				$wc_customer->set_billing_last_name( $last_name );
				$wc_customer->set_billing_company( $company_name );
				$wc_customer->set_billing_address_1( $billing_address['address_1'] );
				$wc_customer->set_billing_address_2( $billing_address['address_2'] );
				$wc_customer->set_billing_city( $billing_address['city'] );
				$wc_customer->set_billing_postcode( $billing_address['postcode'] );
				$wc_customer->set_billing_country( $billing_address['country'] );
				$wc_customer->set_billing_state( $billing_address['state'] );
				$wc_customer->set_billing_email( $customer_mail );
				$wc_customer->set_billing_phone( $billing_address['phone'] );
				// Set shipping details.
				$wc_customer->set_shipping_first_name( $first_name );
				$wc_customer->set_shipping_last_name( $last_name );
				$wc_customer->set_shipping_address_1( $shipping_address['address_1'] );
				$wc_customer->set_shipping_address_2( $shipping_address['address_2'] );
				$wc_customer->set_shipping_city( $shipping_address['city'] );
				$wc_customer->set_shipping_postcode( $shipping_address['postcode'] );
				$wc_customer->set_shipping_country( $shipping_address['country'] );
				$wc_customer->set_shipping_state( $shipping_address['state'] );
				$wc_customer->save();
				$customer = get_user_by( 'id', $customer_id );
			} else {
				$wc_customer = new \WC_Customer( $customer->ID );
				// Set billing details.
				$wc_customer->set_billing_first_name( $first_name );
				$wc_customer->set_billing_last_name( $last_name );
				$wc_customer->set_billing_company( $company_name );
				$wc_customer->set_billing_address_1( $billing_address['address_1'] );
				$wc_customer->set_billing_address_2( $billing_address['address_2'] );
				$wc_customer->set_billing_city( $billing_address['city'] );
				$wc_customer->set_billing_postcode( $billing_address['postcode'] );
				$wc_customer->set_billing_country( $billing_address['country'] );
				$wc_customer->set_billing_state( $billing_address['state'] );
				$wc_customer->set_billing_email( $customer_mail );
				$wc_customer->set_billing_phone( $billing_address['phone'] );
				// Set shipping details.
				$wc_customer->set_shipping_first_name( $first_name );
				$wc_customer->set_shipping_last_name( $last_name );
				$wc_customer->set_shipping_address_1( $shipping_address['address_1'] );
				$wc_customer->set_shipping_address_2( $shipping_address['address_2'] );
				$wc_customer->set_shipping_city( $shipping_address['city'] );
				$wc_customer->set_shipping_postcode( $shipping_address['postcode'] );
				$wc_customer->set_shipping_country( $shipping_address['country'] );
				$wc_customer->set_shipping_state( $shipping_address['state'] );
				$wc_customer->save();
			}

			if ( class_exists( 'WC_EU_VAT_Number' ) && '' !== $eu_vat_number && ! empty( $customer ) ) {
				update_user_meta( $customer->ID, 'vat_number', $eu_vat_number );
			}
		}

		// Validate line items exist.
		if ( empty( $order_data['line_items'] ) ) {
			// translators: 1: order number, 2: Store name.
			$message      = sprintf( __( 'Zoho order #%1$s could not be created in your store %2$s because of missing line items.', 'commercebird' ), $order_data['salesorder_number'], get_bloginfo( 'name' ) );
			$common_class = new \CMBIRD_Common_Functions();
			$common_class->send_email( __( 'Zoho Order Sync', 'commercebird' ), $message );
			$response->set_status( 500 );
			$response->set_data( $message );
			return $response;
		}

		$line_items_result = $this->get_items( $order_data['line_items'] );
		$line_items        = $line_items_result['items'];
		$shipping_charge   = ! empty( $line_items_result['shipping_total'] )
			? (float) $line_items_result['shipping_total']
			: ( isset( $order_data['shipping_charge'] ) ? (float) $order_data['shipping_charge'] : 0.0 );

		if ( ! empty( $line_items_result['not_found'] ) ) {
			// translators: 1: order number, 2: Store name, 3: missing items.
			$message      = sprintf( __( 'Zoho order #%1$s could not be created in your store %2$s because of missing items: %3$s', 'commercebird' ), $order_data['salesorder_number'], get_bloginfo( 'name' ), implode( ', ', $line_items_result['not_found'] ) );
			$common_class = new \CMBIRD_Common_Functions();
			$common_class->send_email( __( 'Zoho Order Sync', 'commercebird' ), $message );
			$response->set_status( 500 );
			$response->set_data( $message );
			return $response;
		}

		$order_discount_total = isset( $order_data['discount_total'] ) ? (float) $order_data['discount_total'] : 0.0;
		$sales_order_total    = isset( $order_data['total'] ) ? (float) $order_data['total'] : null;

		// Check if order already exists.
		$orders = wc_get_orders(
			array(
				'limit'        => 1,
				'meta_key'     => 'zi_salesorder_id',
				'meta_value'   => $order_data['salesorder_id'],
				'meta_compare' => '=',
				'return'       => 'ids',
			)
		);
		if ( ! empty( $orders ) ) {
			$existing_order = wc_get_order( $orders[0] );
		}

		// Update existing order.
		if ( ! empty( $existing_order ) && empty( $line_items_result['not_found'] ) ) {
			// if order status is completed or processing, do not update the order and return error response.
			if ( in_array( $existing_order->get_status(), array( 'completed', 'processing' ), true ) ) {
				/* translators: %1$s: Zoho order number, %2$s: Store name, %3$s: Order status */
				$message      = sprintf( __( 'Zoho order #%1$s could not be updated in your store %2$s because the order is already in %3$s status.', 'commercebird' ), $order_data['salesorder_number'], get_bloginfo( 'name' ), $existing_order->get_status() );
				$common_class = new \CMBIRD_Common_Functions();
				$common_class->send_email( __( 'Zoho Order Sync', 'commercebird' ), $message );
				$response->set_status( 200 );
				$response->set_data( $message );
				return $response;
			}
			if ( $customer ) {
				$wc_customer_data = ( new \WC_Customer( $customer->ID ) )->get_data();
				$existing_order->set_address( $wc_customer_data['billing'], 'billing' );
				$existing_order->set_address( $wc_customer_data['shipping'], 'shipping' );
			} else {
				$existing_order->set_address( $billing_address, 'billing' );
				$existing_order->set_address( $shipping_address, 'shipping' );
			}
			$existing_order->set_billing_company( $billing_company );
			// Remove existing order items.
			$existing_order->remove_order_items( 'line_item' );
			// Add products to the order.
			foreach ( $line_items as $line_item ) {
				$product_id = $line_item['id'];
				$quantity   = $line_item['quantity'];
				$rate       = $line_item['rate'] ?? null;
				if ( ! empty( $product_id ) ) {
					$product = wc_get_product( $product_id );
					if ( $product && $product->is_type( 'variation' ) ) {
						// Get variation object.
						$variation = wc_get_product_object( 'variation', $product_id );
						if ( $variation ) {
							$item_id = $existing_order->add_product( $variation, $quantity );
						}
					} else {
						$item_id = $existing_order->add_product( $product, $quantity );
					}
				}
			}

			// Set order details.
			$existing_order->set_customer_note( isset( $order_data['notes'] ) ? $order_data['notes'] : '' );
			$existing_order->update_status( $this->map_status( $order_data['paid_status'], $order_data['invoiced_status'] ?? '' ) );

			// Handle shipping.
			// Remove existing shipping items first.
			foreach ( $existing_order->get_items( 'shipping' ) as $item_id => $item ) {
				$existing_order->remove_item( $item_id );
			}

			if ( $shipping_charge > 0 ) {
				$shipping = new \WC_Order_Item_Shipping();
				$shipping->set_method_title( $order_data['delivery_method'] ?? 'Flat Rate' );
				$shipping->set_method_id( 'flat_rate' );
				$shipping->set_total( $shipping_charge );
				$existing_order->add_item( $shipping );
			}
			// Set order totals and save.
			$existing_order->calculate_totals();
			$this->apply_order_discount_total( $existing_order, $order_discount_total, $sales_order_total );
			$existing_order->save();
			$note = 'Updated in Zoho Inventory';
			if ( ! empty( $order_data['salesperson_name'] ) ) {
				$note .= ' by ' . $order_data['salesperson_name'];
			}
			$existing_order->add_order_note( $note );

			$response->set_data(
				array(
					'order_id' => $existing_order->get_id(),
					'total'    => $existing_order->get_total(),
					'status'   => $existing_order->get_status(),
				)
			);
			$response->set_status( 200 );
		} elseif ( empty( $line_items_result['not_found'] ) ) {
			// Create new order.
			$order = wc_create_order();
			if ( $customer ) {
				$order->set_customer_id( $customer->ID );
				$wc_customer_data = ( new \WC_Customer( $customer->ID ) )->get_data();
				$order->set_address( $wc_customer_data['billing'], 'billing' );
				$order->set_address( $wc_customer_data['shipping'], 'shipping' );
			}
			$order->set_billing_company( $billing_company );
			// Add products to the order.
			foreach ( $line_items as $line_item ) {
				$product_id = $line_item['id'];
				$quantity   = $line_item['quantity'];
				$rate       = $line_item['rate'] ?? null;
				if ( ! empty( $product_id ) ) {
					$product = wc_get_product( $product_id );
					if ( $product && $product->is_type( 'variation' ) ) {
						// Get variation object.
						$variation = wc_get_product_object( 'variation', $product_id );
						if ( $variation ) {
							$item_id = $order->add_product( $variation, $quantity );
						}
					} else {
						$item_id = $order->add_product( $product, $quantity );
					}
				}
			}
			$order->set_currency( $order_data['currency_code'] );
			$order->set_status( $this->map_status( $order_data['paid_status'], $order_data['invoiced_status'] ?? '' ) );
			// Handle shipping.
			if ( $shipping_charge > 0 ) {
				$shipping = new \WC_Order_Item_Shipping();
				$shipping->set_method_title( $order_data['delivery_method'] ?? 'Flat Rate' );
				$shipping->set_method_id( 'flat_rate' );
				$shipping->set_total( $shipping_charge );
				$order->add_item( $shipping );
			}

			$order->calculate_totals();
			$this->apply_order_discount_total( $order, $order_discount_total, $sales_order_total );
			$order->set_customer_note( $order_data['notes'] ?? '' );
			$order->save();
			$order->update_meta_data( 'zi_salesorder_id', $order_data['salesorder_id'] );
			$order->save();
			$note = 'Synced in Zoho Inventory';
			if ( ! empty( $order_data['salesperson_name'] ) ) {
				$note .= ' by ' . $order_data['salesperson_name'];
			}
			$order->add_order_note( $note );

			// Update Zoho sales order with WooCommerce order ID as reference number.
			if ( empty( $order_data['reference_number'] ) ) {
				$this->update_zoho_reference_number( $order, $order_data['salesorder_id'] );
			}
			$response->set_data(
				array(
					'order_id' => $order->get_id(),
					'status'   => $order->get_status(),
				)
			);
			$response->set_status( 200 );
		} else {
			$response->set_data(
				array(
					'status' => 'Something went wrong. Please try again.',
				)
			);
			$response->set_status( 500 );
		}

		return $response;
	}

	/**
	 * Apply external discount amount from Zoho to WooCommerce order totals.
	 *
	 * @param \WC_Order  $order WooCommerce order object.
	 * @param float      $discount_total Discount total from payload.
	 * @param float|null $sales_order_total Zoho sales order total from payload.
	 * @return void
	 */
	private function apply_order_discount_total( \WC_Order $order, float $discount_total, ?float $sales_order_total = null ): void {
		$current_total = (float) $order->get_total();

		// When the Zoho total is provided, the gap between the calculated WC total and the
		// Zoho total is the authoritative discount — using discount_total on top would double-count.
		if ( null !== $sales_order_total && $sales_order_total >= 0 && $sales_order_total < $current_total ) {
			$effective_discount = $current_total - $sales_order_total;
		} else {
			$effective_discount = max( 0, $discount_total );
		}

		if ( $effective_discount <= 0 ) {
			$order->set_discount_total( 0 );
			$order->set_discount_tax( 0 );
			return;
		}

		$effective_discount = min( $effective_discount, $current_total );
		$order->set_discount_total( $effective_discount );
		$order->set_discount_tax( 0 );
		$order->set_total( max( 0, $current_total - $effective_discount ) );
	}


	private function map_status( $paid_status, $invoiced_status = '' ): string {
		// If invoiced, status must be processing.
		if ( 'invoiced' === $invoiced_status ) {
			return 'wc-processing';
		}

		// Otherwise check paid status.
		switch ( $paid_status ) {
			case 'paid':
				return 'wc-completed';
			default:
				return 'wc-pending';
		}
	}


	/**
	 * Update Zoho sales order reference number with WooCommerce order ID.
	 *
	 * @param \WC_Order $order WooCommerce order object.
	 * @param string    $salesorder_id Zoho sales order ID.
	 * @return void
	 */
	private function update_zoho_reference_number( $order, $salesorder_id ): void {
		// Get Zoho Inventory configuration.
		$zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
		$zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );

		if ( empty( $zoho_inventory_url ) || empty( $zoho_inventory_oid ) || empty( $salesorder_id ) ) {
			return;
		}

		// Return if the order status is processing or completed, since the reference number should not be updated in that case.
		if ( in_array( $order->get_status(), array( 'processing', 'completed' ), true ) ) {
			return;
		}

		// Prepare reference number using the same logic as order sync.
		$transaction_id = $order->get_transaction_id();
		if ( empty( $transaction_id ) ) {
			$transaction_id = $order->get_meta( '_order_number', true );
		}

		$order_prefix     = get_option( 'cmbird_zoho_order_prefix_status' );
		$reference_number = '';

		if ( class_exists( 'WCJ_Order_Numbers' ) || class_exists( 'WC_Seq_Order_Number_Pro' ) ) {
			$reference_number = $order_prefix . $transaction_id;
		} elseif ( ! empty( $order_prefix ) ) {
			$reference_number = $order_prefix . '-' . $order->get_id();
		} else {
			$reference_number = $order->get_id();
		}

		// Build the API URL.
		$url = $zoho_inventory_url . 'inventory/v1/salesorders/' . $salesorder_id . '?organization_id=' . $zoho_inventory_oid;

		// Prepare data for update.
		$data = array(
			'JSONString' => wp_json_encode(
				array(
					'reference_number' => $reference_number,
				)
			),
		);

		// Make the API call to update Zoho sales order.
		$api_handler = new \CMBIRD_API_Handler_Zoho();
		$response    = $api_handler->execute_curl_call_put( $url, $data );

		// Log any errors.
		$logger = wc_get_logger();
		if ( is_wp_error( $response ) ) {
			$logger->error(
				'Error updating Zoho reference number: ' . $response->get_error_message(),
				array(
					'source'        => 'commercebird',
					'order_id'      => $order->get_id(),
					'salesorder_id' => $salesorder_id,
				)
			);
		} elseif ( isset( $response->code ) && 0 !== $response->code ) {
			$error_message = isset( $response->message ) ? $response->message : 'Unknown error';
			$logger->error(
				'Error updating Zoho reference number: ' . $error_message,
				array(
					'source'        => 'commercebird',
					'order_id'      => $order->get_id(),
					'salesorder_id' => $salesorder_id,
				)
			);
		} else {
			$order->add_order_note( 'Updated Zoho reference number to: ' . $reference_number );
		}
	}


	/**
	 * Find the product ids from the line items from Zoho Inventory.
	 *
	 * @param mixed $line_items Line items from the salesorder.
	 * @return array
	 */
	private function get_items( $line_items ): array {
		$product_ids    = array();
		$not_found      = array();
		$shipping_total = 0.0;

		foreach ( $line_items as $item ) {
			$line_item_name = isset( $item['name'] ) ? trim( (string) $item['name'] ) : trim( (string) ( $item['item_name'] ?? '' ) );
			if ( 'shipping' === strtolower( $line_item_name ) ) {
				$line_item_total = isset( $item['item_total'] ) ? (float) $item['item_total'] : 0.0;
				if ( $line_item_total <= 0 && isset( $item['rate'] ) ) {
					$quantity        = isset( $item['quantity'] ) ? (float) $item['quantity'] : 1;
					$line_item_total = (float) $item['rate'] * $quantity;
				}
				$shipping_total += $line_item_total;
				continue;
			}

			// Check if the sku key is present (case-insensitive check).
			$sku      = isset( $item['sku'] ) ? $item['sku'] : ( isset( $item['SKU'] ) ? $item['SKU'] : null );
			$quantity = $item['quantity'] ?? 1;
			$rate     = $item['rate'] ?? null;

			if ( null !== $sku ) {
				$product_id = wc_get_product_id_by_sku( $sku );
				if ( $product_id ) {
					// Append to product_ids instead of overwriting.
					$product_ids[] = array(
						'id'       => $product_id,
						'quantity' => $quantity,
						'rate'     => $rate,
					);
				} else {
					// create the item in WooCommerce.
					try {
						$new_product = new \WC_Product_Simple();
						$new_product->set_name( $line_item_name );
						$new_product->set_sku( $sku );
						$new_product->set_regular_price( $rate );
						$new_product->set_status( 'publish' );
						$new_product->set_manage_stock( false );
						// add meta zi_item_id to link the product with Zoho item.
						$new_product->add_meta_data( 'zi_item_id', $item['item_id'] ?? '' );
						$product_id = $new_product->save();
						if ( $product_id > 0 ) {
							$product_ids[] = array(
								'id'       => $product_id,
								'quantity' => $quantity,
								'rate'     => $rate,
							);
						} else {
							$error_msg = 'Unknown error';
							$logger    = wc_get_logger();
							$logger->error(
								'Failed to create product with SKU ' . $sku . ': ' . $error_msg,
								array( 'source' => 'commercebird' )
							);
							$not_found[] = $line_item_name . ' (SKU: ' . $sku . ')';
						}
					} catch ( \Throwable $e ) {
						$logger = wc_get_logger();
						$logger->error(
							'Exception creating product with SKU ' . $sku . ': ' . $e->getMessage(),
							array( 'source' => 'commercebird' )
						);
						$not_found[] = $line_item_name . ' (SKU: ' . $sku . ')';
					}
				}
			} else {
				$not_found[] = 'Unknown SKU';
			}
		}

		return array(
			'items'          => $product_ids,
			'not_found'      => $not_found,
			'shipping_total' => $shipping_total,
		);
	}

	/**
	 * Fetch contact person details from Zoho Inventory using a customer_id.
	 * Returns an array compatible with contact_person_details format.
	 *
	 * @param string $customer_id Zoho customer/contact ID.
	 * @return array
	 */
	private function get_zoho_contact_details( string $customer_id ): array {
		$zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
		$zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_oid' );

		if ( empty( $zoho_inventory_url ) || empty( $zoho_inventory_oid ) ) {
			return array();
		}

		$url = $zoho_inventory_url . 'inventory/v1/contacts/' . $customer_id . '?organization_id=' . $zoho_inventory_oid;

		$api_handler = new \CMBIRD_API_Handler_Zoho();
		$response    = $api_handler->execute_curl_call_get( $url );

		if ( is_wp_error( $response ) || empty( $response->contact ) ) {
			return array();
		}

		$contact         = (array) $response->contact;
		$contact_persons = array();

		$company_name = $contact['company_name'] ?? '';
		$company_id   = $contact['company_id'] ?? '';

		if ( ! empty( $contact['contact_persons'] ) ) {
			foreach ( $contact['contact_persons'] as $person ) {
				$person = (array) $person;
				if ( ! empty( $person['is_primary_contact'] ) && ! empty( $person['email'] ) ) {
					$contact_persons[] = array(
						'email'        => $person['email'],
						'first_name'   => $person['first_name'] ?? '',
						'last_name'    => $person['last_name'] ?? '',
						'company_name' => $company_name,
						'company_id'   => $company_id,
					);
					break;
				}
			}
		}

		// Fall back to the contact's own email if no contact persons with email found.
		if ( empty( $contact_persons ) && ! empty( $contact['email'] ) ) {
			$contact_persons[] = array(
				'email'        => $contact['email'],
				'first_name'   => $contact['first_name'] ?? '',
				'last_name'    => $contact['last_name'] ?? '',
				'company_name' => $company_name,
				'company_id'   => $company_id,
			);
		}

		return $contact_persons;
	}
}
