<?php
declare(strict_types=1);

/**
 * Christo Lochenberg Developments - Client Licensing SDK
 * Auto-generated API Wrapper for License Communication.
 */
class AppClient {
    private string $serverUrl;
    private string $licenseKey;
    private string $currentVersion;
    private string $domain;
    private string $cacheDir;
    
    const CACHE_LICENSE = 43200; // 12 hours
    const CACHE_UPDATE  = 86400; // 24 hours
    const CACHE_NEWS    = 3600;  // 1 hour

    public function __construct(string $serverUrl, string $licenseKey, string $currentVersion, string $cacheDir = __DIR__ . '/cache') {
        $this->serverUrl = rtrim($serverUrl, '/');
        $this->licenseKey = $licenseKey;
        $this->currentVersion = $currentVersion;
        $this->cacheDir = rtrim($cacheDir, '/');
        
        $this->domain = strtolower($_SERVER['SERVER_NAME'] ?? $_SERVER['HTTP_HOST'] ?? 'unknown');
        
        if (!is_dir($this->cacheDir)) {
            @mkdir($this->cacheDir, 0755, true);
        }
    }

    public function verifyLicense(): object {
        $cacheFile = $this->cacheDir . '/license.json';
        
        if ($data = $this->getFromCache($cacheFile, self::CACHE_LICENSE)) {
            if (isset($data->status) && ($data->status === 'valid' || $data->status === 'active')) {
                return $data;
            }
        }
        
        $meta = [
            'php_version' => PHP_VERSION,
            'app_version' => $this->currentVersion,
            'server_os'   => php_uname('s') . ' ' . php_uname('r'),
            'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'
        ];

        $response = $this->makeRequest('/Api/verify', [
            'license_key' => $this->licenseKey,
            'domain'      => $this->domain,
            'metadata'    => json_encode($meta)
        ], 'POST');

        if ($response && isset($response->status) && ($response->status === 'valid' || $response->status === 'active')) {
            $this->saveToCache($cacheFile, $response);
        }
        
        return $response ?: (object)['status' => 'error', 'message' => 'Connection to license server failed.'];
    }

    public function checkUpdates(): object {
        $cacheFile = $this->cacheDir . '/update.json';
        if ($data = $this->getFromCache($cacheFile, self::CACHE_UPDATE)) return $data;
        
        $response = $this->makeRequest('/UpdateApi/check', [
            'license_key' => $this->licenseKey,
            'current_version' => $this->currentVersion,
            'domain' => $this->domain
        ], 'POST');
        
        if ($response) $this->saveToCache($cacheFile, $response);
        return $response ?: (object)['update_available' => false];
    }

    public function getNews(): object {
        $cacheFile = $this->cacheDir . '/news.json';
        if ($data = $this->getFromCache($cacheFile, self::CACHE_NEWS)) return $data;
        
        $endpoint = '/NewsApi/feed?license_key=' . urlencode($this->licenseKey) . '&domain=' . urlencode($this->domain);
        $response = $this->makeRequest($endpoint, [], 'GET');
        
        if ($response && isset($response->status) && $response->status === 'success') {
            $this->saveToCache($cacheFile, $response);
        }
        return $response ?: (object)['global_news' => [], 'product_news' => []];
    }

    private function makeRequest(string $endpoint, array $params, string $method = 'POST'): ?object {
        $ch = curl_init();
        $url = $this->serverUrl . $endpoint;
        
        if ($method !== 'GET') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        }
        
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false, 
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_TIMEOUT => 15,
            CURLOPT_USERAGENT => 'ChristoDev-LicenseClient/2.0'
        ]);
        
        $result = curl_exec($ch);
        curl_close($ch);
        
        return $result ? json_decode($result) : null;
    }

    private function getFromCache(string $file, int $duration): ?object {
        if ($duration <= 0) return null;
        if (file_exists($file) && (time() - filemtime($file) < $duration)) {
            $content = @file_get_contents($file);
            if ($content) return json_decode($content);
        }
        return null;
    }

    private function saveToCache(string $file, object $data): void {
        @file_put_contents($file, json_encode($data));
    }
}