<?php

namespace App\Core;

/**
 * API Middleware - طبقة وسيطة لـ API endpoints
 */
class ApiMiddleware
{
    private PDO $db;
    private RateLimiter $rateLimiter;
    private Logger $logger;
    private array $config;

    public function __construct(PDO $db, array $config)
    {
        $this->db = $db;
        $this->config = $config;
        $this->rateLimiter = new RateLimiter($db);
        $logDir = $config['logging']['log_dir'] ?? __DIR__ . '/../../logs';
        $this->logger = new Logger($logDir);
    }

    /**
     * معالجة CORS headers
     */
    public function handleCors(): void
    {
        $allowedOrigins = $this->config['api']['allowed_origins'] ?? ['*'];
        $origin = $_SERVER['HTTP_ORIGIN'] ?? '';

        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            if (in_array('*', $allowedOrigins) || in_array($origin, $allowedOrigins)) {
                header('Access-Control-Allow-Origin: ' . ($origin ?: '*'));
            }
            header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
            header('Access-Control-Allow-Headers: Content-Type, Authorization, X-CSRF-Token, X-Requested-With');
            header('Access-Control-Max-Age: 3600');
            http_response_code(200);
            exit;
        }

        if (in_array('*', $allowedOrigins) || in_array($origin, $allowedOrigins)) {
            header('Access-Control-Allow-Origin: ' . ($origin ?: '*'));
        }
        header('Access-Control-Allow-Credentials: true');
    }

    /**
     * Rate Limiting للـ API
     */
    public function checkRateLimit(string $identifier, string $actionType = 'api_call'): array
    {
        if (!($this->config['rate_limiting']['enabled'] ?? true)) {
            return ['allowed' => true, 'remaining' => 999, 'reset_at' => null];
        }

        $rateConfig = $this->config['rate_limiting'] ?? [];
        $maxAttempts = $rateConfig['api_max_attempts'] ?? 100;
        $windowSeconds = $rateConfig['api_window_seconds'] ?? 3600;

        return $this->rateLimiter->check($identifier, $actionType, $maxAttempts, $windowSeconds);
    }

    /**
     * تسجيل محاولة API
     */
    public function recordApiCall(string $identifier, string $actionType = 'api_call'): void
    {
        $rateConfig = $this->config['rate_limiting'] ?? [];
        $windowSeconds = $rateConfig['api_window_seconds'] ?? 3600;
        $this->rateLimiter->record($identifier, $actionType, $windowSeconds);
    }

    /**
     * التحقق من API Key
     */
    public function validateApiKey(?string $apiKey): ?array
    {
        if (empty($apiKey)) {
            return null;
        }

        try {
            $stmt = $this->db->prepare('SELECT * FROM clinic_api_keys WHERE api_key = ? AND is_active = 1 LIMIT 1');
            $stmt->execute([$apiKey]);
            $key = $stmt->fetch();
            
            if (!$key) {
                return null;
            }

            // التحقق من IP whitelist
            $ipWhitelist = $key['ip_whitelist'] ?? '';
            if (!empty($ipWhitelist)) {
                $clientIp = RateLimiter::getClientIp();
                $allowedIPs = array_map('trim', explode(',', $ipWhitelist));
                $ipAllowed = false;

                foreach ($allowedIPs as $allowedIP) {
                    if ($allowedIP === $clientIp || (strpos($allowedIP, '*') !== false && fnmatch($allowedIP, $clientIp))) {
                        $ipAllowed = true;
                        break;
                    }
                }

                if (!$ipAllowed) {
                    return null;
                }
            }

            return $key;
        } catch (\Throwable $e) {
            $this->logger->error('API key validation error', ['error' => $e->getMessage()]);
            return null;
        }
    }

    /**
     * تسجيل طلب API
     */
    public function logApiRequest(array $data): void
    {
        try {
            $this->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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ')->execute([
                $data['api_key_id'] ?? null,
                $data['clinic_name'] ?? '',
                $data['request_method'] ?? $_SERVER['REQUEST_METHOD'],
                $data['request_url'] ?? $_SERVER['REQUEST_URI'] ?? '',
                $data['request_params'] ?? null,
                $data['response_status'] ?? 200,
                $data['response_data'] ?? null,
                $data['ip_address'] ?? RateLimiter::getClientIp(),
                $data['user_agent'] ?? $_SERVER['HTTP_USER_AGENT'] ?? '',
                $data['execution_time_ms'] ?? 0,
                $data['error_message'] ?? null
            ]);
        } catch (\Throwable $e) {
            // تجاهل أخطاء التسجيل
        }
    }

    /**
     * تحديث إحصائيات API Key
     */
    public function updateApiKeyStats(int $apiKeyId): void
    {
        try {
            $this->db->prepare('
                UPDATE clinic_api_keys 
                SET last_used_at = NOW(), request_count = request_count + 1 
                WHERE id = ?
            ')->execute([$apiKeyId]);
        } catch (\Throwable $e) {
            // تجاهل الأخطاء
        }
    }

    /**
     * معالجة خطأ API
     */
    public function handleError(\Throwable $e, int $statusCode = 500): void
    {
        $this->logger->exception($e);

        $isProduction = !($this->config['debug'] ?? false);
        
        $response = [
            'success' => false,
            'error' => $isProduction ? 'خطأ في الخادم' : $e->getMessage(),
            'data' => null
        ];

        if (!$isProduction) {
            $response['debug'] = [
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            ];
        }

        http_response_code($statusCode);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($response, JSON_UNESCAPED_UNICODE);
        exit;
    }

    /**
     * إرسال استجابة JSON موحدة
     */
    public function jsonResponse(array $data, int $statusCode = 200): void
    {
        http_response_code($statusCode);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    /**
     * جلب JSON input
     */
    public function getJsonInput(): ?array
    {
        $input = file_get_contents('php://input');
        if (empty($input)) {
            return null;
        }

        $data = json_decode($input, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            return null;
        }

        return $data;
    }

    /**
     * التحقق من Content-Type
     */
    public function validateContentType(string $expected = 'application/json'): bool
    {
        $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
        return strpos($contentType, $expected) !== false;
    }
}
