<?php
/**
 * Block (Store API) checkout support.
 *
 * The block checkout doesn't fire the classic form hooks, so we use WooCommerce's
 * official Additional Checkout Fields API. It has no native "date" type, so the
 * delivery date is offered as a dropdown of available dates (already filtered by the
 * Pro rules). The selected value is mirrored into the canonical `_datery_delivery_date`
 * meta so all existing admin / email / order display code keeps working unchanged.
 *
 * @package Datery
 */

defined( 'ABSPATH' ) || exit;

class Datery_Blocks {

	const FIELD_ID = 'datery/delivery-date';

	private static $instance = null;

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {
		add_action( 'woocommerce_init', array( $this, 'register_fields' ) );

		// Mirror block-checkout values into the canonical order meta.
		add_action( 'woocommerce_set_additional_field_value', array( $this, 'sync_to_meta' ), 10, 4 );

		// Avoid double display: the API renders the field itself on block orders.
		add_filter( 'datery_skip_classic_display', array( $this, 'maybe_skip_classic_display' ), 10, 2 );
	}

	public function register_fields() {
		if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
			return; // Older WooCommerce without the API — classic checkout still works.
		}

		$dates = Datery_Dates::available_dates();
		if ( empty( $dates ) ) {
			return;
		}

		$options = array();
		foreach ( $dates as $d ) {
			$options[] = array(
				'value' => $d,
				'label' => Datery_Dates::display( $d ),
			);
		}

		try {
			woocommerce_register_additional_checkout_field(
				array(
					'id'       => self::FIELD_ID,
					'label'    => Datery_Settings::get( 'field_label', __( 'Delivery date', 'datery-delivery-date-for-woocommerce' ) ),
					'location' => 'order',
					'type'     => 'select',
					'required' => ( 'yes' === Datery_Settings::get( 'required', 'yes' ) ),
					'options'  => $options,
				)
			);
		} catch ( Exception $e ) {
			// Re-registration on the same request (e.g. settings re-read) — safe to ignore.
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				error_log( 'EDD block field registration: ' . $e->getMessage() ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug-only, guarded by WP_DEBUG.
			}
		}

		/** Lets Pro register its time-slot field with the available date options. */
		do_action( 'datery_register_block_fields', $options );
	}

	public function sync_to_meta( $key, $value, $group, $wc_object ) {
		if ( self::FIELD_ID !== $key || ! $wc_object instanceof WC_Order ) {
			return;
		}
		$value = sanitize_text_field( (string) $value );
		if ( '' !== $value && ! is_wp_error( Datery_Dates::validate( $value ) ) ) {
			$wc_object->update_meta_data( DATERY_META_KEY, $value );
		}
	}

	/**
	 * True when this order already shows the date via the block API, so the classic
	 * display hooks should stay quiet to prevent duplicates.
	 */
	public function maybe_skip_classic_display( $skip, $order ) {
		if ( ! $order instanceof WC_Order ) {
			return $skip;
		}
		return $order->get_meta( '_wc_other/' . self::FIELD_ID ) !== '' ? true : $skip;
	}
}
