<?php
/**
 * License Verification System
 * 
 * Runtime license check for the SMM Panel.
 * Include this file early in index.php to enforce license validation.
 * 
 * Flow:
 *   1. Read config/license.php
 *   2. Check local cache (6-hour TTL)
 *   3. If cache miss → call selling site API via cURL
 *   4. Block if invalid, allow if valid
 */

if (!defined('BASEPATH')) {
    die('Direct access to the script is not allowed');
}

// ─── Configuration ──────────────────────────────────────────────────
define('LICENSE_CACHE_TTL', 6 * 3600); // 6 hours
define('LICENSE_CURL_CONNECT_TIMEOUT', 5);
define('LICENSE_CURL_TIMEOUT', 10);

$licenseConfigPath = __DIR__ . '/../config/license.php';
$licenseCachePath  = __DIR__ . '/../storage/license_check_cache.json';
$licenseLogPath    = __DIR__ . '/../storage/logs/license_verify.log';

// ─── Helper: Log verification events ────────────────────────────────
function _license_log($logPath, $message) {
    $dir = dirname($logPath);
    if (!is_dir($dir)) {
        @mkdir($dir, 0755, true);
    }
    $timestamp = date('Y-m-d H:i:s');
    $line = "[$timestamp] $message" . PHP_EOL;
    @file_put_contents($logPath, $line, FILE_APPEND | LOCK_EX);
}

// ─── Helper: Show styled error & halt ───────────────────────────────
function _license_block($title, $message, $detail = '') {
    http_response_code(403);
    $safeTitle   = htmlspecialchars($title);
    $safeMessage = htmlspecialchars($message);
    $safeDetail  = htmlspecialchars($detail);
    echo <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>License Error</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { 
            min-height: 100vh; display: flex; align-items: center; justify-content: center;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
            color: #e0e0e0;
        }
        .card {
            background: rgba(255,255,255,0.05); backdrop-filter: blur(20px);
            border: 1px solid rgba(255,255,255,0.1); border-radius: 16px;
            padding: 40px 48px; max-width: 520px; width: 90%; text-align: center;
            box-shadow: 0 8px 32px rgba(0,0,0,0.3);
        }
        .icon { font-size: 48px; margin-bottom: 16px; }
        h1 { font-size: 22px; margin-bottom: 12px; color: #ff6b6b; }
        p { font-size: 15px; line-height: 1.6; color: #b0b0b0; margin-bottom: 8px; }
        .detail { font-size: 12px; color: #666; margin-top: 16px; font-family: monospace; word-break: break-all; }
        .contact { margin-top: 24px; font-size: 13px; color: #888; }
    </style>
</head>
<body>
    <div class="card">
        <div class="icon">🔒</div>
        <h1>{$safeTitle}</h1>
        <p>{$safeMessage}</p>
        {$safeDetail}
        <div class="contact">Contact your panel provider for support.</div>
    </div>
</body>
</html>
HTML;
    exit;
}

// ─── Step 1: Read license config ────────────────────────────────────
if (!file_exists($licenseConfigPath)) {
    // No license installed → redirect to installer
    $installUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')
                . '://' . $_SERVER['HTTP_HOST'] . '/install';
    header('Location: ' . $installUrl);
    exit;
}

$licenseConfig = @include $licenseConfigPath;

if (!is_array($licenseConfig) || empty($licenseConfig['license_key']) || empty($licenseConfig['api_url'])) {
    _license_log($licenseLogPath, 'ERROR: Invalid or corrupted license config file');
    _license_block(
        'License Configuration Error',
        'The license configuration file is invalid or corrupted.',
        '<p class="detail">Please re-run the installer or contact support.</p>'
    );
}

// ─── Step 2: Check cache ────────────────────────────────────────────
if (file_exists($licenseCachePath)) {
    $cacheRaw = @file_get_contents($licenseCachePath);
    $cache = @json_decode($cacheRaw, true);
    
    if (is_array($cache) 
        && isset($cache['status'], $cache['timestamp']) 
        && $cache['status'] === 'valid'
        && (time() - $cache['timestamp']) < LICENSE_CACHE_TTL
    ) {
        // Cache hit — license is valid, allow through
        return;
    }
}

// ─── Step 3: Call selling site API ──────────────────────────────────
$domain = $_SERVER['HTTP_HOST'] ?? 'unknown';
$domain = str_replace('www.', '', strtolower($domain));
$serverIp = $_SERVER['SERVER_ADDR'] ?? '0.0.0.0';

$postData = [
    'license_key'  => $licenseConfig['license_key'],
    'domain'       => $domain,
    'ip'           => $serverIp,
    'product_slug' => $licenseConfig['product_slug'] ?? '',
    'product_id'   => $licenseConfig['product_id'] ?? '',
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => $licenseConfig['api_url'],
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($postData),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => LICENSE_CURL_CONNECT_TIMEOUT,
    CURLOPT_TIMEOUT        => LICENSE_CURL_TIMEOUT,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_HTTPHEADER     => [
        'User-Agent: SMM-Panel-License-Client/1.0',
        'Accept: application/json',
    ],
]);

$response = curl_exec($ch);
$curlError = curl_error($ch);
$httpCode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// ─── Step 4: Handle response ────────────────────────────────────────

// API unreachable → fail closed
if ($response === false || empty($response)) {
    _license_log($licenseLogPath, "ERROR: API unreachable. cURL error: $curlError");
    _license_block(
        'License Server Unreachable',
        'Unable to contact the license verification server. Please check your internet connection and try again.',
        '<p class="detail">Error: ' . htmlspecialchars($curlError) . '</p>'
    );
}

$data = @json_decode($response, true);

// Invalid JSON response
if (!is_array($data) || !isset($data['status'])) {
    _license_log($licenseLogPath, "ERROR: Invalid API response. HTTP $httpCode. Body: " . substr($response, 0, 500));
    _license_block(
        'License Verification Error',
        'Received an unexpected response from the license server.',
        '<p class="detail">HTTP ' . $httpCode . '</p>'
    );
}

// Valid license → update cache and allow
if ($data['status'] === 'valid') {
    $cacheData = [
        'status'     => 'valid',
        'timestamp'  => time(),
        'expires_at' => $data['expires_at'] ?? null,
        'domain'     => $domain,
        'checked_at' => date('Y-m-d H:i:s'),
    ];
    
    $cacheDir = dirname($licenseCachePath);
    if (!is_dir($cacheDir)) {
        @mkdir($cacheDir, 0755, true);
    }
    @file_put_contents($licenseCachePath, json_encode($cacheData, JSON_PRETTY_PRINT), LOCK_EX);
    
    return; // Allow through
}

// ─── License is NOT valid ───────────────────────────────────────────
$statusMessages = [
    'invalid'         => ['Invalid License', 'The license key is not valid. Please check your license key or contact support.'],
    'expired'         => ['License Expired', 'Your license has expired on ' . ($data['expires_at'] ?? 'unknown date') . '. Please renew your license.'],
    'revoked'         => ['License Revoked', 'This license has been revoked by the administrator. Contact support for assistance.'],
    'blocked'         => ['License Blocked', 'This license has been blocked. Contact support for assistance.'],
    'domain_mismatch' => ['Domain Mismatch', 'This license is registered to a different domain. ' . ($data['message'] ?? '')],
    'wrong_product'   => ['Product Mismatch', 'This license does not match the installed product.'],
    'rate_limited'    => ['Too Many Requests', 'License verification rate limit exceeded. Please wait a moment and refresh.'],
    'unauthorized'    => ['Unauthorized', 'API authentication failed. Please check your license configuration.'],
];

$status = $data['status'];
$info = $statusMessages[$status] ?? ['License Error', $data['message'] ?? 'An unknown license error occurred.'];

_license_log($licenseLogPath, "BLOCKED: status=$status, domain=$domain, message=" . ($data['message'] ?? ''));

// Clear cache on invalid status
if (file_exists($licenseCachePath)) {
    @unlink($licenseCachePath);
}

_license_block($info[0], $info[1], '<p class="detail">Status: ' . htmlspecialchars($status) . '</p>');
