<?php
defined( 'ABSPATH' ) || exit;

/*
 * 247ChatMate — Secret-free terminal paid-status check.
 *
 * The customer plugin never receives a private server signing secret.
 * It proves control of this WordPress installation with a short-lived
 * one-time REST proof. The .pro server then matches LemonSqueezy lifecycle
 * state using non-secret LemonSqueezy object identifiers returned by the
 * normal licence validation response.
 */

if ( ! defined( 'MATEWA_TERMINAL_STATUS_ENDPOINT' ) ) {
	define( 'MATEWA_TERMINAL_STATUS_ENDPOINT', 'https://247trademate.pro/247chatmate/product-lifecycle.php' );
}

if ( ! defined( 'MATEWA_TERMINAL_STATUS_UUID_OPTION' ) ) {
	define( 'MATEWA_TERMINAL_STATUS_UUID_OPTION', 'matewa_terminal_status_install_uuid' );
}

if ( ! defined( 'MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT' ) ) {
	define( 'MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT', 'matewa_terminal_status_site_proof' );
}

if ( ! function_exists( 'matewa_terminal_status_install_uuid' ) ) {
	function matewa_terminal_status_install_uuid() {
		if ( function_exists( 'matewa_pro_trial_registry_get_install_uuid' ) ) {
			$uuid = trim( (string) matewa_pro_trial_registry_get_install_uuid() );
			if ( '' !== $uuid ) {
				return $uuid;
			}
		}

		$uuid = trim( (string) get_option( MATEWA_TERMINAL_STATUS_UUID_OPTION, '' ) );
		if ( '' !== $uuid ) {
			return $uuid;
		}

		$uuid = function_exists( 'wp_generate_uuid4' )
			? wp_generate_uuid4()
			: md5( home_url( '/' ) . '|' . microtime( true ) . '|' . wp_rand() );

		update_option( MATEWA_TERMINAL_STATUS_UUID_OPTION, $uuid, false );

		return $uuid;
	}
}

if ( ! function_exists( 'matewa_terminal_status_make_proof' ) ) {
	function matewa_terminal_status_make_proof() {
		try {
			$proof = bin2hex( random_bytes( 32 ) );
		} catch ( Throwable $e ) {
			$proof = wp_generate_password( 64, false, false );
		}

		set_transient(
			MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT,
			array(
				'uuid'    => matewa_terminal_status_install_uuid(),
				'hash'    => hash( 'sha256', $proof ),
				'expires' => time() + 180,
			),
			180
		);

		return $proof;
	}
}

if ( ! function_exists( 'matewa_terminal_status_proof_callback' ) ) {
	function matewa_terminal_status_proof_callback( WP_REST_Request $request ) {
		$uuid  = sanitize_text_field( (string) $request->get_param( 'install_uuid' ) );
		$proof = sanitize_text_field( (string) $request->get_param( 'proof' ) );
		$saved = get_transient( MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT );

		$ok = is_array( $saved )
			&& (int) ( $saved['expires'] ?? 0 ) >= time()
			&& hash_equals( (string) ( $saved['uuid'] ?? '' ), $uuid )
			&& hash_equals( (string) ( $saved['hash'] ?? '' ), hash( 'sha256', $proof ) );

		if ( ! $ok ) {
			return new WP_REST_Response( array( 'ok' => false ), 403 );
		}

		delete_transient( MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT );

		return new WP_REST_Response(
			array(
				'ok'           => true,
				'install_uuid' => $uuid,
			),
			200
		);
	}
}

add_action(
	'rest_api_init',
	static function() {
		register_rest_route(
			'247chatmate/v1',
			'/terminal-status-proof',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => 'matewa_terminal_status_proof_callback',
				'permission_callback' => '__return_true',
			)
		);
	}
);

if ( ! function_exists( 'matewa_terminal_status_check' ) ) {
	function matewa_terminal_status_check( $license_meta = array() ) {
		$license_meta = is_array( $license_meta ) ? $license_meta : array();

		$order_id      = sanitize_text_field( (string) ( $license_meta['order_id'] ?? '' ) );
		$order_item_id = sanitize_text_field( (string) ( $license_meta['order_item_id'] ?? '' ) );
		$customer_id   = sanitize_text_field( (string) ( $license_meta['customer_id'] ?? '' ) );
		$product_id    = sanitize_text_field( (string) ( $license_meta['product_id'] ?? '' ) );
		$variant_id    = sanitize_text_field( (string) ( $license_meta['variant_id'] ?? '' ) );

		/*
		 * Without a LemonSqueezy object identifier there is nothing reliable
		 * to match server-side. Fail open here and leave the normal licence
		 * validation result unchanged.
		 */
		if ( '' === $order_id && '' === $order_item_id && '' === $customer_id ) {
			return array(
				'ok'       => false,
				'code'     => 'no_match_identifiers',
				'terminal' => false,
			);
		}

		$proof = matewa_terminal_status_make_proof();

		$payload = array(
			'action'          => 'entitlement_status',
			'site_url'        => esc_url_raw( home_url( '/' ) ),
			'install_uuid'    => matewa_terminal_status_install_uuid(),
			'plugin_version'  => defined( 'MATEWA_VERSION' ) ? (string) MATEWA_VERSION : '',
			'release_channel' => defined( 'MATEWA_DISTRIBUTION_PROFILE' ) ? (string) MATEWA_DISTRIBUTION_PROFILE : 'free',
			'proof_url'       => esc_url_raw( rest_url( '247chatmate/v1/terminal-status-proof' ) ),
			'site_proof'      => $proof,
			'order_id'        => $order_id,
			'order_item_id'   => $order_item_id,
			'customer_id'     => $customer_id,
			'product_id'      => $product_id,
			'variant_id'      => $variant_id,
		);

		$response = wp_remote_post(
			MATEWA_TERMINAL_STATUS_ENDPOINT,
			array(
				'timeout' => 12,
				'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ),
				'body'    => wp_json_encode( $payload, JSON_UNESCAPED_SLASHES ),
			)
		);

		if ( is_wp_error( $response ) ) {
			return array(
				'ok'       => false,
				'code'     => 'status_unavailable',
				'terminal' => false,
			);
		}

		$status_code = (int) wp_remote_retrieve_response_code( $response );
		$data        = json_decode( (string) wp_remote_retrieve_body( $response ), true );

		if ( $status_code < 200 || $status_code >= 300 || ! is_array( $data ) ) {
			return array(
				'ok'       => false,
				'code'     => 'invalid_status_response',
				'terminal' => false,
			);
		}

		return array(
			'ok'                  => ! empty( $data['ok'] ),
			'code'                => sanitize_key( (string) ( $data['code'] ?? '' ) ),
			'terminal'            => ! empty( $data['terminal'] ),
			'stored_status'       => sanitize_key( (string) ( $data['stored_status'] ?? '' ) ),
			'subscription_status' => sanitize_key( (string) ( $data['subscription_status'] ?? '' ) ),
			'last_event'          => sanitize_key( (string) ( $data['last_event'] ?? '' ) ),
		);
	}
}
