<?php
/**
 * Normalized campaign recipient records (registered users and guest emails).
 *
 * @package CartCue
 */

namespace CartCue;

defined( 'ABSPATH' ) || exit;

final class CampaignRecipient {

	/**
	 * @param array<string, mixed> $row
	 * @return array{user_id: int, email: string, first_name: string, last_name: string}
	 */
	public static function from_array( array $row ): array {
		$email = sanitize_email( (string) ( $row['email'] ?? '' ) );
		$user_id = max( 0, (int) ( $row['user_id'] ?? 0 ) );

		if ( $user_id > 0 ) {
			$user = get_user_by( 'id', $user_id );
			if ( $user ) {
				return [
					'user_id'    => $user->ID,
					'email'      => $user->user_email,
					'first_name' => (string) $user->first_name,
					'last_name'  => (string) $user->last_name,
				];
			}
		}

		if ( is_email( $email ) ) {
			$user = get_user_by( 'email', $email );
			if ( $user ) {
				return [
					'user_id'    => $user->ID,
					'email'      => $user->user_email,
					'first_name' => (string) $user->first_name,
					'last_name'  => (string) $user->last_name,
				];
			}

			return [
				'user_id'    => 0,
				'email'      => $email,
				'first_name' => sanitize_text_field( (string) ( $row['first_name'] ?? '' ) ),
				'last_name'  => sanitize_text_field( (string) ( $row['last_name'] ?? '' ) ),
			];
		}

		return [
			'user_id'    => 0,
			'email'      => '',
			'first_name' => '',
			'last_name'  => '',
		];
	}

	/**
	 * @param int $user_id
	 * @return array{user_id: int, email: string, first_name: string, last_name: string}|null
	 */
	public static function from_user_id( int $user_id ): ?array {
		$user = get_user_by( 'id', $user_id );
		if ( ! $user ) {
			return null;
		}

		return [
			'user_id'    => $user->ID,
			'email'      => $user->user_email,
			'first_name' => (string) $user->first_name,
			'last_name'  => (string) $user->last_name,
		];
	}

	/**
	 * Action Scheduler chunks may be legacy int user IDs or recipient arrays.
	 *
	 * @param array<int|string|array<string, mixed>> $chunk
	 * @return list<array{user_id: int, email: string, first_name: string, last_name: string}>
	 */
	public static function normalize_chunk( array $chunk ): array {
		$recipients = [];

		foreach ( $chunk as $item ) {
			if ( is_array( $item ) ) {
				$row = self::from_array( $item );
			} else {
				$row = self::from_user_id( (int) $item ) ?? self::from_array( [] );
			}

			if ( ! is_email( $row['email'] ) ) {
				continue;
			}

			$key = strtolower( $row['email'] );
			$recipients[ $key ] = $row;
		}

		return array_values( $recipients );
	}

	/**
	 * @param int[] $user_ids
	 * @return list<array{user_id: int, email: string, first_name: string, last_name: string}>
	 */
	public static function from_user_ids( array $user_ids ): array {
		$recipients = [];
		foreach ( $user_ids as $user_id ) {
			$row = self::from_user_id( (int) $user_id );
			if ( $row ) {
				$recipients[] = $row;
			}
		}
		return $recipients;
	}
}
