<?php
// File: backend/auth/otp/request.php
// Unified OTP request endpoint with geographical routing (Syria, Egypt, Jordan)

require_once __DIR__ . '/../../core/bootstrap.php';
require_once __DIR__ . '/../../functions.php';
require_once __DIR__ . '/providers.php';

// 1. Rate Limiting check (max 3 requests per 5 minutes per IP)
$limiter = new RateLimiter($redis);
$limiter->enforce(RateLimiter::identifier(), 'otp');

// 2. Fetch input parameters
$receiver    = filterRequest("receiver");
if (empty($receiver)) {
    $receiver = filterRequest("phone_number");
}

$user_type = filterRequest("user_type");

$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? (function_exists('apache_request_headers') ? (apache_request_headers()['Authorization'] ?? null) : null);
if (!empty($authHeader) && preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
    $jwtToken = $matches[1];
    $tokenParts = explode('.', $jwtToken);
    if (count($tokenParts) === 3) {
        $payload = json_decode(base64_decode($tokenParts[1]), true);
        if (isset($payload['role'])) {
            $user_type = $payload['role'];
        }
    }
}

$country     = filterRequest("country");    // Egypt | Syria | Jordan
$method      = filterRequest("method");     // whatsapp | sms | voice | flash_call | bearer_send
$context     = filterRequest("context");    // token_change | login (default)

// For driver registration context
$driverId    = filterRequest("driverId");
$email       = filterRequest("email");

if (empty($receiver)) {
    jsonError("Phone number (receiver) is required.");
    exit;
}

// Auto-detect country if empty
if (empty($country)) {
    $cleanReceiver = preg_replace('/\D+/', '', $receiver);
    if (strpos($cleanReceiver, '20') === 0 || (strlen($cleanReceiver) === 11 && strpos($cleanReceiver, '01') === 0)) {
        $country = 'Egypt';
    } elseif (strpos($cleanReceiver, '962') === 0 || (strlen($cleanReceiver) === 9 && strpos($cleanReceiver, '7') === 0)) {
        $country = 'Jordan';
    } elseif (strpos($cleanReceiver, '963') === 0 || (strlen($cleanReceiver) === 9 && strpos($cleanReceiver, '9') === 0)) {
        $country = 'Syria';
    } else {
        $country = 'Jordan'; // Default fallback
    }
}

// Auto-detect user_type if empty
if (empty($user_type)) {
    if (!empty($driverId) || strpos($_SERVER['REQUEST_URI'], 'driver') !== false) {
        $user_type = 'driver';
    } else {
        $user_type = 'passenger';
    }
}
if (empty($user_type) || !in_array($user_type, ['passenger', 'driver', 'admin', 'service'])) {
    jsonError("User type must be 'passenger', 'driver', 'admin', or 'service'.");
    exit;
}

if ($user_type === 'admin') {
    $allowedPhones = explode(',', getenv('ADMIN_PHONE_NUMBERS'));
    if (!in_array($receiver, $allowedPhones)) {
        error_log("⚠️ [Admin OTP] Unauthorized phone number attempted: $receiver");
        jsonError("رقم الهاتف غير مصرح له.");
        exit;
    }
}

// 3. Establish DB Connection
try {
    $con = Database::get('main');
} catch (Exception $e) {
    http_response_code(500);
    exit(json_encode(['error' => 'Database connection failed']));
}

// 4. Generate 3-digit OTP code
$otp = str_pad((string)random_int(0, 999), 3, '0', STR_PAD_LEFT);

// 5. Geographical Routing & Dispatch
$sentSuccessfully = false;

switch (strtolower($country)) {
    case 'egypt':
        $sentSuccessfully = sendKazumiSms($receiver, $otp);
        if (!$sentSuccessfully) {
            error_log("⚠️ [Egypt OTP Failover 1] Kazumi SMS failed. Falling back to Intaleq OTP WhatsApp.");
            $sentSuccessfully = sendIntaleqOtp($receiver, $otp, 'whatsapp');
            if (!$sentSuccessfully) {
                error_log("⚠️ [Egypt OTP Failover 2] Intaleq OTP WhatsApp failed. Falling back to Nabeh JWT OTP text.");
                $sentSuccessfully = sendNabehOtp($receiver, $otp, 'text');
            }
        }
        break;
        
    case 'syria':
        // Syria uses dynamic Nabeh JWT for voice/image, static Intaleq app_key for whatsapp/sms
        if ($method === 'bearer_send' || $method === 'voice' || $method === 'image') {
            $sentSuccessfully = sendNabehOtp($receiver, $otp, $method);
            if (!$sentSuccessfully) {
                error_log("⚠️ [Syria OTP Failover] Nabeh JWT method failed. Falling back to Intaleq OTP WhatsApp.");
                $sentSuccessfully = sendIntaleqOtp($receiver, $otp, 'whatsapp');
            }
        } else {
            $sentSuccessfully = sendIntaleqOtp($receiver, $otp, $method ?: 'whatsapp');
            if (!$sentSuccessfully) {
                error_log("⚠️ [Syria OTP Failover] Intaleq OTP WhatsApp failed. Falling back to Nabeh JWT OTP text.");
                $sentSuccessfully = sendNabehOtp($receiver, $otp, 'text');
            }
        }
        break;
        
    case 'jordan':
        // Jordan uses dynamic Nabeh JWT for voice/image, static Intaleq app_key for sms/whatsapp
        if ($method === 'bearer_send' || $method === 'voice' || $method === 'image') {
            $sentSuccessfully = sendNabehOtp($receiver, $otp, $method);
            if (!$sentSuccessfully) {
                error_log("⚠️ [Jordan OTP Failover] Nabeh JWT method failed. Falling back to Intaleq OTP SMS.");
                $sentSuccessfully = sendIntaleqOtp($receiver, $otp, 'sms');
            }
        } else {
            $sentSuccessfully = sendIntaleqOtp($receiver, $otp, $method ?: 'sms');
            if (!$sentSuccessfully) {
                error_log("⚠️ [Jordan OTP Failover] Intaleq OTP SMS failed. Falling back to Nabeh JWT OTP text.");
                $sentSuccessfully = sendNabehOtp($receiver, $otp, 'text');
            }
        }
        break;
        
    default:
        // Default fallback to Kazumi SMS
        $sentSuccessfully = sendKazumiSms($receiver, $otp);
        if (!$sentSuccessfully) {
            error_log("⚠️ [Default OTP Failover] Kazumi SMS failed. Falling back to Intaleq OTP WhatsApp.");
            $sentSuccessfully = sendIntaleqOtp($receiver, $otp, 'whatsapp');
        }
        break;
}

// 6. DB Storage on Success
if ($sentSuccessfully) {
    $encryptedPhone = $encryptionHelper->encryptData($receiver);
    $encryptedOtp   = $encryptionHelper->encryptData($otp);
    $encryptedEmail = !empty($email) ? $encryptionHelper->encryptData($email) : '';
    
    $expirationTime = date('Y-m-d H:i:s', strtotime('+5 minutes'));
    
    try {
        if ($user_type === 'admin') {
            $stmt = $con->prepare("INSERT INTO token_verification_admin (phone_number, token, expiration_time)
                                   VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 5 MINUTE))
                                   ON DUPLICATE KEY UPDATE token = VALUES(token), expiration_time = VALUES(expiration_time)");
            $stmt->execute([$encryptedPhone, $encryptedOtp]);
        } elseif ($user_type === 'service') {
            $stmtDel = $con->prepare("DELETE FROM `phone_verification_service` WHERE `phone_number` = ?");
            $stmtDel->execute([$encryptedPhone]);
            
            $stmtIns = $con->prepare("
                INSERT INTO `phone_verification_service` 
                  (`phone_number`, `token_code`, `expiration_time`, `is_verified`, `created_at`) 
                VALUES (?, ?, ?, 0, NOW())
            ");
            $stmtIns->execute([
                $encryptedPhone,
                $encryptedOtp,
                $expirationTime
            ]);
        } elseif ($user_type === 'driver') {
            if ($context === 'token_change') {
                // Delete old verification attempts
                $stmtDel = $con->prepare("DELETE FROM `token_verification_driver` WHERE `phone_number` = ?");
                $stmtDel->execute([$encryptedPhone]);
                
                // Insert new attempt
                $stmtIns = $con->prepare("
                    INSERT INTO `token_verification_driver` 
                      (`phone_number`, `token`, `expiration_time`, `verified`, `created_at`) 
                    VALUES (?, ?, ?, 0, NOW())
                ");
                $stmtIns->execute([
                    $encryptedPhone,
                    $encryptedOtp,
                    $expirationTime
                ]);
            } else {
                // Delete old verification attempts
                $stmtDel = $con->prepare("DELETE FROM `phone_verification` WHERE `phone_number` = ?");
                $stmtDel->execute([$encryptedPhone]);
                
                // Insert new attempt
                $stmtIns = $con->prepare("
                    INSERT INTO `phone_verification` 
                      (`phone_number`, `driverId`, `email`, `token_code`, `expiration_time`, `is_verified`, `created_at`) 
                    VALUES (?, ?, ?, ?, ?, 0, NOW())
                ");
                $stmtIns->execute([
                    $encryptedPhone,
                    $driverId ?: '',
                    $encryptedEmail,
                    $encryptedOtp,
                    $expirationTime
                ]);
            }
        } else {
            if ($context === 'token_change') {
                // Delete old verification attempts
                $stmtDel = $con->prepare("DELETE FROM `token_verification` WHERE `phone_number` = ?");
                $stmtDel->execute([$encryptedPhone]);
                
                // Insert new attempt
                $stmtIns = $con->prepare("
                    INSERT INTO `token_verification` 
                      (`phone_number`, `token`, `expiration_time`, `verified`, `created_at`) 
                    VALUES (?, ?, ?, 0, NOW())
                ");
                $stmtIns->execute([
                    $encryptedPhone,
                    $encryptedOtp,
                    $expirationTime
                ]);
            } else {
                // Delete old verification attempts
                $stmtDel = $con->prepare("DELETE FROM `phone_verification_passenger` WHERE `phone_number` = ?");
                $stmtDel->execute([$encryptedPhone]);
                
                // Insert new attempt
                $stmtIns = $con->prepare("
                    INSERT INTO `phone_verification_passenger` 
                      (`phone_number`, `token`, `expiration_time`, `verified`, `created_at`) 
                    VALUES (?, ?, ?, 0, NOW())
                ");
                $stmtIns->execute([
                    $encryptedPhone,
                    $encryptedOtp,
                    $expirationTime
                ]);
            }
        }
        
        jsonSuccess(null, "OTP sent and saved successfully");
    } catch (PDOException $e) {
        error_log("⚠️ [OTP DB Save] Error: " . $e->getMessage());
        jsonError("OTP sent but failed to save verification data");
    }
} else {
    jsonError("Failed to send verification code. Please try again.");
}
