<?php
/**
 * Capturing SMS consent at checkout.
 *
 * @package TextTango
 */

declare( strict_types=1 );

namespace TextTango\Consent;

use TextTango\Support\Settings;
use WC_Order;

defined( 'ABSPATH' ) || exit;

/**
 * Adds an opt-in checkbox to checkout and records what was agreed (spec §7, §16).
 *
 * Registered through WooCommerce's Additional Checkout Fields API rather than a
 * template hook, so the same declaration renders in block checkout and is
 * persisted by WooCommerce itself. A hand-rolled field on
 * `woocommerce_review_order_before_submit` would only ever appear on classic
 * checkout, which most new stores no longer use.
 *
 * The consent is written to the **order** as well as the customer, so a guest
 * checkout still leaves an artifact, and so the record says what was agreed at
 * the time rather than whatever the account happens to say later.
 */
final class CheckoutConsent {

	/**
	 * Field id. Namespaced, as the API requires.
	 */
	public const FIELD = 'texttango/sms_optin';

	/**
	 * Where the consent came from.
	 */
	public const SOURCE = 'checkout';

	/**
	 * Register hooks.
	 */
	public function register(): void {
		add_action( 'woocommerce_init', array( $this, 'register_field' ) );
		add_action( 'woocommerce_checkout_order_created', array( $this, 'capture' ) );
		add_action( 'woocommerce_store_api_checkout_order_processed', array( $this, 'capture' ) );
	}

	/**
	 * Whether the checkbox should appear.
	 */
	public static function is_enabled(): bool {
		return (bool) Settings::get( 'consent_checkout_enabled', true );
	}

	/**
	 * The wording shown beside the checkbox.
	 */
	public static function label(): string {
		$label = trim( (string) Settings::get( 'consent_checkout_label', '' ) );

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

		return __( 'Text me offers and updates from this store', 'texttango' );
	}

	/**
	 * Declare the field to WooCommerce.
	 */
	public function register_field(): void {
		if ( ! self::is_enabled() || ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
			return;
		}

		woocommerce_register_additional_checkout_field(
			array(
				'id'       => self::FIELD,
				'label'    => self::label(),
				'location' => 'contact',
				'type'     => 'checkbox',
				// Never pre-ticked. Consent that was not actively given is not consent.
				'required' => false,
			)
		);
	}

	/**
	 * Record what the customer chose.
	 *
	 * @param WC_Order|mixed $order Order just created.
	 */
	public function capture( $order ): void {
		if ( ! $order instanceof WC_Order || ! self::is_enabled() ) {
			return;
		}

		// Already recorded by the other hook on this request.
		if ( '' !== (string) $order->get_meta( Consent::ORDER_META_OPTIN, true ) ) {
			return;
		}

		$granted = $order->get_meta( '_wc_other/' . self::FIELD, true );

		Consent::record_for_order( $order, self::is_truthy( $granted ), self::SOURCE );
	}

	/**
	 * Whether a stored checkbox value means yes.
	 *
	 * WooCommerce has stored additional-field booleans as `1`, `true` and `yes`
	 * across versions, so all three are accepted rather than assuming one.
	 *
	 * @param mixed $value Stored value.
	 */
	public static function is_truthy( $value ): bool {
		if ( is_bool( $value ) ) {
			return $value;
		}

		return in_array( strtolower( (string) $value ), array( '1', 'true', 'yes' ), true );
	}
}
