<?php

/**
 * Registration Manager
 *
 * @package _121Digital\Connect
 */

namespace _121Digital\Connect\Registration;

use _121Digital\Connect\Security\KeyManager;

/**
 * Registration Manager Class
 *
 * Handles site registration with 121 Digital platform
 */
class RegistrationManager
{
    /**
     * Key Manager instance
     *
     * @var KeyManager
     */
    private KeyManager $keyManager;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->keyManager = new KeyManager();
    }

    /**
     * Register this component
     *
     * @return void
     */
    public function register(): void
    {
        // Hooks can be added here if needed
    }

    /**
     * Check if site has registration data
     *
     * @return bool
     */
    public function hasRegistrationData(): bool
    {
        $existingPublicKey = get_option('sc_public_key');
        $existingPrivateKey = get_option('sc_private_key');
        $existingPrivateKeyIv = get_option('sc_private_key_iv');

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

    /**
     * Get the public IP address of the current server
     *
     * @return string|null
     */
    private function getPublicIp(): ?string
    {
        $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 site disconnection
     *
     * @return array
     */
    public function disconnect(): array
    {
        if (!isset($_POST['sc_disconnect_nonce']) || !wp_verify_nonce($_POST['sc_disconnect_nonce'], 'sc_disconnect_site_action')) {
            return ['success' => false, 'message' => 'Security check failed.'];
        }

        $siteId = get_option('sc_site_id');
        $siteUrl = get_site_url();

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

        delete_option('sc_private_key');
        delete_option('sc_private_key_iv');
        delete_option('sc_public_key');
        delete_option('sc_site_registered');
        delete_option('sc_site_public_ip');

        return ['success' => true];
    }

    /**
     * Verify site registration
     *
     * @return array
     */
    public function verify(): array
    {
        $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.',
            ];
        }

        $optionsSiteId = get_option('sc_site_id');
        $optionsBackendToken = get_option('sc_backend_token');

        $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,
                'backend_token' => $optionsBackendToken,
            ],
            'timeout' => 120,
        ]);

        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'];
        update_option('sc_last_communication', date('Y-m-d H:i:s'));

        $responseBody = json_decode($body);
        if ($responseBody->response_data->registration_valid) {
            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
     *
     * @return array
     */
    public function handleRegistration(): array
    {
        $publicKey = '';
        $privateKey = '';
        $iv = '';

        $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 = $this->keyManager->generateKeypair();
            if (!$keypair['success']) {
                return $keypair;
            }

            $publicKey = $keypair['public_key'];
            $privateKey = $keypair['private_key_encrypted'];
            $iv = $keypair['iv'];
        } else {
            $publicKey = $existingPublicKey;
            $privateKey = $existingPrivateKey;
            $iv = $existingPrivateKeyIv;
        }

        $publicIp = $this->getPublicIp();

        if (get_option('sc_site_id') === false) {
            $siteId = $this->keyManager->generateRandomString(25);
            update_option('sc_site_id', $siteId);
        }
        $siteId = get_option('sc_site_id');

        if (get_option('sc_site_token') === false) {
            $siteToken = $this->keyManager->generateRandomString(25);
            update_option('sc_site_token', $siteToken);
        }
        $siteToken = get_option('sc_site_token');

        $generatedRegistrationId = $this->keyManager->generateRandomString(25);
        update_option('sc_registration_id', $generatedRegistrationId);

        update_option('sc_private_key', $privateKey);
        update_option('sc_private_key_iv', $iv);
        update_option('sc_public_key', $publicKey);
        update_option('sc_site_registered', true);
        update_option('sc_site_public_ip', $publicIp);

        $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' => $publicKey,
                'site_token' => $siteToken,
                'plugin_version' => SC_PLUGIN_VERSION,
                'site_id' => $siteId,
                'ip_address' => $publicIp,
                'registration_id' => $generatedRegistrationId,
            ],
            'timeout' => 120,
        ]);

        $body = $response['body'];

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

        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 ['success' => true, 'message' => 'The site has been registered with 121 Digital.'];
        } else {
            return ['success' => false, 'message' => $responseBody->response_data->reason];
        }
    }
}
