<?php

namespace WeDevs\AppBridge\Integrations\WPERP\REST;

use WeDevs\AppBridge\Core\REST\BaseController;
use WeDevs\AppBridge\Integrations\WPERP\LicenseManager;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * Proof-of-possession endpoint for the mobile-app license flow.
 *
 * The wperp.com server hands the app a one-time `nonce`. The app brings that nonce here,
 * to the customer's own site, while authenticated as a real WP ERP user. The
 * site answers with HMAC_SHA256(stored_license_key, nonce). wperp.com then
 * recomputes the same HMAC from the key it has on record and confirms the
 * match.
 *
 * Security properties
 * -------------------
 *  - The raw license key never leaves the site — only the HMAC does.
 *  - The route requires an authenticated user, so a stranger who merely knows
 *    a licensed site's URL cannot trigger attestation: they have no login.
 *  - Because the proof must come from *this* site's stored key, a guessed or
 *    relayed site URL cannot satisfy wperp.com's final check.
 */
class AttestController extends BaseController {

	/**
	 * Match the WP ERP integration namespace.
	 *
	 * @var string
	 */
	protected $namespace = 'app-bridge/v1/wp-erp';

	/**
	 * @var LicenseManager
	 */
	private $license_manager;

	public function __construct( LicenseManager $license_manager ) {
		$this->license_manager = $license_manager;
	}

	public function register_routes(): void {
		register_rest_route(
			$this->namespace,
			'/attest',
			[
				[
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'attest' ],
					'permission_callback' => [ $this, 'permission_callback' ],
					'args'                => [
						'nonce' => [
							'required'          => true,
							'type'              => 'string',
							'sanitize_callback' => 'sanitize_text_field',
						],
					],
				],
			]
		);
	}

	/**
	 * Only an authenticated user (session or app JWT) may attest. This is what
	 * stops a third party who knows the site URL from proving ownership.
	 *
	 * @return bool
	 */
	public function permission_callback(): bool {
		return is_user_logged_in();
	}

	/**
	 * Return HMAC_SHA256( license_key, nonce ).
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function attest( $request ) {
		$nonce       = (string) $request['nonce'];
		$license_key = $this->license_manager->get_license_key();

		if ( '' === $license_key ) {
			return new WP_Error(
				'no_license',
				__( 'This site has no activated ERP App license to attest.', 'app-bridge' ),
				[ 'status' => 409 ]
			);
		}

		return rest_ensure_response(
			[
				'proof' => hash_hmac( 'sha256', $nonce, $license_key ),
			]
		);
	}
}
