<?php
// File: backend/auth/otp/providers.php
// Encapsulates external OTP gateway API calls for Kazumi, Intaleq, and Nabeh.

/**
 * Send SMS OTP via Kazumi SMS Gateway (Egypt)
 * 
 * @param string $receiver Recipient phone number (e.g. +2010xxxxxxxx)
 * @param string $otp 3-digit verification code
 * @return bool True if OTP was sent successfully
 */
function sendKazumiSms(string $receiver, string $otp): bool {
    $username = getenv('SMS_USERNAME');
    $password = getenv('SMS_PASSWORD_EGYPT');
    $sender   = getenv('SMS_SENDER');

    if (!$username || !$password || !$sender) {
        error_log("⚠️ [Kazumi OTP] Missing credentials in environment variables.");
        return false;
    }

    $message = "Siro app code is " . $otp;
    $apiUrl = 'https://sms.kazumi.me/api/sms/send-sms';
    
    $payload = [
        'username' => $username,
        'password' => $password,
        'language' => 'e',
        'sender'   => $sender,
        'receiver' => $receiver,
        'message'  => $message
    ];

    $response = curlCall("POST", $apiUrl, json_encode($payload), [
        "Content-Type: application/json"
    ]);

    if ($response) {
        $decoded = json_decode($response, true);
        if (isset($decoded['message']) && $decoded['message'] === 'Success') {
            return true;
        }
        error_log("❌ [Kazumi OTP] API returned failure response: " . $response);
    }
    return false;
}

/**
 * Retrieve Nabeh JWT Bearer Token, caching it in Redis for 24 hours.
 * 
 * @return string|null The Bearer token, or null on failure.
 */
function getNabehBearerToken(): ?string {
    global $redis;

    // 1. Try to read cached token from Redis (TTL 24 hours)
    if ($redis) {
        try {
            $cachedToken = $redis->get('nabeh_bearer_token');
            if ($cachedToken) {
                return $cachedToken;
            }
        } catch (Exception $e) {
            error_log("⚠️ [Nabeh Auth Redis] Error reading token: " . $e->getMessage());
        }
    }

    // 2. Token not cached, authenticate via Nabeh Login API
    $email = getenv('NABEH_EMAIL');
    $password = getenv('NABEH_PASSWORD');

    if (!$email || !$password) {
        error_log("⚠️ [Nabeh Auth] Missing NABEH_EMAIL or NABEH_PASSWORD environment variables.");
        return null;
    }

    $apiUrl = 'https://nabeh.intaleqapp.com/api/auth/login';
    $payload = [
        'email' => $email,
        'password' => $password
    ];

    $response = curlCall("POST", $apiUrl, json_encode($payload), [
        'Content-Type: application/json'
    ]);

    if ($response) {
        $decoded = json_decode($response, true);
        $token = $decoded['token'] ?? $decoded['message']['token'] ?? $decoded['jwt'] ?? $decoded['access_token'] ?? null;
        
        if ($token) {
            // Cache token in Redis for 24 hours (86400 seconds)
            if ($redis) {
                try {
                    $redis->setex('nabeh_bearer_token', 86400, $token);
                } catch (Exception $e) {
                    error_log("⚠️ [Nabeh Auth Redis Cache Save] Error saving token: " . $e->getMessage());
                }
            }
            return $token;
        }
        error_log("❌ [Nabeh Auth] Failed to extract token from login response: " . $response);
    }
    return null;
}

/**
 * Send OTP via Nabeh JWT Auth Gateway (WhatsApp, Voice, etc.)
 * 
 * @param string $receiver Recipient phone number
 * @param string $otp 3-digit verification code
 * @param string $method text | voice | image | whatsapp
 * @return bool True if OTP was sent successfully
 */
function sendNabehOtp(string $receiver, string $otp, string $method = 'text'): bool {
    $bearerToken = getNabehBearerToken();
    if (!$bearerToken) {
        error_log("⚠️ [Nabeh OTP] Failed to obtain dynamic JWT Bearer token.");
        return false;
    }

    // Strip symbols for Nabeh endpoint
    $phoneRaw = preg_replace('/\D+/', '', $receiver);

    // Map method/type
    $type = 'text';
    if ($method === 'voice') {
        $type = 'voice';
    } elseif ($method === 'image') {
        $type = 'image';
    } 
    // elseif ($method === 'flash_call') {
    //     $type = 'flash_call';
    // }

    $apiUrl = 'https://nabeh.intaleqapp.com/api/otp/send';
    $payload = [
        'phone' => $phoneRaw,
        'type' => $type,
        'code' => $otp
    ];

    $response = curlCall("POST", $apiUrl, json_encode($payload), [
        'Content-Type: application/json',
        "Authorization: Bearer $bearerToken"
    ]);

    if ($response) {
        $decoded = json_decode($response, true);
        if ($decoded && ($decoded['success'] ?? false)) {
            return true;
        }
        error_log("❌ [Nabeh OTP] API returned failure response: " . $response);
    }
    return false;
}

/**
 * Send OTP via Intaleq Static OTP Gateway (using body app_key parameter)
 * 
 * @param string $receiver Recipient phone number
 * @param string $otp 3-digit verification code
 * @param string $method whatsapp | sms | voice | flash_call
 * @return bool True if OTP was sent successfully
 */
function sendIntaleqOtp(string $receiver, string $otp, string $method = 'whatsapp'): bool {
    $appKey = getenv('NABEH_OTP_APP_KEY');
    
    if (!$appKey) {
        error_log("⚠️ [Intaleq OTP] Missing NABEH_OTP_APP_KEY in environment.");
        return false;
    }

    // Normalize receiver to start with +
    $phoneWithPlus = (strpos($receiver, '+') === 0) ? $receiver : '+' . $receiver;

    $apiUrl = 'https://otp.intaleqapp.com/api/request-otp.php';
    $payload = [
        'phone' => $phoneWithPlus,
        'app_key' => $appKey,
        'device_type' => 'android',
        'method' => $method,
        'code' => $otp
    ];

    $response = curlCall("POST", $apiUrl, json_encode($payload), [
        'Content-Type: application/json'
    ]);

    if ($response) {
        $decoded = json_decode($response, true);
        if ($decoded && ($decoded['success'] ?? false)) {
            return true;
        }
        error_log("❌ [Intaleq OTP] API returned failure response: " . $response);
    }
    return false;
}

/**
 * Generic cURL execution helper
 */
function curlCall(string $method, string $url, string $data, array $headers): ?string {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_POSTFIELDS => $data,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_CONNECTTIMEOUT => 5
    ]);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($error) {
        error_log("⚠️ [OTP cURL] Error calling $url: $error");
        return null;
    }

    if ($httpCode !== 200) {
        error_log("⚠️ [OTP cURL] Non-200 HTTP code $httpCode from $url. Response: $response");
    }

    return $response;
}
