<?php
/**
 * Order Status Check API Endpoint
 * 
 * This endpoint allows users to check the status of their orders using a GET request.
 * It integrates with the existing create_order.php API and supports both single and bulk status checks.
 * 
 * Note: The order_id parameter should be the external_transaction_id returned when creating an order.
 * 
 * Usage: 
 * - Single: GET /api/check_order_status.php?order_id=EXTERNAL_TX_ID&api_key=your_api_key
 * - Bulk: GET /api/check_order_status.php?order_ids=EXTERNAL_TX_ID1,EXTERNAL_TX_ID2&api_key=your_api_key
 * - Multiple: GET /api/check_order_status.php?order_id=EXTERNAL_TX_ID1&order_id=EXTERNAL_TX_ID2&api_key=your_api_key
 * 
 * Response: JSON with order status and details
 */

require_once '../config.php';
require_once '../config_api.php';
require_once __DIR__ . '/../app/classes/ApiKeyManager.php';

date_default_timezone_set('GMT');
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: Content-Type');

// Initialize API key manager
$apiKeyManager = new ApiKeyManager($conn);

// ------------------ Helpers ------------------
function respond($data, $code = 200) {
    http_response_code($code);
    echo json_encode($data);
    exit;
}

function validateExternalTransactionId($externalTxId) {
    // external_transaction_id is a string, so we just check it's not empty
    return !empty(trim($externalTxId));
}

function getOrderStatus($conn, $externalTransactionId, $userId) {
    $query = "
        SELECT 
            ao.id,
            ao.agent_id,
            ao.package_size,
            ao.amount,
            ao.beneficiary_number,
            ao.network_type,
            ao.status,
            ao.external_transaction_id,
            ao.external_reference,
            ao.api_response_data,
            ao.order_source,
            ao.created_at,
            ao.status_updated_at,
            a.username,
            a.email,
            a.role
        FROM agent_orders ao
        JOIN agents a ON ao.agent_id = a.id
        WHERE ao.external_transaction_id = ? AND ao.agent_id = ?
        LIMIT 1
    ";
    
    if ($stmt = $conn->prepare($query)) {
        $stmt->bind_param("si", $externalTransactionId, $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        $order = $result->fetch_assoc();
        $stmt->close();
        
        if ($order) {
            return $order;
        }
    }
    
    return null;
}


function formatOrderResponse($order) {
    $response = [
        'order_id' => (int)$order['id'],
        'external_transaction_id' => $order['external_transaction_id'],
        'external_reference' => $order['external_reference'],
        'status' => $order['status'],
        'package_size' => $order['package_size'],
        'amount' => floatval($order['amount']),
        'beneficiary_number' => $order['beneficiary_number'],
        'network_type' => $order['network_type'],
        'order_source' => $order['order_source'],
        'username' => $order['username'],
        'email' => $order['email'],
        'role' => $order['role'],
        'created_at' => $order['created_at'],
        'status_updated_at' => $order['status_updated_at'],
        'timestamp' => date('c')
    ];
    
    // Add status-specific information
    switch ($order['status']) {
        case 'delivered':
            $response['status_description'] = 'Order has been successfully delivered';
            $response['is_completed'] = true;
            $response['is_successful'] = true;
            break;
        case 'pending':
            $response['status_description'] = 'Order is being processed';
            $response['is_completed'] = false;
            $response['is_successful'] = null; // Unknown
            break;
        case 'failed':
        case 'api_failed':
            $response['status_description'] = 'Order failed to process';
            $response['is_completed'] = true;
            $response['is_successful'] = false;
            break;
        default:
            $response['status_description'] = 'Order status: ' . $order['status'];
            $response['is_completed'] = false;
            $response['is_successful'] = null;
    }
    
    // Add API response data if available
    if ($order['api_response_data']) {
        $apiData = json_decode($order['api_response_data'], true);
        if ($apiData) {
            $response['api_response'] = $apiData;
        }
    }
    
    
    return $response;
}

// ------------------ Main Logic ------------------

// Only allow GET requests
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
    respond([
        'success' => false,
        'message' => 'Method Not Allowed. Only GET requests are accepted.',
        'error_code' => 'METHOD_NOT_ALLOWED'
    ], 405);
}

// Get API key from headers or query parameters
$apiKey = null;
$headers = getallheaders();

// Check Authorization header (Bearer token format)
if (isset($headers['Authorization'])) {
    $authHeader = $headers['Authorization'];
    if (preg_match('/Bearer\s+(.+)/', $authHeader, $matches)) {
        $apiKey = $matches[1];
    }
}

// Check X-API-Key header
if (!$apiKey && isset($headers['X-API-Key'])) {
    $apiKey = $headers['X-API-Key'];
}

// Check query parameters
if (!$apiKey) {
    $apiKey = $_GET['api_key'] ?? $_GET['apikey'] ?? null;
}

if (!$apiKey) {
    respond([
        'success' => false,
        'message' => 'API key required. Provide via Authorization header, X-API-Key header, or api_key parameter.',
        'error_code' => 'API_KEY_REQUIRED'
    ], 401);
}

// Validate API key
$startTime = microtime(true);
$validation = $apiKeyManager->validateApiKey($apiKey);
$responseTime = round((microtime(true) - $startTime) * 1000);

if (!$validation['valid']) {
    respond([
        'success' => false,
        'message' => $validation['message'],
        'error_code' => 'INVALID_API_KEY'
    ], 401);
}

$userId = $validation['user_id'];
$username = $validation['username'];

// Check rate limit
$rateLimitCheck = $apiKeyManager->checkRateLimit($validation['key_data']['id'], 'check_order_status');
if (!$rateLimitCheck['allowed']) {
    respond([
        'success' => false,
        'message' => $rateLimitCheck['message'],
        'rate_limit' => $rateLimitCheck,
        'error_code' => 'RATE_LIMIT_EXCEEDED'
    ], 429);
}

// Parse external transaction IDs from different input formats
// Note: order_id parameter should contain the external_transaction_id returned when creating an order
$externalTransactionIds = [];

// Single external transaction ID
if (isset($_GET['order_id']) && !is_array($_GET['order_id'])) {
    $externalTxId = trim($_GET['order_id']);
    if (validateExternalTransactionId($externalTxId)) {
        $externalTransactionIds[] = $externalTxId;
    }
}

// Multiple external transaction IDs (comma-separated)
if (isset($_GET['order_ids'])) {
    $externalTxIdsStr = trim($_GET['order_ids']);
    $ids = explode(',', $externalTxIdsStr);
    foreach ($ids as $id) {
        $id = trim($id);
        if (validateExternalTransactionId($id)) {
            $externalTransactionIds[] = $id;
        }
    }
}

// Multiple order_id parameters (array)
if (isset($_GET['order_id']) && is_array($_GET['order_id'])) {
    foreach ($_GET['order_id'] as $id) {
        $id = trim($id);
        if (validateExternalTransactionId($id)) {
            $externalTransactionIds[] = $id;
        }
    }
}

// Remove duplicates
$externalTransactionIds = array_unique($externalTransactionIds);

if (empty($externalTransactionIds)) {
    respond([
        'success' => false,
        'message' => 'No valid external transaction IDs provided. Use order_id or order_ids parameter with the external_transaction_id returned when creating an order.',
        'error_code' => 'NO_ORDER_IDS',
        'required_parameters' => ['order_id (external_transaction_id)', 'api_key']
    ], 400);
}


// Process each order by external transaction ID
$orders = [];
$notFound = [];
$errors = [];

foreach ($externalTransactionIds as $externalTxId) {
    try {
        $order = getOrderStatus($conn, $externalTxId, $userId);
        
        if ($order) {
            $orders[] = formatOrderResponse($order);
        } else {
            $notFound[] = $externalTxId;
        }
    } catch (Exception $e) {
        $errors[] = [
            'external_transaction_id' => $externalTxId,
            'error' => $e->getMessage()
        ];
    }
}

// Build response
$response = [
    'success' => true,
    'processed' => count($orders),
    'not_found' => count($notFound),
    'errors' => count($errors),
    'orders' => $orders,
    'not_found_ids' => $notFound,
    'error_details' => $errors,
    'api_info' => [
        'user_id' => (int)$userId,
        'username' => $username,
        'role' => $validation['role']
    ],
    'rate_limit' => $rateLimitCheck,
    'response_time_ms' => $responseTime
];

// Add summary message
if (count($orders) === count($externalTransactionIds)) {
    $response['message'] = 'All orders found and processed successfully';
} elseif (count($orders) > 0) {
    $response['message'] = 'Some orders found, some not found or had errors';
} else {
    $response['message'] = 'No orders found or all had errors';
}

// Log successful API usage
$totalResponseTime = round((microtime(true) - $startTime) * 1000);
$apiKeyManager->logApiUsage($validation['key_data']['id'], $userId, 'check_order_status', 
    $_SERVER['REQUEST_METHOD'], $_SERVER['REMOTE_ADDR'] ?? 'unknown', 
    $_SERVER['HTTP_USER_AGENT'] ?? '', $_GET, 200, $totalResponseTime);

respond($response, 200);
?>
