<?php

namespace Kanzu\StoreVoiceAI\Services;

// Prevent direct file access.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Store_Voice_AI_API
{
    private $api_base_url;

    public function __construct()
    {
        // $api_base_url      = "http://localhost:4002/";
        $api_base_url      = "https://api.storevoiceai.com/v1/api/";
        $this->api_base_url = $this->normalize_api_base_url($api_base_url);
    }

    private function make_api_request($endpoint, $params = array(), $request_method = 'GET')
    {
        if (empty($this->api_base_url)) {
            return new \WP_Error(
                'missing_api_base_url',
                __('StoreVoiceAI API base URL is not configured.', 'storevoiceai-for-woocommerce')
            );
        }

        $url          = $this->api_base_url . $endpoint;

        $args = array(
            'headers' => array(
                'Authorization' => 'Bearer ' . $this->get_api_key(),
                'Content-Type'  => 'application/json',
                'Accept'        => 'application/json',
            ),
            'body'    => !empty($params) ? json_encode($params) : null,
            'timeout' => 30, // Increase timeout to 30 seconds
            'connect_timeout' => 10, // Set connection timeout to 10 seconds
        );
        $response = $this->dispatch_api_request($request_method, $url, $args);
        if (is_wp_error($response)) {
            return new \WP_Error(
                'api_unreachable',
                __('Could not reach the StoreVoiceAI service. Please check your connection and try again.', 'storevoiceai-for-woocommerce'),
                array( 'detail' => $response->get_error_message() )
            );
        }
        $status_code = (int) wp_remote_retrieve_response_code($response);

        // 401 — try to mint a fresh access token from our site_key + system_email
        // and replay the request once. If we can't even attempt the retry (missing
        // creds), surface a clear error explaining what's wrong.
        if ($status_code === 401) {
            $system_email = get_option('_storevoiceai_system_email');
            $site_key     = get_option('_storevoiceai_site_key');

            if (!$system_email || !$site_key) {
                return new \WP_Error(
                    'site_not_registered',
                    __('This site is not connected to StoreVoiceAI. Please re-activate the plugin to complete setup.', 'storevoiceai-for-woocommerce'),
                    array( 'status' => 401 )
                );
            }

            $access_token = $this->get_access_token($site_key, $system_email);
            if (is_wp_error($access_token)) {
                return $access_token;
            }

            // Retry the original request with the fresh token.
            $args['headers']['Authorization'] = 'Bearer ' . $access_token;
            $response = $this->dispatch_api_request($request_method, $url, $args);
            if (is_wp_error($response)) {
                return new \WP_Error(
                    'api_unreachable',
                    __('Could not reach the StoreVoiceAI service. Please check your connection and try again.', 'storevoiceai-for-woocommerce'),
                    array( 'detail' => $response->get_error_message() )
                );
            }
            $status_code = (int) wp_remote_retrieve_response_code($response);
        }

        $body         = wp_remote_retrieve_body($response);
        $decoded      = $body === '' ? null : json_decode($body, true);

        // Anything outside 2xx is a real failure — surface a WP_Error so callers
        // can render proper feedback instead of treating garbage as success.
        if ($status_code < 200 || $status_code >= 300) {
            $message = $this->extract_error_message($decoded, $status_code);
            $code    = $this->classify_error_code($status_code, $decoded);
            return new \WP_Error(
                $code,
                $message,
                array(
                    'status'   => $status_code,
                    'response' => $decoded,
                )
            );
        }

        return $decoded;
    }

    /**
     * Pull the most useful error message out of a backend response, falling
     * back to a generic message when the body is empty or malformed.
     */
    private function extract_error_message($decoded, $status_code)
    {
        if (is_array($decoded)) {
            foreach (array('message', 'error', 'detail') as $key) {
                if (!empty($decoded[$key]) && is_string($decoded[$key])) {
                    return $decoded[$key];
                }
            }
            if (!empty($decoded['errors']) && is_array($decoded['errors'])) {
                $first = reset($decoded['errors']);
                if (is_string($first) && $first !== '') {
                    return $first;
                }
            }
        }

        if ($status_code === 401 || $status_code === 403) {
            return __('Your site lost access to StoreVoiceAI. Please re-activate the plugin or contact support.', 'storevoiceai-for-woocommerce');
        }
        if ($status_code === 404) {
            return __('The requested data could not be found on the server.', 'storevoiceai-for-woocommerce');
        }
        if ($status_code >= 500) {
            return __('StoreVoiceAI is having trouble responding right now. Please try again in a moment.', 'storevoiceai-for-woocommerce');
        }

        /* translators: %d: HTTP status code */
        return sprintf( __('Request failed (HTTP %d). Please try again.', 'storevoiceai-for-woocommerce'), $status_code );
    }

    private function classify_error_code($status_code, $decoded)
    {
        if ($status_code === 401 || $status_code === 403) {
            return 'auth_failed';
        }
        if ($status_code === 404) {
            return 'not_found';
        }
        if ($status_code === 429) {
            return 'rate_limited';
        }
        if ($status_code >= 500) {
            return 'server_error';
        }
        if (is_array($decoded) && !empty($decoded['code']) && is_string($decoded['code'])) {
            return $decoded['code'];
        }
        return 'api_error';
    }

    private function dispatch_api_request($request_method, $url, array $args)
    {
        $method = strtoupper((string) $request_method);

        if ($method === 'GET') {
            return wp_remote_get($url, $args);
        }

        if ($method === 'DELETE' || $method === 'PUT' || $method === 'PATCH') {
            $request_args = $args;
            $request_args['method'] = $method;
            return wp_remote_request($url, $request_args);
        }

        return wp_remote_post($url, $args);
    }

    private function normalize_api_base_url($url)
    {
        $url = trim((string) $url);

        if ($url === '') {
            return '';
        }

        if (!preg_match('#^[a-z][a-z0-9+.-]*://#i', $url)) {
            $scheme = preg_match('#^(localhost|127\.0\.0\.1|\[::1\])(?::|/|$)#i', $url) ? 'http://' : 'https://';
            $url    = $scheme . ltrim($url, '/');
        }

        return rtrim($url, '/') . '/';
    }

    public function get_call_logs()
    {
        $api_response = $this->make_api_request('kcinc/wordpress/calls');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function sync_calls()
    {
        $api_response = $this->make_api_request('kcinc/wordpress/calls/sync', array(), 'POST');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function create_call()
    {
        $agent_id = get_option('_storevoiceai_agentid');

        if (!$agent_id) {
            return new \WP_Error('missing_agent_id', __('Missing agent ID', 'storevoiceai-for-woocommerce'));
        }

        $params = [
            'agentId' => $agent_id,
            'metadata' => [
                'source' => 'storefront',
            ],
        ];

        $response = $this->make_api_request(
            'kcinc/wordpress/calls/initiate',
            $params,
            'POST'
        );

        $logger = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        if (is_wp_error($response)) {
            $logger->error('call.initiate.response', [
                'agent_id' => $agent_id,
                'code'     => $response->get_error_code(),
                'message'  => $response->get_error_message(),
            ]);
        } else {
            $logger->info('call.initiate.response', [
                'agent_id' => $agent_id,
                'response' => $this->redact_log_payload($response),
            ]);
        }

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

        if (isset($response['code']) && $response['code'] === 'minutes_exhausted') {
            return new \WP_Error(
                'minutes_exhausted',
                __('Minutes exhausted', 'storevoiceai-for-woocommerce'),
                $response
            );
        }

        if (empty($response['access_token'])) {
            return new \WP_Error(
                'invalid_api_response',
                __('Invalid response from API', 'storevoiceai-for-woocommerce'),
                $response
            );
        }

        return [
            'access_token' => $response['access_token'],
            'call_id'      => $response['call_id'] ?? null,
            'quota'        => $response['quota'] ?? null,
        ];
    }

    public function export_product_list($body)
    {
        $api_response = $this->make_api_request('kcinc/wordpress/products/import', $body, 'POST');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function create_voice_assistant($assistant_name)
    {
        $site_url      = site_url();
        $shop_name     = get_bloginfo('name');
        $current_user  = wp_get_current_user();
        $random_string = bin2hex(random_bytes(32));

        update_option('_storevoiceai_serversecret', $random_string, false);

        $args = [
            'name'         => $assistant_name,
            'companyName'  => $shop_name,
            'notifyName'   => $current_user->display_name,
            'notifyEmail'  => $current_user->user_email,
            'serverSecret' => $random_string,
            'serverUrl'    => $site_url,
        ];
        $api_response = $this->make_api_request('kcinc/wordpress/agents/requests', $args, 'POST');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        if (!isset($api_response['name'])) { // The API response will return the name of the assistant
            return new \WP_Error('api_error', __('Failed to create voice assistant', 'storevoiceai-for-woocommerce'));
        }

        update_option('_storevoiceai_serversecret', $random_string, false);
        update_option('_storevoiceai_assistant_name', $assistant_name);

        return $api_response;
    }

    public function sync_license($license_key)
    {
        $api_response = $this->make_api_request(
            'kcinc/wordpress/sites/license',
            ['licenseKey' => $license_key],
            'POST'
        );

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_voice_usage()
    {
        $api_response = $this->make_api_request('kcinc/wordpress/usage/minutes');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_voice_usage_daily($days = 30)
    {
        $days = max(1, min(365, (int) $days));
        $api_response = $this->make_api_request('kcinc/wordpress/usage/minutes/daily?days=' . $days);

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_billing_connection_status()
    {
        $api_response = $this->make_api_request('tenants/billing/connection-status');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_wallet_transactions()
    {
        $api_response = $this->make_api_request('transactions/payments');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function create_stripe_top_up_session($amount, $return_url = '')
    {
        $params = array(
            'paymentType'   => 'topupCredit',
            'initiatorType' => 'subaccount',
            'amount'        => (float) $amount,
        );

        if (!empty($return_url)) {
            $params['returnUrl'] = $return_url;
        }

        $api_response = $this->make_api_request('transactions/stripe/sessions', $params, 'POST');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_call_details($call_id)
    {
        $api_response = $this->make_api_request('calls/' . $call_id);

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_call_summary($days = 30)
    {
        $days = max(1, min(365, (int) $days));
        $api_response = $this->make_api_request('kcinc/wordpress/reports/call-summary?days=' . $days);

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function get_voices()
    {
        $api_response = $this->make_api_request('kcinc/wordpress/voices');

        if (is_wp_error($api_response)) {
            return $api_response;
        }

        return $api_response;
    }

    public function update_agent(string $agent_id, array $fields)
    {
        $agent_id = $agent_id !== '' ? $agent_id : get_option('_storevoiceai_agentid');
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        if (!$agent_id) {
            return new \WP_Error('missing_agent_id', __('Missing agent ID', 'storevoiceai-for-woocommerce'));
        }

        $logger->info('agent.update.payload', [
            'agent_id' => $agent_id,
            'payload'  => $this->redact_log_payload($fields),
        ]);

        $api_response = $this->make_api_request(
            'calls/agents/' . $agent_id,
            $fields,
            'POST'
        );

        if (is_wp_error($api_response)) {
            $logger->error('agent.update.response', [
                'agent_id' => $agent_id,
                'code'     => $api_response->get_error_code(),
                'message'  => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        // $logger->info('agent.update.response', [
        //     'agent_id'  => $agent_id,
        //     'response'  => $this->redact_log_payload($api_response),
        // ]);

        return $api_response;
    }

    /**
     * Update site-level settings (shipping/returns policies, owner email).
     * The site is identified by the bearer token, so no agent ID is needed.
     * Caller decides which keys to include — this is a partial (PATCH) update.
     */
    public function update_site(array $fields)
    {
        $logger = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        $logger->info('site.update.payload', [
            'payload' => $this->redact_log_payload($fields),
        ]);

        $api_response = $this->make_api_request(
            'kcinc/wordpress/site',
            $fields,
            'PATCH'
        );

        if (is_wp_error($api_response)) {
            $logger->error('site.update.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        return $api_response;
    }

    public function get_phone_numbers()
    {
        $endpoint = 'kcinc/wordpress/phone-numbers';
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        $logger->info('phone_numbers.list.request', [
            'endpoint' => $endpoint,
        ]);

        $api_response = $this->make_api_request($endpoint, [], 'GET');

        if (is_wp_error($api_response)) {
            $logger->error('phone_numbers.list.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        $logger->info('phone_numbers.list.response', [
            'response' => $this->redact_log_payload($api_response),
        ]);

        return $api_response;
    }

    public function purchase_phone_number($area_code = null)
    {
        $endpoint = 'kcinc/wordpress/phone-numbers';
        $params   = [];
        if ($area_code !== null && $area_code !== '') {
            $params['areaCode'] = (int) $area_code;
        }
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        $logger->info('phone_numbers.purchase.request', [
            'endpoint' => $endpoint,
            'payload'  => $this->redact_log_payload($params),
        ]);

        $api_response = $this->make_api_request($endpoint, $params, 'POST');

        if (is_wp_error($api_response)) {
            $logger->error('phone_numbers.purchase.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        $logger->info('phone_numbers.purchase.response', [
            'response' => $this->redact_log_payload($api_response),
        ]);

        return $api_response;
    }

    public function delete_phone_number($phone_number)
    {
        $endpoint = 'kcinc/wordpress/phone-numbers/' . rawurlencode($phone_number);
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        $logger->info('phone_numbers.delete.request', [
            'endpoint' => $endpoint,
        ]);

        $api_response = $this->make_api_request($endpoint, [], 'DELETE');

        if (is_wp_error($api_response)) {
            $logger->error('phone_numbers.delete.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        $logger->info('phone_numbers.delete.response', [
            'response' => $this->redact_log_payload($api_response),
        ]);

        return $api_response;
    }

    /**
     * Fetch the calendar availability profiles for this site. The upstream
     * endpoint guarantees at least one row — if none exist, it lazily creates
     * a "Default" profile and returns it. The default profile is sorted to
     * the top and marked with `isDefault: true`.
     */
    public function get_availability_profiles()
    {
        $endpoint = 'calendar/availability-profiles';
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        $logger->info('availability_profiles.list.request', [
            'endpoint' => $endpoint,
        ]);

        $api_response = $this->make_api_request($endpoint, [], 'GET');

        if (is_wp_error($api_response)) {
            $logger->error('availability_profiles.list.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        return $api_response;
    }

    /**
     * Replace a profile in full. Caller is expected to send the canonical
     * { name, workingHours, isDefault } body.
     */
    public function update_availability_profile(string $profile_id, array $body)
    {
        $endpoint = 'calendar/availability-profiles/' . rawurlencode($profile_id);
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');

        $logger->info('availability_profiles.update.request', [
            'endpoint' => $endpoint,
            'payload'  => $body,
        ]);

        $api_response = $this->make_api_request($endpoint, $body, 'PUT');

        if (is_wp_error($api_response)) {
            $logger->error('availability_profiles.update.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        return $api_response;
    }

    public function create_agent(string $name = 'Grace'): array|\WP_Error
    {
        $params = [
            'name'        => $name,
            'companyName' => get_bloginfo('name'),
        ];

        $response = $this->make_api_request('kcinc/wordpress/agents/requests', $params, 'POST');

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

        // Expect agent_id in the response (Retell provider object)
        if (empty($response['agent_id'])) {
            return new \WP_Error(
                'api_error',
                __('Agent creation failed: no agent_id in response.', 'storevoiceai-for-woocommerce')
            );
        }

        return $response;
    }

    public function create_knowledge_base_pages($pages_data)
    {
        $logger = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');
        $payload = [
            'data' => [
                'pages' => $pages_data,
            ],
        ];

        $logger->info('knowledge_base.update.request', [
            'endpoint' => 'kcinc/wordpress/knowledge-base/pages',
            'payload'  => $this->redact_log_payload($payload),
        ]);

        $api_response = $this->make_api_request('kcinc/wordpress/knowledge-base/pages', $payload, 'POST');

        if (is_wp_error($api_response)) {
            $logger->error('knowledge_base.update.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
            ]);

            return $api_response;
        }

        $logger->info('knowledge_base.update.response', [
            'response' => $this->redact_log_payload($api_response),
        ]);

        return $api_response;
    }

    /**
     * Notify the backend that a product was created, updated, or deleted.
     * The body is a small event ({action, productId}); the backend pulls
     * fresh product data via the WC REST API key it received at site
     * registration.
     */
    public function sync_product_catalog(array $payload)
    {
        $logger   = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');
        $endpoint = 'kcinc/wordpress/knowledge-base/product-catalog';

        $logger->info('product_catalog.sync.request', [
            'endpoint' => $endpoint,
            'payload'  => $this->redact_log_payload($payload),
        ]);

        $api_response = $this->make_api_request($endpoint, $payload, 'POST');

        if (is_wp_error($api_response)) {
            $logger->error('product_catalog.sync.response', [
                'code'    => $api_response->get_error_code(),
                'message' => $api_response->get_error_message(),
                'payload' => $this->redact_log_payload($payload),
            ]);

            return $api_response;
        }

        $logger->info('product_catalog.sync.response', [
            'response' => $this->redact_log_payload($api_response),
        ]);

        return $api_response;
    }

    public function register_site($site_title, $site_url, $consumer_key, $consumer_secret, $description = null, $owner_email = null, $agent_name = null)
    {
        $endpoint = 'kcinc/wordpress/sites';
        $site_url = $this->ensure_url_protocol($site_url);
        $args     = [
            'url'                    => $site_url,
            'siteName'               => $site_title,
            'externalConsumerKey'    => $consumer_key,
            'externalConsumerSecret' => $consumer_secret,
            'description'            => $description,
        ];

        if (!empty($owner_email)) {
            $args['ownerEmail'] = $owner_email;
        }
        if (!empty($agent_name)) {
            $args['agentName'] = $agent_name;
        }

        $logger = \Kanzu\StoreVoiceAI\Kanzu_StoreVoiceAI()->container->get('logger');
        $logger->info('site.registration.payload', $this->redact_registration_payload($args));

        // Site registration is unauthenticated — backend identifies the site by URL
        // and returns a siteKey. Bypass the standard make_api_request flow because it
        // attaches a bearer token we don't have yet.
        $url      = $this->api_base_url . $endpoint;
        $response = wp_remote_post($url, [
            'headers' => [
                'Content-Type' => 'application/json',
                'Accept'       => 'application/json',
            ],
            'body'    => json_encode($args),
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            $logger->error("site.registration.failure.Error: {$response->get_error_message()}");
            return $response;
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        $logger->info('site.registration.response', $this->redact_log_payload($body));

        if (empty($body['siteKey'])) {
            $logger->error('site.registration.failure', is_array($body) ? $body : []);
            return new \WP_Error('api_error', __('Site registration failed: no siteKey in response.', 'storevoiceai-for-woocommerce'));
        }

        $logger->info("site.registration.success|Site URL:{$site_url}");

        return $body;
    }

    private function ensure_url_protocol($url)
    {
        $url = trim((string) $url);

        if ($url === '' || preg_match('#^[a-z][a-z0-9+.-]*://#i', $url)) {
            return $url;
        }

        return 'https://' . ltrim($url, '/');
    }

    private function redact_registration_payload(array $payload)
    {
        foreach (['licenseKey', 'consumerKey', 'consumerSecret', 'externalConsumerKey', 'externalConsumerSecret', 'ownerEmail'] as $sensitive_key) {
            if (isset($payload[$sensitive_key])) {
                $payload[$sensitive_key] = '[redacted]';
            }
        }

        return $payload;
    }

    private function redact_log_payload($payload)
    {
        if (!is_array($payload)) {
            return $payload;
        }

        $sensitive_keys = [
            'accessToken',
            'access_token',
            'apiKey',
            'api_key',
            'consumerKey',
            'consumerSecret',
            'email',
            'emailAddress',
            'email_address',
            'externalConsumerKey',
            'externalConsumerSecret',
            'licenseKey',
            'notifyEmail',
            'notify_email',
            'ownerEmail',
            'owner_email',
            'secret',
            'secretKey',
            'userEmail',
            'user_email',
            'token',
        ];

        foreach ($payload as $key => $value) {
            if (in_array($key, $sensitive_keys, true)) {
                $payload[$key] = '[redacted]';
                continue;
            }

            if (is_array($value)) {
                $payload[$key] = $this->redact_log_payload($value);
            }
        }

        return $payload;
    }

    /**
     * Get the access token from the API.
     *
     * @param string $site_key The site key returned at registration.
     * @param string $email The system email.
     * @return string|WP_Error The access token or WP_Error if something fails.
     */
    function get_access_token($site_key, $email)
    {
        $login_url = $this->api_base_url . 'kcinc/wordpress/auth/login';
        // Prepare the login request arguments
        $login_args = array(
            'method'  => 'POST',
            'body'    => json_encode(array(
                'siteKey' => $site_key,
                'email'   => $email,
            )),
            'headers' => array(
                'Content-Type' => 'application/json',
            ),
        );

        // Make the login API request
        $login_response = wp_remote_request($login_url, $login_args);
        // Check if the request was successful
        if (is_wp_error($login_response)) {
            return new \WP_Error(
                'api_unreachable',
                __('Could not reach the StoreVoiceAI service. Please check your connection and try again.', 'storevoiceai-for-woocommerce'),
                array( 'detail' => $login_response->get_error_message() )
            );
        }

        $login_status_code = (int) wp_remote_retrieve_response_code($login_response);
        $login_body        = wp_remote_retrieve_body($login_response);
        $data              = $login_body === '' ? null : json_decode($login_body, true);

        if ($login_status_code !== 200 && $login_status_code !== 201) {
            // 401 here means the backend has no site matching this email/siteKey
            // pair — the registration record is broken or got cleared on the
            // server. Make the message actionable rather than generic.
            if ($login_status_code === 401 || $login_status_code === 404) {
                return new \WP_Error(
                    'site_not_registered',
                    __('This site is not connected to StoreVoiceAI. Please re-activate the plugin to complete setup.', 'storevoiceai-for-woocommerce'),
                    array( 'status' => $login_status_code, 'response' => $data )
                );
            }

            $message = $this->extract_error_message($data, $login_status_code);
            return new \WP_Error(
                $this->classify_error_code($login_status_code, $data),
                $message,
                array( 'status' => $login_status_code, 'response' => $data )
            );
        }

        if (is_array($data) && isset($data['accessToken'])) {
            update_option('_storevoiceai_access_token', $data['accessToken'], false);
            return $data['accessToken'];
        }

        return new \WP_Error('api_error', __('Access token not found in the response', 'storevoiceai-for-woocommerce'));
    }

    public function get_api_key()
    {
        return get_option('_storevoiceai_access_token');
    }
}
