<?php

namespace WeDevs\AppBridge\Core\REST;

class LicenseVerificationController extends BaseController {
    /**
     * @var string
     */
    protected $rest_base = 'license';

    /**
     *
     * @var \WeDevs\AppBridge\Core\Auth\JwtAuth
     */
    protected $jwt_auth;

    /**
     * LicenseVerificationController constructor.
     */
    public function __construct() {
        $this->jwt_auth = new \WeDevs\AppBridge\Core\Auth\JwtAuth();
    }

    /**
     * Register Routes
     *
     * @since SINCE_TAG
     *
     * @return void
     */
    public function register_routes(): void {
        register_rest_route(
            $this->namespace, '/' . $this->rest_base . '/(?P<app_name>[a-zA-Z0-9\-\/]+)/verification-token', array(
                'methods'             => 'POST',
                'callback'            => array( $this, 'get_verification_token' ),
                'permission_callback' => '__return_true',
            )
        );
        register_rest_route(
            $this->namespace, '/' . $this->rest_base . '/(?P<app_name>[a-zA-Z0-9\-\/]+)/verification-failed', array(
                'methods'             => 'POST',
                'args'                => array(
                    'errors' => array(
                        'required' => true,
                        'type'     => 'object',
                        'description' => __( 'Error details for the failed license verification attempt', 'app-bridge' ),
                    ),
                ),
                'callback'            => array( $this, 'notify_verification_failed' ),
                'permission_callback' => '__return_true',
            )
        );
    }

    /**
     * Get a JWT token for license verification.
     * @since SINCE_TAG
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response|\WP_Error
     */
    public function get_verification_token( $request ) {
        $app_name = $request['app_name'];
        $app_bridge_license = apply_filters( 'app_bridge_license_for_' . $app_name, null, $app_name );

        if ( ! $app_bridge_license ) {
            return new \WP_Error( 'no_license', __( 'No license found for the specified app', 'app-bridge' ), [ 'status' => 404 ] );
        }

        $payload = [
            'app_name' => $app_name,
            'license'  => $app_bridge_license,
        ];

        /**
         * Same token will be send as response which help the Appsero to manage cache for the license verification results.
         * The token will be cached until the license verification result is valid.
         */
        $cache_data = apply_filters( 'app_bridge_rest_' . $app_name . '_license_verification_cache_data', null, $app_name );

        if ( $cache_data && isset( $cache_data['verification_token'] ) && isset( $cache_data['expires_in'] ) && $cache_data['expires_in'] > time() ) {
            return rest_ensure_response(
                [
					'verification_token' => $cache_data['verification_token'],
					'expires_in' => $cache_data['expires_in'],
				]
            );
        }

        // Generate a new token and cache it
        $token = $this->jwt_auth->encode( $payload, $app_bridge_license );

        $data = [
            'verification_token' => $token,
            'expires_in' => $this->jwt_auth->get_expire_at(),
        ];

        do_action( 'app_bridge_rest_' . $app_name . '_license_verification_data_generated', $data, $app_name, $this->jwt_auth->get_ttl() );

        return rest_ensure_response( $data );
    }


    /**
     * Get a JWT token for license verification.
     * @since SINCE_TAG
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response|\WP_Error
     */
    public function notify_verification_failed( $request ) {

        do_action( 'app_bridge_rest_' . $request['app_name'] . '_license_verification_failed', $request['errors'], $request['app_name'] );

        return rest_ensure_response(
            [
				'message' => __( 'License verification failed notification received', 'app-bridge' ),
			]
        );
    }
}
