<?php
/**
 * LICENSE MANAGER SERVER (Standalone Module)
 * 
 * This is the central authority that manages license keys and activations.
 * It should be hosted on a secure, separate server.
 */

header('Content-Type: application/json');
require_once __DIR__ . '/config.php';

// Simple Router
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
$endpoint = '';

if (strpos($request_uri, '/activate') !== false) $endpoint = 'activate';
if (strpos($request_uri, '/verify') !== false) $endpoint = 'verify';
if (strpos($request_uri, '/deactivate') !== false) $endpoint = 'deactivate';
if (strpos($request_uri, '/issue') !== false) $endpoint = 'issue';
if (strpos($request_uri, '/list') !== false) $endpoint = 'list';
if (strpos($request_uri, '/update') !== false) $endpoint = 'update';

$input = json_decode(file_get_contents('php://input'), true);

// If running as a simple script without proper URL rewriting
if (empty($endpoint)) {
    $endpoint = $_GET['action'] ?? $input['action'] ?? '';
}

try {
    $pdo = db_manager();
} catch (Exception $e) {
    echo json_encode(['success' => false, 'error' => 'Database connection failed.']);
    exit;
}

if ($endpoint === 'activate') {
    $key = strtoupper(trim($input['license_key'] ?? ''));
    $fingerprint = $input['fingerprint'] ?? '';
    $domain = $input['domain'] ?? '';
    $product = $input['product'] ?? '';

    if (empty($key) || empty($fingerprint)) {
        echo json_encode(['success' => false, 'error' => 'Missing required parameters.']);
        exit;
    }

    // 1. Find License
    $stmt = $pdo->prepare("SELECT * FROM licenses WHERE license_key = ? LIMIT 1");
    $stmt->execute([$key]);
    $license = $stmt->fetch();

    if (!$license) {
        echo json_encode(['success' => false, 'error' => 'Invalid license key.']);
        exit;
    }

    if ($license['status'] !== 'active') {
        echo json_encode(['success' => false, 'error' => 'License is ' . $license['status'] . '.']);
        exit;
    }

    // 2. Check current activations
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM activations WHERE license_id = ?");
    $stmt->execute([$license['id']]);
    $current_activations = $stmt->fetchColumn();

    // 3. Check if this machine is already activated
    $stmt = $pdo->prepare("SELECT * FROM activations WHERE license_id = ? AND fingerprint = ?");
    $stmt->execute([$license['id'], $fingerprint]);
    $existing = $stmt->fetch();

    if (!$existing) {
        if ($current_activations >= $license['max_activations']) {
            echo json_encode(['success' => false, 'error' => 'Maximum activation limit reached.']);
            exit;
        }

        // Record new activation
        $stmt = $pdo->prepare("INSERT INTO activations (license_id, fingerprint, domain, product) VALUES (?, ?, ?, ?)");
        $stmt->execute([$license['id'], $fingerprint, $domain, $product]);
    }

    // Success: Return signed token and license info
    $token = hash_hmac('sha256', $key . $fingerprint, SERVER_SECRET);
    echo json_encode([
        'success' => true,
        'activation_token' => $token,
        'max_activations' => (int)$license['max_activations'],
        'max_counters' => (int)$license['max_counters']
    ]);
    exit;
}

if ($endpoint === 'verify') {
    $key = strtoupper(trim($input['license_key'] ?? ''));
    $fingerprint = $input['fingerprint'] ?? '';
    $token = $input['token'] ?? '';

    // Simple validation: re-calculate token and check DB status
    $expected_token = hash_hmac('sha256', $key . $fingerprint, SERVER_SECRET);
    
    if ($token !== $expected_token) {
        echo json_encode(['success' => false, 'error' => 'Invalid activation token.']);
        exit;
    }

    $stmt = $pdo->prepare("SELECT * FROM licenses WHERE license_key = ?");
    $stmt->execute([$key]);
    $license = $stmt->fetch();
    $status = $license['status'] ?? 'suspended';

    if ($status === 'active') {
        // Count current activations for this license
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM activations WHERE license_id = ?");
        $stmt->execute([$license['id']]);
        $current_activations = (int)$stmt->fetchColumn();

        echo json_encode([
            'success' => true,
            'max_activations' => (int)$license['max_activations'],
            'max_counters' => (int)$license['max_counters'],
            'current_activations' => $current_activations
        ]);
    } else {
        echo json_encode(['success' => false, 'error' => 'License is no longer active.']);
    }
    exit;
}

if ($endpoint === 'deactivate') {
    $key = strtoupper(trim($input['license_key'] ?? ''));
    $fingerprint = $input['fingerprint'] ?? '';

    // Deactivation should ideally require a token or signature, but for simplicity:
    // We check if the license exists and the activation matches
    
    // Find License ID
    $stmt = $pdo->prepare("SELECT id FROM licenses WHERE license_key = ?");
    $stmt->execute([$key]);
    $licenseId = $stmt->fetchColumn();

    if (!$licenseId) {
        echo json_encode(['success' => false, 'error' => 'Invalid license key.']);
        exit;
    }

    // Delete Activation
    $stmt = $pdo->prepare("DELETE FROM activations WHERE license_id = ? AND fingerprint = ?");
    $stmt->execute([$licenseId, $fingerprint]);

    if ($stmt->rowCount() > 0) {
        echo json_encode(['success' => true]);
    } else {
        echo json_encode(['success' => false, 'error' => 'Activation not found.']);
    }
    exit;
}

if ($endpoint === 'issue') {
    $secret = $input['secret'] ?? '';
    
    // Basic security check using the config constant
    if ($secret !== SERVER_SECRET) {
        echo json_encode(['success' => false, 'error' => 'Unauthorized. Invalid secret.']);
        exit;
    }

    $max_activations = (int)($input['max_activations'] ?? 1);
    $max_counters = (int)($input['max_counters'] ?? 1);
    $prefix = strtoupper(trim($input['prefix'] ?? 'FLAT'));
    $owner = $input['owner'] ?? null;
    $address = $input['address'] ?? null;
    
    // Generate a formatted key: PREFIX-XXXX-XXXX
    $key = $prefix . '-' . bin2hex(random_bytes(2)) . '-' . bin2hex(random_bytes(2));
    $key = strtoupper($key);

    try {
        $stmt = $pdo->prepare("INSERT INTO licenses (license_key, max_activations, max_counters, owner, address) VALUES (?, ?, ?, ?, ?)");
        $stmt->execute([$key, $max_activations, $max_counters, $owner, $address]);
        
        echo json_encode([
            'success' => true, 
            'license_key' => $key,
            'max_activations' => $max_activations,
            'max_counters' => $max_counters,
            'owner' => $owner,
            'address' => $address
        ]);
    } catch (Exception $e) {
        echo json_encode(['success' => false, 'error' => 'Failed to generate license.']);
    }
    exit;
}

if ($endpoint === 'list') {
    // Basic security check (Optional: You can use the secret here too)
    // For now, it fetches all licenses with their activation counts
    try {
        $stmt = $pdo->prepare("
            SELECT l.*, 
                   (SELECT COUNT(*) FROM activations a WHERE a.license_id = l.id) as activations_count,
                   (l.status = 'active') as is_active
            FROM licenses l 
            ORDER BY l.created_at DESC
        ");
        $stmt->execute();
        $licenses = $stmt->fetchAll();
        
        echo json_encode([
            'success' => true,
            'data' => $licenses
        ]);
    } catch (Exception $e) {
        echo json_encode(['success' => false, 'error' => 'Failed to fetch licenses: ' . $e->getMessage()]);
    }
    exit;
}

if ($endpoint === 'update') {
    $secret = $input['secret'] ?? '';
    if ($secret !== SERVER_SECRET) {
        echo json_encode(['success' => false, 'error' => 'Unauthorized.']);
        exit;
    }

    $id = (int)($input['id'] ?? 0);
    $status = $input['status'] ?? null;
    $owner = $input['owner'] ?? null;
    $address = $input['address'] ?? null;
    $max_activations = isset($input['max_activations']) ? (int)$input['max_activations'] : null;
    $max_counters = isset($input['max_counters']) ? (int)$input['max_counters'] : null;

    if (!$id) {
        echo json_encode(['success' => false, 'error' => 'ID is required.']);
        exit;
    }

    try {
        $fields = [];
        $params = [];
        if ($status !== null) { $fields[] = "status = ?"; $params[] = $status; }
        if ($owner !== null) { $fields[] = "owner = ?"; $params[] = $owner; }
        if ($address !== null) { $fields[] = "address = ?"; $params[] = $address; }
        if ($max_activations !== null) { $fields[] = "max_activations = ?"; $params[] = $max_activations; }
        if ($max_counters !== null) { $fields[] = "max_counters = ?"; $params[] = $max_counters; }

        if (empty($fields)) {
            echo json_encode(['success' => false, 'error' => 'No fields to update.']);
            exit;
        }

        $params[] = $id;
        $sql = "UPDATE licenses SET " . implode(', ', $fields) . " WHERE id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);

        echo json_encode(['success' => true]);
    } catch (Exception $e) {
        echo json_encode(['success' => false, 'error' => 'Update failed: ' . $e->getMessage()]);
    }
    exit;
}

echo json_encode(['success' => false, 'error' => 'Invalid endpoint.']);
