<?php
/**
 * Pickup point validator for shipping method.
 *
 * @package DhlPolska\CheckoutBlocks
 */

namespace DhlPolska\CheckoutBlocks;

use DhlPolskaVendor\Octolize\Blocks\PickupPoint\PickupPointValidatorForShippingMethod as BasePickupPointValidatorForShippingMethod;
use DhlPolskaVendor\Octolize\Blocks\PickupPoint\SelectPickupPointException;
use WC_Shipping_Method;

class PickupPointValidatorForShippingMethod extends BasePickupPointValidatorForShippingMethod {

	/**
	 * @param string $shipping_method_id .
	 * @param string $setting_key .
	 * @param string $setting_value .
	 */
	public function __construct( string $shipping_method_id, string $setting_key, string $setting_value ) {
		parent::__construct( $shipping_method_id, $setting_key, $setting_value, '' );
	}

	/**
	 * @param string             $value .
	 * @param WC_Shipping_Method $shipping_method .
	 *
	 * @throws SelectPickupPointException .
	 */
	public function validate( string $value, WC_Shipping_Method $shipping_method ): void {
		try {
			parent::validate( $this->normalize_pickup_point_value( $value ), $shipping_method );
		} catch ( SelectPickupPointException $e ) {
			throw new SelectPickupPointException( PickupPointRequiredErrorMessage::get_error_message() );
		}
	}

	/**
	 * @param string $value .
	 *
	 * @return string
	 */
	private function normalize_pickup_point_value( string $value ): string {
		$value = trim( $value );
		if ( '' === $value ) {
			return '';
		}

		$first_char = $value[0];
		if ( '{' !== $first_char && '[' !== $first_char ) {
			return $value;
		}

		$decoded = json_decode( $value, true );
		if ( JSON_ERROR_NONE !== json_last_error() || ! is_array( $decoded ) ) {
			return '';
		}

		$point_id = trim( (string) ( $decoded['id'] ?? '' ) );

		return '' === $point_id ? '' : $value;
	}
}
