<?php
// File: backend/auth/otp/verify.php
// Unified OTP verification endpoint

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

// 0. Rate Limiting: 3 محاولات OTP كل 5 دقائق لكل IP
$rateLimiter = new RateLimiter($redis);
$rateLimiter->enforce(RateLimiter::identifier(), 'otp');

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

$token_code   = filterRequest("token_code");
if (empty($token_code)) {
    $token_code = filterRequest("token");
}

$user_type    = filterRequest("user_type");
$context      = filterRequest("context");   // token_change | login (default)

$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'];
        }
    }
}

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

if (empty($token_code)) {
    jsonError("Verification token code is required.");
    exit;
}

if (empty($user_type)) {
    if (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;
}

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

// 3. Encrypt data to query
$encryptedPhone = $encryptionHelper->encryptData($phone_number);
$encryptedToken = $encryptionHelper->encryptData($token_code);

// 4. Verify based on user type
try {
    if ($user_type === 'admin') {
        $sql = "SELECT * FROM token_verification_admin 
                WHERE phone_number = :phone AND token = :token 
                AND expiration_time >= NOW()";
        $stmt = $con->prepare($sql);
        $stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
        $stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
        $stmt->execute();
        
        if ($stmt->rowCount() > 0) {
            $deviceNumber = filterRequest("device_number") ?? '';
            // adminUser stores unencrypted phone
            $checkAdmin = $con->prepare("SELECT * FROM adminUser WHERE name = ?");
            $checkAdmin->execute([$phone_number]);
            $now = date("Y-m-d H:i:s");
            
            if ($checkAdmin->rowCount() > 0) {
                $update = $con->prepare("UPDATE adminUser SET device_number = ?, updated_at = ? WHERE name = ?");
                $update->execute([$deviceNumber, $now, $phone_number]);
                jsonSuccess(["message" => "verified and updated existing admin"]);
            } else {
                $insert = $con->prepare("INSERT INTO adminUser (device_number, name, created_at, updated_at) VALUES (?, ?, ?, ?)");
                $insert->execute([$deviceNumber, $phone_number, $now, $now]);
                jsonSuccess(["message" => "verified and new admin created"]);
            }
        } else {
            jsonError("Your phone number could not be verified or the code is expired. Please try again.");
        }
    } elseif ($user_type === 'service') {
        $sql = "SELECT `id` FROM `phone_verification_service` 
                WHERE `phone_number` = :phone AND `token_code` = :token 
                AND `expiration_time` > NOW()";
        $stmt = $con->prepare($sql);
        $stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
        $stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
        $stmt->execute();
        $result = $stmt->fetch();
        
        if ($result) {
            $sqlUpdate = "UPDATE `phone_verification_service` SET `is_verified` = 1 WHERE `phone_number` = :phone";
            $stmtUpd = $con->prepare($sqlUpdate);
            $stmtUpd->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
            $stmtUpd->execute();
            jsonSuccess(null, "Your phone number has been verified.");
        } else {
            jsonError("Your phone number could not be verified or the code is expired. Please try again.");
        }
    } elseif ($user_type === 'driver') {
        if ($context === 'token_change') {
            $sql = "SELECT `id` FROM `token_verification_driver` 
                    WHERE `phone_number` = :phone 
                      AND `token` = :token 
                      AND `expiration_time` > NOW()";
                      
            $stmt = $con->prepare($sql);
            $stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
            $stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
            $stmt->execute();
            $result = $stmt->fetch();
            
            if ($result) {
                // Update driver verified status
                $sqlUpdate = "UPDATE `token_verification_driver` SET `verified` = 1 WHERE `phone_number` = :phone";
                $stmtUpd = $con->prepare($sqlUpdate);
                $stmtUpd->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
                $stmtUpd->execute();
                
                jsonSuccess(null, "Your phone number has been verified.");
            } else {
                jsonError("Your phone number could not be verified or the code is expired. Please try again.");
            }
        } else {
            $sql = "SELECT `id` FROM `phone_verification` 
                    WHERE `phone_number` = :phone 
                      AND `token_code` = :token 
                      AND `expiration_time` > NOW()";
                      
            $stmt = $con->prepare($sql);
            $stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
            $stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
            $stmt->execute();
            $result = $stmt->fetch();
            
            if ($result) {
                // Update driver is_verified status
                $sqlUpdate = "UPDATE `phone_verification` SET `is_verified` = 1 WHERE `phone_number` = :phone";
                $stmtUpd = $con->prepare($sqlUpdate);
                $stmtUpd->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
                $stmtUpd->execute();
                
                jsonSuccess(null, "Your phone number has been verified.");
            } else {
                jsonError("Your phone number could not be verified or the code is expired. Please try again.");
            }
        }
    } else {
        if ($context === 'token_change') {
            $sql = "SELECT `id` FROM `token_verification` 
                    WHERE `phone_number` = :phone 
                      AND `token` = :token 
                      AND `expiration_time` > NOW()";
                      
            $stmt = $con->prepare($sql);
            $stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
            $stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
            $stmt->execute();
            $result = $stmt->fetch();
            
            if ($result) {
                // Update passenger verified status
                $sqlUpdate = "UPDATE `token_verification` SET `verified` = 1 WHERE `phone_number` = :phone";
                $stmtUpd = $con->prepare($sqlUpdate);
                $stmtUpd->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
                $stmtUpd->execute();
                
                jsonSuccess(null, "Your phone number has been verified.");
            } else {
                jsonError("Your phone number could not be verified or the code is expired. Please try again.");
            }
        } else {
            $sql = "SELECT `id` FROM `phone_verification_passenger` 
                    WHERE `phone_number` = :phone 
                      AND `token` = :token 
                      AND `expiration_time` > NOW()";
                      
            $stmt = $con->prepare($sql);
            $stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
            $stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
            $stmt->execute();
            $result = $stmt->fetch();
            
            if ($result) {
                // Update passenger verified status
                $sqlUpdate = "UPDATE `phone_verification_passenger` SET `verified` = 1 WHERE `phone_number` = :phone";
                $stmtUpd = $con->prepare($sqlUpdate);
                $stmtUpd->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
                $stmtUpd->execute();
                
                jsonSuccess(null, "Your phone number has been verified.");
            } else {
                jsonError("Your phone number could not be verified or the code is expired. Please try again.");
            }
        }
    }
} catch (PDOException $e) {
    error_log("⚠️ [OTP DB Verify] Error: " . $e->getMessage());
    jsonError("An error occurred during verification. Please try again.");
}
