<?php
/**
 * Finding the number to text a customer on.
 *
 * @package TextTango
 */

declare( strict_types=1 );

namespace TextTango\Consent;

use TextTango\Api\PhoneNumber;
use TextTango\Otp\UserRepository;
use WC_Order;

defined( 'ABSPATH' ) || exit;

/**
 * Resolves the best number held for a customer, in E.164.
 *
 * A registered customer may have two: the one they proved by signing in, and
 * whatever they typed into billing. The verified one is preferred — it is the
 * number somebody demonstrated they hold, rather than one that might be a typo
 * or a landline. Billing is the fallback, because most customers never sign in
 * by phone at all.
 *
 * Guests have only the order, which is why the two cases are separate rather
 * than one lookup keyed on a user.
 */
final class Recipient {

	/**
	 * The number held for a registered customer, or '' if none is usable.
	 *
	 * @param int $user_id User id.
	 */
	public static function for_user( int $user_id ): string {
		if ( $user_id <= 0 ) {
			return '';
		}

		$verified = self::normalize( UserRepository::phone_for( $user_id ) );

		if ( '' !== $verified ) {
			return $verified;
		}

		return self::normalize( (string) get_user_meta( $user_id, 'billing_phone', true ) );
	}

	/**
	 * The number on an order, or '' if none is usable.
	 *
	 * @param WC_Order $order Order.
	 */
	public static function for_order( WC_Order $order ): string {
		return self::normalize( (string) $order->get_billing_phone(), $order->get_billing_country() );
	}

	/**
	 * Normalize a number, treating anything unusable as absent.
	 *
	 * @param string      $raw     Number as stored.
	 * @param string|null $country ISO country hint.
	 */
	public static function normalize( string $raw, ?string $country = null ): string {
		if ( '' === trim( $raw ) ) {
			return '';
		}

		$normalized = PhoneNumber::normalize( $raw, $country );

		return is_wp_error( $normalized ) ? '' : $normalized;
	}
}
