<?php
/**
 * Obsługa kompatybilności WooCommerce Blocks Checkout.
 *
 * FIX v3.3.4:
 *  - Usunięto globalne `use` (powodowało fatal error gdy klasy Store API niedostępne)
 *  - `use` przeniesione do wewnątrz metod / zabezpieczone class_exists
 *  - Poprawione sprawdzanie dostępności Store API Extensibility
 *  - `validate_blocks_checkout` - rozszerzony fallback bez RouteException
 *
 * @package ParcelSelector
 */

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

if ( ! class_exists( 'Parcselect_Blocks_Integration' ) ) :

class Parcselect_Blocks_Integration {

	/**
	 * Init integracji Blocks.
	 */
	public static function init() {
		// Store API rozszerzenia — rejestrujemy na dedykowanym hooku
		add_action( 'woocommerce_blocks_loaded', array( __CLASS__, 'register_store_api_data' ) );

		// Walidacja i zapis meta przy Blocks Checkout
		add_action(
			'woocommerce_store_api_checkout_update_order_from_request',
			array( __CLASS__, 'validate_blocks_checkout' ),
			10,
			2
		);
	}

	/**
	 * Rejestruje nasze dane zwracane z Store API koszyka Blocks.
	 * Zabezpieczenie: sprawdzamy dostępność wszystkich wymaganych klas przed użyciem.
	 */
	public static function register_store_api_data() {
		if ( ! function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) {
			return;
		}

		if ( ! class_exists( 'Automattic\\WooCommerce\\StoreApi\\Schemas\\V1\\CheckoutSchema' ) ) {
			return;
		}

		woocommerce_store_api_register_endpoint_data(
			array(
				'endpoint'        => \Automattic\WooCommerce\StoreApi\Schemas\V1\CheckoutSchema::IDENTIFIER,
				'namespace'       => 'parcel_selector',
				'data_callback'   => array( __CLASS__, 'get_checkout_data' ),
				'schema_callback' => array( __CLASS__, 'get_checkout_schema' ),
				'schema_type'     => ARRAY_A,
			)
		);
	}

	/**
	 * Zwraca dane do koszyka React (aktualnie wybrany paczkomat z sesji).
	 *
	 * @return array
	 */
	public static function get_checkout_data() {
		$selected_locker = array(
			'name'             => '',
			'address'          => '',
			'city'             => '',
			'post_code'        => '',
			'country'          => '',
			'country_name'     => '',
			'is_selected'      => false,
			'is_custom_pickup' => false,
		);

		if ( ! function_exists( 'WC' ) || ! isset( WC()->session ) || ! WC()->session ) {
			return array( 'point' => $selected_locker );
		}

		$name = (string) WC()->session->get( 'parcselect_locker_name', '' );
		if ( ! empty( $name ) ) {
			$country = (string) WC()->session->get( 'parcselect_locker_country', '' );
			$map     = function_exists( 'parcselect_get_country_names_map' ) ? parcselect_get_country_names_map() : array();
			$cc      = strtolower( $country );

			$selected_locker['name']             = $name;
			$selected_locker['address']          = (string) WC()->session->get( 'parcselect_locker_address', '' );
			$selected_locker['city']             = (string) WC()->session->get( 'parcselect_locker_city', '' );
			$selected_locker['post_code']        = (string) WC()->session->get( 'parcselect_locker_post_code', '' );
			$selected_locker['country']          = $country;
			$selected_locker['country_name']     = isset( $map[ $cc ] ) ? $map[ $cc ] : strtoupper( $country );
			$selected_locker['is_selected']      = true;
			$selected_locker['is_custom_pickup'] = ( '1' === (string) WC()->session->get( 'parcselect_is_custom_pickup', '0' ) );
		}

		return array( 'point' => $selected_locker );
	}

	/**
	 * Definiuje schemat API dla bloków.
	 *
	 * @return array
	 */
	public static function get_checkout_schema() {
		return array(
			'point' => array(
				'description' => 'Selected Parcel Locker information.',
				'type'        => 'object',
				'context'     => array( 'view', 'edit' ),
				'properties'  => array(
					'name'             => array( 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field' ) ),
					'address'          => array( 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field' ) ),
					'city'             => array( 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field' ) ),
					'post_code'        => array( 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field' ) ),
					'country'          => array( 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field' ) ),
					'country_name'     => array( 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field' ) ),
					'is_selected'      => array( 'type' => 'boolean', 'default' => false ),
					'is_custom_pickup' => array( 'type' => 'boolean', 'default' => false ),
				),
			),
		);
	}

	/**
	 * Walidacja podczas submitu przez WC Blocks.
	 *
	 * @param WC_Order        $order   Obiekt zamówienia.
	 * @param WP_REST_Request $request Żądanie z Blocks.
	 * @throws \Exception Błąd przerywający checkout.
	 */
	public static function validate_blocks_checkout( \WC_Order $order, \WP_REST_Request $request ) {
		try {
			// Sprawdzamy czy wybrana jest metoda InPost
			$is_inpost_selected = false;
			foreach ( $order->get_shipping_methods() as $method ) {
				if ( false !== strpos( $method->get_method_id(), 'parcselect_inpost_paczkomat' ) ) {
					$is_inpost_selected = true;
					break;
				}
			}

			if ( ! $is_inpost_selected ) {
				return;
			}

			// Session is the only reliable source here — meta is saved AFTER this hook fires.
			$locker_name = null;
			if ( function_exists( 'WC' ) && WC()->session ) {
				$locker_name = WC()->session->get( 'parcselect_locker_name' );
			}
			// Secondary check: extension data from JS
			if ( ! $locker_name ) {
				$ext = $request->get_param( 'extensions' );
				if ( isset( $ext['parcel_selector']['point']['name'] ) ) {
					$locker_name = sanitize_text_field( $ext['parcel_selector']['point']['name'] );
				}
			}

			if ( empty( $locker_name ) ) {
				$message = __( 'Please select a parcel locker to proceed.', 'parcel-selector' );

				if ( class_exists( 'Automattic\\WooCommerce\\StoreApi\\Exceptions\\RouteException' ) ) {
					throw new \Automattic\WooCommerce\StoreApi\Exceptions\RouteException(
						'parcselect_no_locker_selected',
						esc_html( $message ),
						400
					);
				}

				// Fallback: add notice instead of throwing (prevents 500 on older WC).
				if ( function_exists( 'wc_add_notice' ) ) {
					wc_add_notice( esc_html( $message ), 'error' );
				}
				return;
			}
		} catch ( \Automattic\WooCommerce\StoreApi\Exceptions\RouteException $e ) {
			throw $e; // Re-throw WC exceptions — they handle 400 properly.
		} catch ( \Exception $e ) {
			// Log but still enforce validation — don't silently let orders without locker through.
			if ( function_exists( 'parcselect_log' ) ) {
				parcselect_log( 'Blocks validation error: ' . $e->getMessage() );
			}
			if ( function_exists( 'wc_add_notice' ) ) {
				wc_add_notice( esc_html__( 'Please select a pickup point before placing your order.', 'parcel-selector' ), 'error' );
			}
			return;
		}
	}
}

endif; // class_exists PS_Blocks_Integration

// Inicjalizacja tylko gdy WC jest aktywny
if ( class_exists( 'Parcselect_Blocks_Integration' ) ) {
	Parcselect_Blocks_Integration::init();
}
