<?php
/**
 * WebhookManager
 * ─────────────────────────────────────────────────────────────────────────────
 * Wrapper around the Squaresync-for-Woo proxy API that creates, updates,
 * pauses / resumes and deletes Square webhook subscriptions *via* your
 * developer PAT (held only on the remote server).
 *
 * @package Pixeldev\SquareWooSync\Webhooks
 */

namespace Pixeldev\SquareWooSync\Setup;

defined( 'ABSPATH' ) || exit;

/**
 * Class WebhookManager
 */
class WebhookManager {

	/** @var string Base REST URL for the proxy server */
	private string $base;

	/** @var string Env to use when none supplied (live|sandbox) */
	private string $default_env;

	/**
	 * Ctor.
	 *
	 * @param string $base_url     Proxy root (no trailing slash).
	 * @param string $default_env  Default env ('live' or 'sandbox').
	 */
	public function __construct(
		string $base_url     = 'https://proxy.squaresyncforwoo.com/wp-json/square-oauth/v1',
		string $default_env  = 'live'
	) {
		$this->base         = untrailingslashit( $base_url );
		$this->default_env  = strtolower( $default_env ) === 'sandbox' ? 'sandbox' : 'live';
	}

	/* ─────────────────────────────────────────────────────────────
	 *  Public CRUD
	 * ──────────────────────────────────────────────────────────── */

	/**
	 * Create a new webhook subscription.
	 *
	 * @param string   $merchant_id Square merchant ID.
	 * @param string   $merchant_name Square merchant name.
	 * @param string   $callback    Absolute callback URL.
	 * @param string[] $events      Event type array.
	 * @param string   $env         live|sandbox (optional).
	 * @return array{success:bool,data?:mixed,error?:string}
	 */
	public function create(
		string $merchant_id,
		string $merchant_name,
		string $callback,
		array  $events,
		string $env = ''
	): array {
		return $this->request(
			'POST',
			'/webhook',
			[
				'env'          => $this->env( $env ),
				'merchant_id'  => $merchant_id,
				'merchant_name'  => $merchant_name,
				'callback_url' => $callback,
				'events'       => array_values( $events ),
			]
		);
	}

	/**
	 * Replace the event list for a subscription.
	 *
	 * @param string   $sub_id Subscription UUID.
	 * @param string[] $events New event list.
	 * @param string   $env    live|sandbox (optional).
	 * @return array{success:bool,data?:mixed,error?:string}
	 */
	public function update_events( string $sub_id, array $events, string $env = '' ): array {
		return $this->request(
			'PUT',
			"/webhook/{$sub_id}",
			[
				'env'    => $this->env( $env ),
				'events' => array_values( $events ),
			]
		);
	}

	/**
	 * Pause or re-enable a subscription.
	 *
	 * @param string  $sub_id  Subscription UUID.
	 * @param bool    $enable  True=enable, False=pause.
	 * @param string  $env     live|sandbox (optional).
	 * @return array{success:bool,data?:mixed,error?:string}
	 */
	public function toggle( string $sub_id, bool $enable, string $env = '' ): array {
		return $this->request(
			'PATCH',
			"/webhook/{$sub_id}",
			[
				'env'     => $this->env( $env ),
				'enabled' => $enable,
			]
		);
	}

	/**
	 * Delete a subscription completely.
	 *
	 * @param string $sub_id Subscription UUID.
	 * @param string $env    live|sandbox (optional).
	 * @return array{success:bool,data?:mixed,error?:string}
	 */
	public function delete( string $sub_id, string $env = '' ): array {
		return $this->request(
			'DELETE',
			"/webhook/{$sub_id}",
			[
				'env' => $this->env( $env ),
			]
		);
	}

	/* ─────────────────────────────────────────────────────────────
	 *  Internal helpers
	 * ──────────────────────────────────────────────────────────── */

	/**
	 * Perform the remote call and normalise the output.
	 *
	 * @param string $method  HTTP verb.
	 * @param string $path    Endpoint path (leading slash).
	 * @param array  $body    JSON body (optional).
	 * @return array{success:bool,data?:mixed,error?:string}
	 */
	private function request( string $method, string $path, array $body = [] ): array {

		$args = [
			'method'      => $method,
			'headers'     => [ 'Accept' => 'application/json' ],
			'timeout'     => 15,
		];

		if ( $method !== 'GET' && ! empty( $body ) ) {
			$args['headers']['Content-Type'] = 'application/json';
			$args['body']                    = wp_json_encode( $body );
		}

		$res = wp_remote_request( esc_url_raw( $this->base . $path ), $args );

		if ( is_wp_error( $res ) ) {
			error_log( '[WebhookManager] HTTP error: ' . $res->get_error_message() );
			return [ 'success' => false, 'error' => $res->get_error_message() ];
		}

		$code = wp_remote_retrieve_response_code( $res );
		$data = json_decode( wp_remote_retrieve_body( $res ), true );

		if ( $code >= 200 && $code < 300 ) {
			return [ 'success' => true, 'data' => $data ];
		}

		$msg = is_array( $data ) ? wp_json_encode( $data ) : (string) $data;
		error_log( sprintf( '[WebhookManager] Proxy error (%d): %s', $code, $msg ) );

		return [ 'success' => false, 'error' => $msg ];
	}

	/**
	 * Resolve requested env or fall back to default.
	 *
	 * @param string $env live|sandbox or ''.
	 * @return string live|sandbox
	 */
	private function env( string $env ): string {
		return strtolower( $env ) === 'sandbox' ? 'sandbox' : $this->default_env;
	}
}
