<?php
/**
 * API للعيادات - استلام النتائج برقم الطلب أو المريض
 * نسخة مطورة مع دعم IP whitelist و rate limiting و logging
 * 
 * استدعاء: GET api/clinic_results.php?api_key=XXX&order_number=O12345
 * أو: POST api/clinic_results.php مع JSON body
 */
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

$config = require __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../src/Core/Database.php';
$db = \App\Core\Database::getInstance($config['db'])->connection();

$startTime = microtime(true);
$response = ['success' => false, 'error' => '', 'data' => null];
$httpStatus = 200;
$logData = [
    'request_method' => $_SERVER['REQUEST_METHOD'],
    'request_url' => $_SERVER['REQUEST_URI'] ?? '',
    'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
    'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? ''
];

// قراءة المعاملات من GET أو POST
$apiKey = '';
$orderNumber = '';
$patientId = 0;
$orderId = 0;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = file_get_contents('php://input');
    $logData['request_params'] = $input;
    $postData = json_decode($input, true);
    if ($postData) {
        $apiKey = trim($postData['api_key'] ?? '');
        $orderNumber = trim($postData['order_number'] ?? '');
        $patientId = !empty($postData['patient_id']) ? (int)$postData['patient_id'] : 0;
        $orderId = !empty($postData['order_id']) ? (int)$postData['order_id'] : 0;
    }
} else {
    $apiKey = trim($_GET['api_key'] ?? '');
    $orderNumber = trim($_GET['order_number'] ?? '');
    $patientId = (int)($_GET['patient_id'] ?? 0);
    $orderId = (int)($_GET['order_id'] ?? 0);
    $logData['request_params'] = http_build_query($_GET);
}

// التحقق من وجود مفتاح API
if ($apiKey === '') {
    $response['error'] = 'api_key مطلوب';
    $httpStatus = 400;
    echo json_encode($response, JSON_UNESCAPED_UNICODE);
    exit;
}

try {
    // التحقق من وجود جدول clinic_api_keys
    try {
        $db->query('SELECT id FROM clinic_api_keys LIMIT 1');
    } catch (Throwable $e) {
        $response['error'] = 'API غير متاح حالياً';
        $httpStatus = 503;
        echo json_encode($response, JSON_UNESCAPED_UNICODE);
        exit;
    }
    
    // جلب معلومات المفتاح
    $stmt = $db->prepare('SELECT * FROM clinic_api_keys WHERE api_key = ? AND is_active = 1 LIMIT 1');
    $stmt->execute([$apiKey]);
    $keyRow = $stmt->fetch();
    
    if (!$keyRow) {
        $response['error'] = 'مفتاح API غير صالح';
        $httpStatus = 401;
        echo json_encode($response, JSON_UNESCAPED_UNICODE);
        exit;
    }
    
    $apiKeyId = (int)$keyRow['id'];
    $clinicName = $keyRow['clinic_name'];
    $tenantId = (int)($keyRow['tenant_id'] ?? 1);
    $ipWhitelist = $keyRow['ip_whitelist'] ?? '';
    $rateLimit = (int)($keyRow['rate_limit_per_hour'] ?? 100);
    
    $logData['api_key_id'] = $apiKeyId;
    $logData['clinic_name'] = $clinicName;
    
    // التحقق من IP whitelist
    if (!empty($ipWhitelist)) {
        $allowedIPs = array_map('trim', explode(',', $ipWhitelist));
        $clientIP = $_SERVER['REMOTE_ADDR'] ?? '';
        $ipAllowed = false;
        
        foreach ($allowedIPs as $allowedIP) {
            if ($allowedIP === $clientIP || (strpos($allowedIP, '*') !== false && fnmatch($allowedIP, $clientIP))) {
                $ipAllowed = true;
                break;
            }
        }
        
        if (!$ipAllowed) {
            $response['error'] = 'IP غير مسموح';
            $httpStatus = 403;
            $logData['error_message'] = 'IP not in whitelist: ' . $clientIP;
            // سيتم تسجيل الطلب في نهاية الملف
            echo json_encode($response, JSON_UNESCAPED_UNICODE);
            exit;
        }
    }
    
    // التحقق من rate limit
    if ($rateLimit > 0) {
        try {
            $stmt = $db->prepare('SELECT COUNT(*) FROM clinic_api_logs WHERE api_key_id = ? AND created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)');
            $stmt->execute([$apiKeyId]);
            $requestsLastHour = (int)$stmt->fetchColumn();
            
            if ($requestsLastHour >= $rateLimit) {
                $response['error'] = 'تم تجاوز حد الطلبات (' . $rateLimit . ' طلب/ساعة)';
                $httpStatus = 429;
                $logData['error_message'] = 'Rate limit exceeded';
                // سيتم تسجيل الطلب في نهاية الملف
                echo json_encode($response, JSON_UNESCAPED_UNICODE);
                exit;
            }
        } catch (Throwable $e) {
            // تجاهل خطأ rate limit إذا لم يكن الجدول موجوداً بعد
        }
    }
    
    $tenantCond = '';
    try {
        $db->query('SELECT tenant_id FROM lab_orders LIMIT 1');
        $tenantCond = ' AND o.tenant_id = ' . (int)$tenantId;
    } catch (Throwable $e) {}
    
    // جلب البيانات
    if ($orderId > 0 || $orderNumber !== '' || $patientId > 0) {
        $sql = 'SELECT o.id, o.order_number, o.order_date, o.status, o.patient_id, p.full_name AS patient_name, p.phone, d.full_name AS doctor_name, d.clinic_name AS doctor_clinic
                 FROM lab_orders o
                 JOIN patients p ON p.id = o.patient_id
                 LEFT JOIN doctors d ON d.id = o.doctor_id
                 WHERE 1=1' . $tenantCond;
        $params = [];
        
        if ($orderId > 0) {
            $sql .= ' AND o.id = ?';
            $params[] = $orderId;
        } elseif ($orderNumber !== '') {
            $sql .= ' AND o.order_number = ?';
            $params[] = $orderNumber;
        } elseif ($patientId > 0) {
            $sql .= ' AND o.patient_id = ? ORDER BY o.order_date DESC LIMIT 1';
            $params[] = $patientId;
        }
        
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $result = [];
        foreach ($orders as $ord) {
            $stmt = $db->prepare('SELECT t.name AS test_name, r.result_value, r.flag, t.unit, t.reference_range, r.result_date, r.validated_at
                                 FROM order_items oi
                                 JOIN tests t ON t.id = oi.test_id
                                 LEFT JOIN results r ON r.order_item_id = oi.id
                                 WHERE oi.order_id = ?');
            $stmt->execute([$ord['id']]);
            $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            $result[] = [
                'order' => [
                    'id' => (int)$ord['id'],
                    'order_number' => $ord['order_number'],
                    'order_date' => $ord['order_date'],
                    'status' => $ord['status'],
                    'patient' => [
                        'id' => (int)$ord['patient_id'],
                        'name' => $ord['patient_name'],
                        'phone' => $ord['phone']
                    ],
                    'doctor' => $ord['doctor_name'] ? [
                        'name' => $ord['doctor_name'],
                        'clinic' => $ord['doctor_clinic']
                    ] : null
                ],
                'results' => array_map(function($item) {
                    return [
                        'test_name' => $item['test_name'],
                        'result_value' => $item['result_value'],
                        'unit' => $item['unit'],
                        'reference_range' => $item['reference_range'],
                        'flag' => $item['flag'],
                        'result_date' => $item['result_date'],
                        'validated_at' => $item['validated_at']
                    ];
                }, $items)
            ];
        }
        
        $response['success'] = true;
        $response['data'] = count($result) === 1 ? $result[0] : $result;
        
        // تحديث آخر استخدام وعدد الطلبات
        try {
            $db->prepare('UPDATE clinic_api_keys SET last_used_at = NOW(), request_count = request_count + 1 WHERE id = ?')->execute([$apiKeyId]);
        } catch (Throwable $e) {}
        
    } else {
        $response['error'] = 'حدد order_id أو order_number أو patient_id';
        $httpStatus = 400;
    }
    
} catch (Throwable $e) {
    $response['error'] = 'خطأ في الخادم';
    $httpStatus = 500;
    $logData['error_message'] = $e->getMessage();
}

// تسجيل الطلب
$executionTime = (int)((microtime(true) - $startTime) * 1000);
$logData['execution_time_ms'] = $executionTime;
$logData['response_status'] = $httpStatus;
$logData['response_data'] = json_encode($response, JSON_UNESCAPED_UNICODE);

try {
    $stmt = $db->prepare('INSERT INTO clinic_api_logs (api_key_id, clinic_name, request_method, request_url, request_params, response_status, response_data, ip_address, user_agent, execution_time_ms, error_message) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
    $stmt->execute([
        $logData['api_key_id'] ?? null,
        $logData['clinic_name'] ?? '',
        $logData['request_method'],
        $logData['request_url'],
        $logData['request_params'] ?? null,
        $logData['response_status'],
        $logData['response_data'],
        $logData['ip_address'],
        $logData['user_agent'],
        $logData['execution_time_ms'],
        $logData['error_message'] ?? null
    ]);
} catch (Throwable $e) {
    // تجاهل خطأ التسجيل
}

http_response_code($httpStatus);
echo json_encode($response, JSON_UNESCAPED_UNICODE);
