<?php

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;

/**
 * Decode Unicode escape sequences in strings
 * Converts \u00e9 to é, etc.
 */
function decodeUnicodeString($string)
{
    return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($matches) {
        return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UCS-2BE');
    }, $string);
}

/**
 * Check if running in desktop mode
 */
function isDesktopMode(): bool
{
    return defined('NATIVEPHP') || class_exists('Native\Laravel\NativePHP');
}

/**
 * Get HTTP client configured with SSL options and auth
 *
 * @param  bool  $withAuth  Whether to include auth token
 */
function getHttpClient(bool $withAuth = true): \Illuminate\Http\Client\PendingRequest
{
    $httpClient = Http::retry(3, 100)->timeout(config('app.api_timeout', 30));

    // Configure SSL options if provided
    $sslOptions = [];

    if (config('app.api_ssl_verify') === false) {
        $sslOptions['verify'] = false;
    } elseif (config('app.api_ssl_cert_path')) {
        $sslOptions['cert'] = config('app.api_ssl_cert_path');
    }

    if (config('app.api_ssl_key_path')) {
        $sslOptions['ssl_key'] = config('app.api_ssl_key_path');
    }

    if (config('app.api_ssl_ca_path')) {
        $sslOptions['cafile'] = config('app.api_ssl_ca_path');
    }

    if (! empty($sslOptions)) {
        $httpClient = $httpClient->withOptions($sslOptions);
    }

    // Add auth header if requested
    if ($withAuth) {
        $token = session('auth_token') ?? Auth::user()?->api_token ?? session('pending_user_token') ?? '';
        if ($token) {
            $httpClient = $httpClient->withHeaders([
                'Authorization' => 'Bearer '.$token,
            ]);
        } else {
            throw new \Exception('No authentication token available. Cannot make authenticated API calls.');
        }
    }

    return $httpClient->withHeaders([
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
    ]);
}

/**
 * Extract a user-friendly API error message and status from an exception
 */
function extractApiExceptionMessage(\Exception $e, string $defaultMessage = 'Impossible de se connecter au serveur distant. Veuillez réessayer plus tard.'): array
{
    $status = 500;
    $message = $defaultMessage;

    try {
        if ($e instanceof \Illuminate\Http\Client\RequestException && $e->response) {
            $status = $e->response->status();
            $json = $e->response->json();
            if (is_array($json) && isset($json['message']) && is_string($json['message'])) {
                $message = decodeUnicodeString($json['message']);
            }
        } else {
            // Fallback: try to parse trailing JSON payload from the exception message
            if (preg_match('/\{.*\}$/s', $e->getMessage(), $m)) {
                $parsed = json_decode($m[0], true);
                if (json_last_error() === JSON_ERROR_NONE && isset($parsed['message']) && is_string($parsed['message'])) {
                    $message = decodeUnicodeString($parsed['message']);
                }
            }
        }
    } catch (\Throwable $t) {
        // Keep defaults on any parsing error
    }

    return ['message' => $message, 'status' => $status];
}

/**
 * Check if the API server is reachable
 */
function checkApiConnection(): array
{
    try {
        $response = getHttpClient(false)->timeout(5)->get(config('app.api_url').'/health');

        return [
            'success' => true,
            'status' => $response->status(),
            'message' => 'API server is reachable',
            'response_time' => $response->transferStats->getTransferTime(),
        ];
    } catch (\Illuminate\Http\Client\ConnectionException $e) {
        return [
            'success' => false,
            'status' => 0,
            'message' => 'API server is unreachable',
            'response_time' => null,
        ];
    } catch (\Exception $e) {
        ['message' => $friendlyMessage] = extractApiExceptionMessage($e, 'Error checking API connection');

        return [
            'success' => false,
            'status' => 0,
            'message' => $friendlyMessage,
            'response_time' => null,
        ];
    }
}
