<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }

final class Flexilay_Woo_Rest_Proxy {

	public static function init() : void {
		add_action( 'rest_api_init', array( __CLASS__, 'register_routes' ) );
	}

	public static function register_routes() : void {
		// --- Admin-authenticated endpoints (require manage_woocommerce) ---
		register_rest_route( 'flexilay/v1', '/status', array(
			'methods'             => 'GET',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'status' ),
		) );
		register_rest_route( 'flexilay/v1', '/onboarding/complete', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'onboarding_complete' ),
		) );
		register_rest_route( 'flexilay/v1', '/plans', array(
			'methods'             => 'GET',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'plans' ),
		) );
		register_rest_route( 'flexilay/v1', '/plans/(?P<id>[A-Za-z0-9_-]+)/cancel', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'plan_cancel' ),
		) );
		register_rest_route( 'flexilay/v1', '/plans/(?P<id>[A-Za-z0-9_-]+)/delete-pending', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'plan_delete_pending' ),
		) );
		register_rest_route( 'flexilay/v1', '/plans/manual-create', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'plan_manual_create' ),
		) );
		register_rest_route( 'flexilay/v1', '/plans/(?P<id>[A-Za-z0-9_-]+)/refund-charge', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'plan_refund_charge' ),
		) );
		register_rest_route( 'flexilay/v1', '/crisp', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'set_crisp' ),
		) );
		register_rest_route( 'flexilay/v1', '/settings', array(
			array(
				'methods'             => 'GET',
				'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
				'callback'            => array( __CLASS__, 'get_settings' ),
			),
			array(
				'methods'             => 'POST',
				'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
				'callback'            => array( __CLASS__, 'post_settings' ),
				'args'                => array( 'settings' => array( 'required' => true ) ),
			),
		) );
		register_rest_route( 'flexilay/v1', '/onboarding/register', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'onboarding_register' ),
		) );
		register_rest_route( 'flexilay/v1', '/onboarding/pair', array(
			'methods'             => 'POST',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'onboarding_pair' ),
		) );
		register_rest_route( 'flexilay/v1', '/stripe/connect/start', array(
			'methods'             => 'GET',
			'permission_callback' => array( __CLASS__, 'perm_manage_woo' ),
			'callback'            => array( __CLASS__, 'stripe_connect_start' ),
		) );

		// --- Webhook endpoint (NO WordPress auth — verified by HMAC signature) ---
		register_rest_route( 'flexilay/v1', '/webhooks/plan-status', array(
			'methods'             => 'POST',
			'permission_callback' => '__return_true', // Public — HMAC-verified below
			'callback'            => array( __CLASS__, 'webhook_plan_status' ),
		) );
	}

	// -----------------------------------------------------------------------
	// PERMISSIONS
	// -----------------------------------------------------------------------
	public static function perm_manage_woo() : bool {
		return current_user_can( 'manage_woocommerce' );
	}

	// -----------------------------------------------------------------------
	// HELPERS
	// -----------------------------------------------------------------------
	private static function wp_error( string $code, string $message, int $status = 400 ) {
		return new WP_Error( $code, $message, array( 'status' => $status ) );
	}

	private static function log( string $message, array $context = array() ) : void {
		if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
			error_log( '[FlexiLay] ' . $message . ( $context ? ' | ' . wp_json_encode( $context ) : '' ) );
		}
	}

	private static function status_message_blob( array $out ) : string {
		$parts = array();
		foreach ( array( 'error', 'message', 'msg', 'detail', 'details', 'raw' ) as $key ) {
			if ( isset( $out[ $key ] ) && $out[ $key ] !== '' && $out[ $key ] !== null ) {
				$parts[] = is_scalar( $out[ $key ] ) ? (string) $out[ $key ] : wp_json_encode( $out[ $key ] );
			}
		}
		return strtolower( implode( ' | ', $parts ) );
	}

	private static function status_indicates_missing_merchant( array $out ) : bool {
		if ( isset( $out['_http'] ) && (int) $out['_http'] === 404 ) {
			return true;
		}
		$hay = self::status_message_blob( $out );
		return ( strpos( $hay, 'merchant not found' ) !== false );
	}

	/**
	 * Verify HMAC-SHA256 signature from FlexiLay backend webhooks.
	 * Signature = HMAC-SHA256(raw JSON body, installToken)
	 */
	private static function verify_webhook_signature( WP_REST_Request $req ) : bool {
		$sig = $req->get_header( 'x_flexilay_signature' );
		if ( empty( $sig ) ) {
			return false;
		}

		$secret = trim( (string) Flexilay_Woo_Options::get_install_token() );
		if ( $secret === '' ) {
			$secret = trim( (string) Flexilay_Woo_Options::get_api_key() );
		}
		if ( $secret === '' ) {
			return false;
		}

		$body = $req->get_body();
		$expected = hash_hmac( 'sha256', $body, $secret );

		return hash_equals( $expected, (string) $sig );
	}

	/**
	 * Rate-limit check using WordPress transients.
	 * Returns true if rate-limited (should block).
	 */
	private static function is_rate_limited( string $action, int $cooldown_seconds = 30 ) : bool {
		$key = 'flexilay_rl_' . $action . '_' . get_current_user_id();
		if ( get_transient( $key ) ) {
			return true;
		}
		set_transient( $key, 1, $cooldown_seconds );
		return false;
	}

	// -----------------------------------------------------------------------
	// WEBHOOK: Plan Status Update (from FlexiLay backend)
	// Mirrors Shopify's order lifecycle: hold on active, release on completed, cancel on cancelled
	// -----------------------------------------------------------------------
	public static function webhook_plan_status( WP_REST_Request $req ) {
		// Verify HMAC signature
		if ( ! self::verify_webhook_signature( $req ) ) {
			self::log( 'webhook_plan_status: invalid signature' );
			return new WP_Error( 'invalid_signature', 'Invalid webhook signature', array( 'status' => 401 ) );
		}

		$body = $req->get_json_params();
		$plan_id = isset( $body['planId'] ) ? sanitize_text_field( (string) $body['planId'] ) : '';
		$external_order_id = isset( $body['externalOrderId'] ) ? sanitize_text_field( (string) $body['externalOrderId'] ) : '';
		$status = isset( $body['status'] ) ? sanitize_text_field( (string) $body['status'] ) : '';

		if ( ! $status ) {
			return rest_ensure_response( array( 'ok' => false, 'error' => 'Missing status' ) );
		}

		self::log( 'webhook_plan_status', array( 'planId' => $plan_id, 'orderId' => $external_order_id, 'status' => $status ) );

		// Find the WooCommerce order
		$order = null;
		if ( $external_order_id && function_exists( 'wc_get_order' ) ) {
			$order = wc_get_order( absint( $external_order_id ) );
		}

		if ( ! $order ) {
			return rest_ensure_response( array( 'ok' => false, 'error' => 'Order not found' ) );
		}

		$status = strtolower( $status );

		// Map FlexiLay plan status to WooCommerce order actions
		// Mirrors Shopify flow: hold → release → cancel
		switch ( $status ) {
			case 'scheduled':
			case 'active':
				// Plan is active — put order on hold, add notes
				if ( ! in_array( $order->get_status(), array( 'on-hold' ), true ) ) {
					$order->update_status( 'on-hold', 'FlexiLay: Payment plan active — hold until fully paid.' );
				}
				// Add FlexiLay metadata
				$order->update_meta_data( '_flexilay_plan_id', $plan_id );
				$order->update_meta_data( '_flexilay_status', $status );
				$order->add_order_note( sprintf( 'FlexiLay plan %s is now %s.', $plan_id, $status ) );
				$order->save();
				break;

			case 'completed':
				// Plan fully paid — release hold, mark processing (ready to fulfil)
				$order->update_meta_data( '_flexilay_status', 'completed' );
				if ( in_array( $order->get_status(), array( 'on-hold', 'pending' ), true ) ) {
					$order->update_status( 'processing', 'FlexiLay: Plan fully paid — ready to fulfil.' );
				}
				$order->add_order_note( sprintf( 'FlexiLay plan %s is fully paid. Order ready to fulfil.', $plan_id ) );
				$order->save();
				break;

			case 'cancelled':
				// Plan cancelled — cancel WooCommerce order
				$order->update_meta_data( '_flexilay_status', 'cancelled' );
				if ( ! in_array( $order->get_status(), array( 'cancelled', 'refunded' ), true ) ) {
					$order->update_status( 'cancelled', 'FlexiLay: Payment plan was cancelled.' );
				}
				$order->add_order_note( sprintf( 'FlexiLay plan %s has been cancelled.', $plan_id ) );
				$order->save();
				break;

			case 'overdue':
				// Plan overdue — add warning note but keep on-hold
				$order->update_meta_data( '_flexilay_status', 'overdue' );
				$order->add_order_note( sprintf( 'FlexiLay plan %s has overdue payments. Customer has been notified.', $plan_id ) );
				$order->save();
				break;

			case 'refunded':
				// Plan refunded
				$order->update_meta_data( '_flexilay_status', 'refunded' );
				if ( ! in_array( $order->get_status(), array( 'refunded', 'cancelled' ), true ) ) {
					$order->update_status( 'refunded', 'FlexiLay: Payment plan was refunded.' );
				}
				$order->add_order_note( sprintf( 'FlexiLay plan %s has been refunded.', $plan_id ) );
				$order->save();
				break;

			default:
				$order->add_order_note( sprintf( 'FlexiLay plan %s status changed to: %s', $plan_id, $status ) );
				$order->save();
				break;
		}

		return rest_ensure_response( array( 'ok' => true, 'status' => $status ) );
	}

	// -----------------------------------------------------------------------
	// ADMIN ENDPOINTS (proxied to FlexiLay backend)
	// -----------------------------------------------------------------------

	public static function status( WP_REST_Request $req ) {
		$out = Flexilay_Woo_Node_Client::request( 'GET', '/api/merchant/status', array(), 'wp-admin' );

		if ( ! is_array( $out ) ) {
			$out = array( 'ok' => false, 'error' => 'invalid_status_response' );
		}

		$local_api_key = trim( (string) Flexilay_Woo_Options::get_api_key() );
		$missing       = self::status_indicates_missing_merchant( $out );

		if ( $missing ) {
			if ( $local_api_key !== '' ) {
				Flexilay_Woo_Options::set( 'api_key', '' );
			}
			$out['merchantMissing']     = true;
			$out['hasApiKey']           = false;
			$out['apiKeyPresent']       = false;
			$out['paired']              = false;
			$out['registered']          = false;
			$out['stripeConnected']     = false;
			$out['onboardingComplete']  = false;
			$out['onboardingCompleted'] = false;
		} else {
			$out['merchantMissing'] = false;
			if ( $local_api_key !== '' ) {
				$out['localApiKeyPresent'] = true;
				if ( empty( $out['hasApiKey'] ) && empty( $out['apiKeyPresent'] ) ) {
					$out['hasApiKey'] = true;
				}
				if ( empty( $out['paired'] ) && empty( $out['registered'] ) ) {
					$out['paired'] = true;
				}
			} else {
				$out['localApiKeyPresent'] = false;
			}
		}

		return rest_ensure_response( $out );
	}

	public static function plans( WP_REST_Request $req ) {
		$limit = (int) $req->get_param( 'limit' );
		if ( $limit <= 0 ) { $limit = 200; }
		$out = Flexilay_Woo_Node_Client::request( 'GET', '/api/merchant/plans', array(
			'query' => array( 'limit' => min( max( $limit, 1 ), 500 ) ),
		), 'wp-admin' );
		return rest_ensure_response( $out );
	}

	public static function set_crisp( WP_REST_Request $req ) {
		$body = $req->get_json_params();
		$enabled = ! empty( $body['enabled'] );
		if ( class_exists( 'Flexilay_Woo_Options' ) ) {
			Flexilay_Woo_Options::set_enable_crisp( (bool) $enabled );
		}
		return rest_ensure_response( array( 'ok' => true, 'enabled' => (bool) $enabled ) );
	}

	public static function get_settings( WP_REST_Request $req ) {
		$status = Flexilay_Woo_Node_Client::request( 'GET', '/api/merchant/status', array(), 'wp-admin' );
		if ( is_array( $status ) && self::status_indicates_missing_merchant( $status ) ) {
			return rest_ensure_response( array(
				'ok' => true,
				'settings' => array( 'acceptedDocs' => array() ),
				'merchantMissing' => true,
			) );
		}
		$out = Flexilay_Woo_Node_Client::request( 'GET', '/api/merchant/settings', array(), 'wp-admin' );
		return rest_ensure_response( $out );
	}

	public static function post_settings( WP_REST_Request $req ) {
		$settings = $req->get_param( 'settings' );
		if ( ! is_array( $settings ) ) {
			return self::wp_error( 'invalid_settings', 'settings must be an object', 400 );
		}
		$out = Flexilay_Woo_Node_Client::request( 'POST', '/api/merchant/settings', array(
			'body' => array( 'settings' => $settings ),
		), 'wp-admin' );
		return rest_ensure_response( $out );
	}

	public static function onboarding_register( WP_REST_Request $req ) {
		// Rate limiting
		if ( self::is_rate_limited( 'register', 30 ) ) {
			return self::wp_error( 'rate_limited', 'Please wait before trying again.', 429 );
		}

		$api_base = Flexilay_Woo_Options::get_api_base();
		if ( $api_base === '' ) {
			return self::wp_error( 'missing_api_base', 'FlexiLay API base URL is not set', 400 );
		}

		$shop = Flexilay_Woo_Options::get_shop_domain();
		$tok  = Flexilay_Woo_Options::ensure_install_token();

		$body = array(
			'businessName'  => get_bloginfo( 'name' ),
			'contactEmail'  => get_option( 'admin_email' ),
			'contactName'   => wp_get_current_user() ? wp_get_current_user()->display_name : '',
			'platform'      => 'woocommerce',
			'siteUrl'       => home_url(),
		);

		$url = $api_base . '/api/connectors/woocommerce/register';
		$resp = wp_remote_post( $url, array(
			'timeout' => 25,
			'headers' => array(
				'Content-Type'             => 'application/json',
				'X-Flexilay-Shop'          => $shop,
				'X-Flexilay-Install-Token' => $tok,
			),
			'body' => wp_json_encode( $body ),
		) );

		if ( is_wp_error( $resp ) ) {
			self::log( 'onboarding_register failed', array( 'error' => $resp->get_error_message() ) );
			return self::wp_error( 'request_failed', $resp->get_error_message(), 500 );
		}

		$code = (int) wp_remote_retrieve_response_code( $resp );
		$raw = (string) wp_remote_retrieve_body( $resp );
		$data = json_decode( $raw, true );

		if ( json_last_error() !== JSON_ERROR_NONE ) {
			self::log( 'onboarding_register: non-JSON response', array( 'http' => $code ) );
			return self::wp_error( 'non_json', 'Non-JSON response from FlexiLay', 502 );
		}

		if ( $code >= 400 ) {
			self::log( 'onboarding_register: HTTP error', array( 'http' => $code, 'error' => $data['error'] ?? '' ) );
		}

		if ( ! empty( $data['ok'] ) ) {
			Flexilay_Woo_Options::set( 'api_key', '' );
			self::log( 'onboarding_register: success' );
		}

		return rest_ensure_response( $data );
	}

	public static function plan_manual_create( WP_REST_Request $req ) {
		$body = $req->get_json_params();
		if ( ! is_array( $body ) ) { $body = array(); }

		$body['shopDomain'] = Flexilay_Woo_Options::get_shop_domain();

		$out = Flexilay_Woo_Node_Client::request( 'POST', '/api/plans/draft', array(
			'body' => $body,
		), 'wp-admin' );

		return rest_ensure_response( $out );
	}

	public static function onboarding_complete( WP_REST_Request $req ) {
		$api_base = Flexilay_Woo_Options::get_api_base();
		if ( $api_base === '' ) {
			return self::wp_error( 'missing_api_base', 'FlexiLay API base URL is not set', 400 );
		}

		$body = $req->get_json_params();
		$accepted = isset( $body['acceptedDocs'] ) ? $body['acceptedDocs'] : null;

		if ( ! is_array( $accepted ) ) {
			return self::wp_error( 'invalid_accepted_docs', 'acceptedDocs must be an array', 400 );
		}

		$return_to = admin_url( 'admin.php?page=flexilay-onboarding' );
		$signed    = Flexilay_Woo_Node_Client::sign_query( $return_to );
		if ( is_wp_error( $signed ) ) {
			return $signed;
		}
		$url = add_query_arg( $signed, $api_base . '/app/onboarding/complete' );

		$resp = wp_remote_post( $url, array(
			'timeout' => 25,
			'headers' => array(
				'Content-Type'    => 'application/x-www-form-urlencoded; charset=UTF-8',
				'X-Flexilay-Shop' => Flexilay_Woo_Options::get_shop_domain(),
			),
			'body' => array(
				'acceptedDocs' => wp_json_encode( array_values( $accepted ) ),
			),
		) );

		if ( is_wp_error( $resp ) ) {
			return self::wp_error( 'request_failed', $resp->get_error_message(), 500 );
		}

		$raw  = (string) wp_remote_retrieve_body( $resp );
		$data = json_decode( $raw, true );

		if ( json_last_error() === JSON_ERROR_NONE && is_array( $data ) ) {
			self::log( 'onboarding_complete: success' );
			return rest_ensure_response( $data );
		}

		$code = (int) wp_remote_retrieve_response_code( $resp );
		return rest_ensure_response( array( 'ok' => ( $code >= 200 && $code < 400 ), 'http' => $code ) );
	}

	public static function onboarding_pair( WP_REST_Request $req ) {
		// Rate limiting
		if ( self::is_rate_limited( 'pair', 30 ) ) {
			return self::wp_error( 'rate_limited', 'Please wait before trying again.', 429 );
		}

		$api_base = Flexilay_Woo_Options::get_api_base();
		if ( $api_base === '' ) {
			return self::wp_error( 'missing_api_base', 'FlexiLay API base URL is not set', 400 );
		}

		$shop = Flexilay_Woo_Options::get_shop_domain();
		$tok  = Flexilay_Woo_Options::ensure_install_token();

		$url = $api_base . '/api/connectors/woocommerce/pair';
		$resp = wp_remote_post( $url, array(
			'timeout' => 25,
			'headers' => array(
				'Content-Type'             => 'application/json',
				'X-Flexilay-Shop'          => $shop,
				'X-Flexilay-Install-Token' => $tok,
			),
			'body' => wp_json_encode( array( 'ok' => true ) ),
		) );

		if ( is_wp_error( $resp ) ) {
			self::log( 'onboarding_pair failed', array( 'error' => $resp->get_error_message() ) );
			return self::wp_error( 'request_failed', $resp->get_error_message(), 500 );
		}

		$code = (int) wp_remote_retrieve_response_code( $resp );
		$raw = (string) wp_remote_retrieve_body( $resp );
		$data = json_decode( $raw, true );

		if ( json_last_error() !== JSON_ERROR_NONE ) {
			return self::wp_error( 'non_json', 'Non-JSON response from FlexiLay', 502 );
		}

		if ( $code >= 400 ) {
			self::log( 'onboarding_pair: HTTP error', array( 'http' => $code ) );
		}

		// Persist apiKey if returned
		$api_key = '';
		if ( ! empty( $data['apiKey'] ) && is_string( $data['apiKey'] ) ) {
			$api_key = (string) $data['apiKey'];
		} elseif ( ! empty( $data['data']['apiKey'] ) && is_string( $data['data']['apiKey'] ) ) {
			$api_key = (string) $data['data']['apiKey'];
		} elseif ( ! empty( $data['merchant']['apiKey'] ) && is_string( $data['merchant']['apiKey'] ) ) {
			$api_key = (string) $data['merchant']['apiKey'];
		}
		if ( $api_key !== '' ) {
			Flexilay_Woo_Options::set( 'api_key', sanitize_text_field( $api_key ) );
			$data['apiKey'] = $api_key;
			self::log( 'onboarding_pair: API key received and stored' );
		} else {
			Flexilay_Woo_Options::set( 'api_key', '' );
		}

		return rest_ensure_response( $data );
	}

	public static function stripe_connect_start( WP_REST_Request $req ) {
		$api_base = Flexilay_Woo_Options::get_api_base();
		if ( $api_base === '' ) {
			return self::wp_error( 'missing_api_base', 'FlexiLay API base URL is not set', 400 );
		}

		$return_to = admin_url( 'admin.php?page=flexilay-onboarding' );
		$signed = Flexilay_Woo_Node_Client::sign_query( $return_to );
		$url    = add_query_arg( $signed, $api_base . '/api/stripe/connect/start' );

		$resp = wp_remote_get( $url, array(
			'timeout'     => 25,
			'redirection' => 0,
			'headers'     => array(
				'X-Flexilay-Shop' => Flexilay_Woo_Options::get_shop_domain(),
			),
		) );

		if ( is_wp_error( $resp ) ) {
			self::log( 'stripe_connect_start failed', array( 'error' => $resp->get_error_message() ) );
			return self::wp_error( 'request_failed', $resp->get_error_message(), 500 );
		}

		$code = (int) wp_remote_retrieve_response_code( $resp );
		$loc  = wp_remote_retrieve_header( $resp, 'location' );

		if ( is_array( $loc ) ) {
			$loc = reset( $loc );
		}

		// Handle redirect response (Location header)
		if ( $code >= 300 && $code < 400 && ! empty( $loc ) ) {
			$loc = (string) $loc;
			if ( strpos( $loc, 'http://' ) !== 0 && strpos( $loc, 'https://' ) !== 0 ) {
				$loc = rtrim( $api_base, '/' ) . '/' . ltrim( $loc, '/' );
			}
			return rest_ensure_response( array( 'ok' => true, 'url' => $loc, 'http' => $code ) );
		}

		$raw  = (string) wp_remote_retrieve_body( $resp );
		$data = json_decode( $raw, true );

		// Handle JSON response
		if ( json_last_error() === JSON_ERROR_NONE && is_array( $data ) ) {
			if ( ! empty( $data['url'] ) ) {
				return rest_ensure_response( array( 'ok' => true, 'url' => (string) $data['url'], 'http' => $code ) );
			}
			if ( ! empty( $data['redirectUrl'] ) ) {
				return rest_ensure_response( array( 'ok' => true, 'url' => (string) $data['redirectUrl'], 'http' => $code ) );
			}
			return rest_ensure_response( array( 'ok' => false, 'error' => $data['error'] ?? 'stripe_connect_failed', 'http' => $code ) );
		}

		// Handle HTML response — extract Stripe URL with strict validation
		if ( $code >= 200 && $code < 300 && is_string( $raw ) && $raw !== '' ) {
			if ( preg_match( '#(https://connect\.stripe\.com/oauth/authorize\?[^"\s<\']+)#i', $raw, $m ) ) {
				$u = (string) $m[1];
				$u = str_replace( array( "\\u0026", "&amp;" ), "&", $u );
				$u = str_replace( array( "\\/" ), "/", $u );
				// Validate extracted URL starts with Stripe domain
				if ( strpos( $u, 'https://connect.stripe.com/' ) === 0 ) {
					return rest_ensure_response( array( 'ok' => true, 'url' => $u, 'http' => $code, 'mode' => 'html_scan' ) );
				}
			}
		}

		return rest_ensure_response( array( 'ok' => false, 'error' => 'unexpected_response', 'http' => $code ) );
	}

	// -----------------------------------------------------------------------
	// PLAN ACTIONS (proxied to FlexiLay backend)
	// -----------------------------------------------------------------------

	public static function plan_cancel( WP_REST_Request $req ) {
		$id = sanitize_text_field( (string) $req['id'] );
		$out = Flexilay_Woo_Node_Client::request( 'POST', '/api/plans/' . rawurlencode( $id ) . '/cancel', array(
			'body' => array(),
		), 'wp-admin' );
		self::log( 'plan_cancel', array( 'planId' => $id, 'ok' => ! empty( $out['ok'] ) ) );
		return rest_ensure_response( $out );
	}

	public static function plan_delete_pending( WP_REST_Request $req ) {
		$id = sanitize_text_field( (string) $req['id'] );
		$out = Flexilay_Woo_Node_Client::request( 'POST', '/api/plans/' . rawurlencode( $id ) . '/delete-pending', array(
			'body' => array(),
		), 'wp-admin' );
		self::log( 'plan_delete_pending', array( 'planId' => $id, 'ok' => ! empty( $out['ok'] ) ) );
		return rest_ensure_response( $out );
	}

	public static function plan_refund_charge( WP_REST_Request $req ) {
		$id = sanitize_text_field( (string) $req['id'] );
		$body = $req->get_json_params();
		$charge_id = isset( $body['chargeId'] ) ? sanitize_text_field( (string) $body['chargeId'] ) : '';
		$out = Flexilay_Woo_Node_Client::request( 'POST', '/api/plans/' . rawurlencode( $id ) . '/refund', array(
			'body' => array( 'chargeId' => $charge_id ),
		), 'wp-admin' );
		self::log( 'plan_refund_charge', array( 'planId' => $id, 'chargeId' => $charge_id, 'ok' => ! empty( $out['ok'] ) ) );
		return rest_ensure_response( $out );
	}

	// -----------------------------------------------------------------------
	// ORDER STATUS (admin-triggered, requires manage_woocommerce)
	// -----------------------------------------------------------------------

	public static function order_set_status( WP_REST_Request $req ) {
		// This endpoint is intentionally removed.
		// Order status is now managed exclusively through the webhook_plan_status endpoint
		// which requires HMAC signature verification from the FlexiLay backend.
		return self::wp_error( 'deprecated', 'Use the webhook endpoint for order status updates.', 410 );
	}
}
