<?php

namespace Phox\core;

class License_Activation
{
    /**
     * option name
     *
     * On table `wp-options` it need 2 column the first column is option_name so this the value of this column
     */
    const OPTIONS_NAME = 'wdes_license_information_data';

    const WDES_PLATFORM_URL = 'https://platform.wdes.org';

    const WDES_PORTAL_URL = 'https://wdes.org/activate';

    /**
     * License Information data container
     *
     * List of the information that will use on class
     *
     * @var array
     */
    private array $license_information = [];

    public function __construct()
    {

        $this->set_license_information();

        if(empty($this->license_information['purchase_code'])){
            $this->api_init();
        }

    }

    /**
     * Set the $license_information with data license
     *
     * Check wp_options with value option name to find if add license on it or not and then set it on property
     *
     * @link https://developer.wordpress.org/reference/functions/get_option/
     * @return void
     */
    public function set_license_information(): void
    {
        $license_data_default = [
            'purchase_code' => '',
            'status' => false
        ];

        $license_data_db = get_option(self::OPTIONS_NAME, $license_data_default);

        $this->license_information = wp_parse_args($license_data_db, $license_data_default);

    }

    /**
     * Determines whether a license is activated based on purchase code and registration status.
     *
     * @return bool True if the license is activated, False otherwise.
     */
    public function does_activated()
    {

        return ! empty($this->license_information['purchase_code']) && $this->license_information['status'];

    }


    /**
     * Take the license from client to WDES server to register the product
     *
     * @link https://developer.wordpress.org/reference/functions/wp_remote_post/
     * @link https://developer.wordpress.org/reference/functions/wp_remote_retrieve_response_code/
     * @return void
     */
    public function register_license():void
    {
        if( !empty( $_POST['purchaseCode'] ) && wp_verify_nonce( $_POST['activationNonce'], 'wp_rest' ) ) {

            $purchase_code = $this->prepare_purchase_code( $_POST['purchaseCode'] );

            $this->license_information['purchase_code'] = $purchase_code;
            $this->license_information['status'] = true;

            update_option( self::OPTIONS_NAME, $this->license_information );

            set_transient( 'wdes_fresh_install', 'fresh' );

            wp_send_json([], 200);

        }
        wp_send_json([
            'error' => [
                'message'  => 'Missing purchase code',
            ],
        ], 400);

    }


    /**
     * Establishes a connection to a remote server using a POST request with the provided purchase code and path.
     *
     * @link https://developer.wordpress.org/reference/functions/wp_remote_post/
     * @link https://developer.wordpress.org/reference/functions/wp_remote_retrieve_response_code/
     * @param string $purchase_code
     * @param string $path
     * @return array
     */
    private function connection( string $purchase_code, string $path ): array
    {

        $body = array(
            'url'    => get_site_url(),
            'code'   => $purchase_code,
            'source' => 'wordpress',
        );

        $args = array(
            'timeout'    => 60,
            'body'        => $body,
        );

        $connection = wp_remote_post( self::WDES_PLATFORM_URL . '/'.$path ,$args);

        if( is_object($connection) ){
            $connection = [];
            $connection['body'] = json_encode([
                'error' => [
                    'message' => 'cURL error'
                ]
            ]);
        }

        return array (
            'code' => wp_remote_retrieve_response_code( $connection ),
            'body' => json_decode( $connection['body'], true )
        );

    }

    /**
     * Prepares a purchase code for safe usage.
     *
     * @link https://developer.wordpress.org/reference/functions/wp_unslash/
     * @link https://developer.wordpress.org/reference/functions/sanitize_text_field/
     * @link https://developer.wordpress.org/reference/functions/wp_strip_all_tags/
     *
     * @param string $code The raw purchase code to be processed.
     *
     * @return string The sanitized and prepared purchase code.
     */
    private function prepare_purchase_code(string $code): string
    {

         //Removes any slashes that might have been added for escaping purposes.

        $slash = wp_unslash($code);


        //Sanitizes the code for safe usage in a text field context, removing potentially harmful characters.

        $sanitize = sanitize_text_field($slash);


        //Removes any leading or trailing whitespace from the code.

        $whitespace = trim($sanitize);


        //Removes any HTML or PHP tags that might be present in the code, preventing potential code injection.

        $tags = wp_strip_all_tags($whitespace);

        // Use preg_match to check if the UUID matches the pattern
        $pattern = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';
        if (!preg_match($pattern, $tags)) {
            wp_send_json([
                'error' => [
                    'message'  => 'Missing purchase code',
                ],
            ], 400);
        }

        return $tags;
    }


    /**
     * Obfuscates a purchase code by replacing half of it with asterisks.
     *
     * This function takes a purchase code as input, typically retrieved from a license information array, and transforms it to hide a portion of the code for security reasons.
     *
     * @return string The obfuscated purchase code with half replaced by asterisks.
     *
     * If the provided purchase code is empty, the function returns an empty string.
     */
    public function show_license_code()
    {
        $purchase_code = $this->license_information['purchase_code'];

        // Check if the purchase code is empty
        if (empty($purchase_code)) {
            return '';
        }

        // Calculate the length of the first half of the code (assuming equal halves)
        $code_length = strlen($purchase_code) / 4;

        // Extract the first half of the code
        $first_half = substr($purchase_code, 0, $code_length);

        // Create a string of asterisks with the same length as the first half
        $asterisks = str_repeat('*', $code_length);

        // Combine the first half of the code and the asterisks
        $obfuscated_code = $first_half . $asterisks;

        return $obfuscated_code;
    }


    public function api_init():void
    {
        add_action('rest_api_init', [$this, 'register_routes']);
    }

    public function register_routes(){

        register_rest_route(
            route_namespace: 'wdes',
            route: 'activate-license',
            args: [
                'methods' => 'POST',
                'callback' => [$this, 'register_license'],
                'permission_callback' => function () {
                    return current_user_can('administrator');
                }
            ]
        );


    }

}