<?php

function sc_has_registration_data()
{
    // verify the existence of keys and backend token...
    $existingPublicKey = get_option('sc_public_key');
    $existingPrivateKey = get_option('sc_private_key');
    $existingPrivateKeyIv = get_option('sc_private_key_iv');

    if ($existingPublicKey == false || $existingPrivateKey == false || $existingPrivateKeyIv == false) {
        return false;
    }

    return true;
}

/**
 * Get the public IP address of the current server using ipify API.
 *
 * @return string|null Returns the IP address if successful, or null if the request failed.
 */
function sc_get_public_ip()
{
    $response = wp_remote_get('https://api.ipify.org?format=json', ['timeout' => 5]);

    if (is_wp_error($response)) {
        return null;
    }

    $body = json_decode(wp_remote_retrieve_body($response), true);
    return $body['ip'] ?? null;
}

/**
 * Handle disconnecting the site from the 121 Digital platform.
 *
 * - Verifies the security nonce.
 * - Notifies the backend of the disconnection if a site ID exists.
 * - Deletes all local keys and registration flags (except site ID).
 *
 * @return array Result status and message.
 */
function sc_handle_disconnect()
{
    if (!isset($_POST['sc_disconnect_nonce']) || !wp_verify_nonce($_POST['sc_disconnect_nonce'], 'sc_disconnect_site_action')) {
        return ['success' => false, 'message' => 'Security check failed.'];
    }

    $site_id = get_option('sc_site_id');
    $site_url = get_site_url();

    // Optional: Notify backend of disconnection
    if ($site_id) {
        wp_remote_post(SC_REMOTE_API_BASE . '/v3/registration/disconnect-wp-site', [
          'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
          'body' => [
            'site_id'  => $site_id,
            'site_url' => $site_url,
          ],
          'timeout' => 10,
        ]);
    }

    // Delete local registration data (except site ID)
    delete_option('sc_private_key');
    delete_option('sc_private_key_iv');
    delete_option('sc_public_key');
    // delete_option('sc_site_id'); // site ID should never be deleted...
    delete_option('sc_site_registered');
    delete_option('sc_site_public_ip');

    return ['success' => true];
}

/**
 * Verify if the site is correctly registered with the backend.
 *
 * - Ensures keys and tokens exist.
 * - Encrypts site data and sends a verification request to the backend.
 * - Updates the last communication timestamp.
 *
 * @return array Result status and optional message.
 */
function sc_verify_registration()
{
    // verify the existence of keys and backend token...
    $existingPublicKey = get_option('sc_public_key');
    $existingPrivateKey = get_option('sc_private_key');
    $existingPrivateKeyIv = get_option('sc_private_key_iv');

    if ($existingPublicKey == false || $existingPrivateKey == false || $existingPrivateKeyIv == false) {
        return [
          'success' => false,
          'reason' => 'Could not verify connection: Missing local keys.'
        ];
    }

    // encrypt the payload data using stored RSA keypair...
    $optionsSiteId = get_option('sc_site_id');
    $optionsBackendToken = get_option('sc_backend_token');

    // Send to backend (form-encoded)
    $response = wp_remote_post(SC_REMOTE_API_BASE . '/v3/registration/verify-wp-site', [
      'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
      'body' => [
        'site_id'       => $optionsSiteId, // site ID should NEVER be encrypted as it is used to decrypt on backend...
        'backend_token' => $optionsBackendToken
      ],
      'timeout' => 120,
    ]);

    // die(var_dump($response));

    if (is_wp_error($response)) {
        update_option('sc_site_registered', false);
        update_option('sc_last_backend_error', $response->get_error_message());
        return ['success' => false, 'message' => 'Registration Validation failed: ' . $response->get_error_message()];
    }
    $body = $response['body'];

    // record the last communication with backend...
    update_option('sc_last_communication', date('Y-m-d H:i:s'));

    $responseBody = json_decode($body);
    if ($responseBody->response_data->registration_valid) {
        // return a success response...
        update_option('sc_site_registered', true);
        return ['success' => true, 'message' => 'The site registration with 121 Digital has been verified.'];
    } else {
        update_option('sc_site_registered', false);
        update_option('sc_last_backend_error', $responseBody->response_data->reason);
        return ['success' => false, 'message' => $responseBody->response_data->reason];
    }
}

/**
 * Handle site registration with the 121 Digital platform.
 *
 * - Generates RSA key pair if not present.
 * - Registers the site with the remote backend.
 * - Stores keys, site ID, public IP, and registration ID locally.
 *
 * @return array Result status and message.
 */
function sc_handle_registration()
{
    // define base vars...
    $publicKey = '';
    $privateKey = '';
    $iv = '';

    // check if we already have a keypair...
    $existingPublicKey = get_option('sc_public_key');
    $existingPrivateKey = get_option('sc_private_key');
    $existingPrivateKeyIv = get_option('sc_private_key_iv');

    if ($existingPublicKey == false || $existingPrivateKey == false || $existingPrivateKeyIv == false) {
        $keypair = sc_generate_keypair();
        if (!$keypair['success']) {
            return $keypair;
        }

        $public_key = $keypair['public_key'];
        $private_key = $keypair['private_key_encrypted'];
        $iv = $keypair['iv'];
    } else {
        // get the existing generated public / private keypair from the options API...
        $publicKey = get_option('sc_public_key');
        $privateKey = get_option('sc_private_key');
        $iv = get_option('sc_private_key_iv');
    }

    $public_ip = sc_get_public_ip();

    // only update site ID if it has not already been generated
    if (get_option('sc_site_id') === false) {
        $site_id = sc_generate_site_id();
        update_option('sc_site_id', $site_id);
    }
    $site_id = get_option('sc_site_id');

    // only update the site token if it does not already exist...
    if (get_option('sc_site_token') === false) {
        $site_token = sc_generate_site_token();
        update_option('sc_site_token', $site_token);
    }
    $site_token = get_option('sc_site_token');

    // generate and store the registration id that is used to verify the registration...
    $generatedRegistrationId = sc_generate_registration_id();
    update_option('sc_registration_id', $generatedRegistrationId);

    // Store locally
    update_option('sc_private_key', $private_key);
    update_option('sc_private_key_iv', $iv);
    update_option('sc_public_key', $public_key);
    update_option('sc_site_registered', true);
    update_option('sc_site_public_ip', $public_ip);

    // Send to backend (form-encoded)
    $response = wp_remote_post(SC_REMOTE_API_BASE . '/v3/registration/register-wp-site', [
      'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
      'body' => [
        'site_url'        => get_site_url(),
        'public_key'      => $public_key,
        'site_token'      => $site_token,
        'plugin_version'  => SC_PLUGIN_VERSION,
        'site_id'         => $site_id,
        'ip_address'      => $public_ip,
        'registration_id' => $generatedRegistrationId
      ],
      'timeout' => 120,
    ]);

    $body = $response['body'];

    if (is_wp_error($response)) {
        return ['success' => false, 'message' => 'Registration failed: ' . $response->get_error_message()];
    }

    // record the last communication with backend...
    update_option('sc_last_communication', date('Y-m-d H:i:s'));

    $code = wp_remote_retrieve_response_code($response);

    $responseBody = json_decode($body);
    if ($responseBody->response_data->site_connected) {
        if (!isset($responseBody->response_data->backend_token)) {
            return ['success' => false, 'message' => 'No backend token was returned with the request.'];
        }

        $backendToken = $responseBody->response_data->backend_token;
        update_option('sc_backend_token', $backendToken);

        // return a success response...
        return ['success' => true, 'message' => 'The site has been registered with 121 Digital.'];
    } else {
        return ['success' => false, 'message' => $responseBody->response_data->reason];
    }

    return ['success' => true];
}
