<?php

namespace App\Core;

/**
 * API Versioning System
 * يدعم versioning للـ APIs مع deprecation policy
 */
class ApiVersioning
{
    private string $currentVersion;
    private array $supportedVersions;
    private array $deprecatedVersions;
    private array $versionHandlers;

    public function __construct(string $currentVersion = 'v1', array $supportedVersions = ['v1'], array $deprecatedVersions = [])
    {
        $this->currentVersion = $currentVersion;
        $this->supportedVersions = $supportedVersions;
        $this->deprecatedVersions = $deprecatedVersions;
        $this->versionHandlers = [];
    }

    /**
     * استخراج version من request
     */
    public static function extractVersion(): ?string
    {
        // من URL: /api/v1/endpoint
        $path = $_SERVER['REQUEST_URI'] ?? '';
        if (preg_match('#/api/(v\d+)/#', $path, $matches)) {
            return $matches[1];
        }

        // من Header: Accept: application/vnd.api+json;version=1
        $accept = $_SERVER['HTTP_ACCEPT'] ?? '';
        if (preg_match('/version=(\d+)/', $accept, $matches)) {
            return 'v' . $matches[1];
        }

        // من Query: ?version=1
        $version = $_GET['version'] ?? null;
        if ($version) {
            return is_numeric($version) ? 'v' . $version : $version;
        }

        return null;
    }

    /**
     * التحقق من صحة version
     */
    public function isValidVersion(?string $version): bool
    {
        if ($version === null) {
            return true; // Default to current
        }
        return in_array($version, $this->supportedVersions, true);
    }

    /**
     * التحقق من deprecation
     */
    public function isDeprecated(?string $version): bool
    {
        if ($version === null) {
            return false;
        }
        return in_array($version, $this->deprecatedVersions, true);
    }

    /**
     * جلب version للاستخدام
     */
    public function getVersion(?string $requestedVersion = null): string
    {
        $version = $requestedVersion ?? self::extractVersion() ?? $this->currentVersion;
        
        if (!$this->isValidVersion($version)) {
            return $this->currentVersion;
        }

        return $version;
    }

    /**
     * إضافة deprecation headers
     */
    public function addDeprecationHeaders(?string $version): void
    {
        if ($this->isDeprecated($version)) {
            header('Deprecation: true');
            header('Sunset: ' . date('Y-m-d', strtotime('+6 months')));
            header('Link: <' . $_SERVER['REQUEST_URI'] . '>; rel="deprecation"');
        }
    }

    /**
     * تسجيل version handler
     */
    public function registerHandler(string $version, callable $handler): void
    {
        $this->versionHandlers[$version] = $handler;
    }

    /**
     * تنفيذ handler للـ version
     */
    public function handleVersion(?string $version, array $params = [])
    {
        $version = $this->getVersion($version);
        
        if (isset($this->versionHandlers[$version])) {
            return call_user_func($this->versionHandlers[$version], $params);
        }

        return null;
    }

    /**
     * API Response مع version info
     */
    public function versionedResponse(array $data, ?string $version = null): array
    {
        $version = $this->getVersion($version);
        
        return [
            'data' => $data,
            'meta' => [
                'version' => $version,
                'current_version' => $this->currentVersion,
                'deprecated' => $this->isDeprecated($version),
                'supported_versions' => $this->supportedVersions
            ]
        ];
    }

    /**
     * Error response للـ version غير مدعوم
     */
    public function unsupportedVersionResponse(?string $version): array
    {
        http_response_code(400);
        return [
            'error' => 'Unsupported API version',
            'requested_version' => $version,
            'supported_versions' => $this->supportedVersions,
            'current_version' => $this->currentVersion
        ];
    }
}
