<?php
/**
 * ============================================================================
 * api/encryption.php - Encryption Key Management API
 * ============================================================================
 */
define('AIMS_ACCESS', true);
require_once __DIR__ . '/../config/config.php';

header('Content-Type: application/json');
requireLogin();

try {
    $database = new Database();
    $db = $database->getConnection();
    
    $action = $_POST['action'] ?? $_GET['action'] ?? '';
    $userId = getUserId();
    
    switch ($action) {
        case 'generate_keys':
            handleGenerateKeys($db, $userId);
            break;
            
        case 'get_public_key':
            handleGetPublicKey($db);
            break;
            
        case 'verify_keys':
            handleVerifyKeys($db, $userId);
            break;
            
        case 'rotate_keys':
            handleRotateKeys($db, $userId);
            break;
            
        case 'get_fingerprint':
            handleGetFingerprint($db, $userId);
            break;
            
        default:
            jsonError('Invalid action', 400);
    }
} catch (Exception $e) {
    logError('Encryption API Error: ' . $e->getMessage());
    jsonError('An error occurred: ' . $e->getMessage(), 500);
}

/**
 * Generate encryption keys for user
 */
function handleGenerateKeys($db, $userId) {
    try {
        // Check if user already has keys
        $sql = "SELECT id FROM user_encryption_keys WHERE user_id = ?";
        $stmt = $db->prepare($sql);
        $stmt->execute([$userId]);
        
        if ($stmt->fetch()) {
            jsonError('User already has encryption keys. Use rotate_keys to change them.');
        }
        
        // Get user's password from request (required for encrypting private key)
        $password = $_POST['password'] ?? '';
        
        if (empty($password)) {
            jsonError('Password is required to generate encryption keys');
        }
        
        // Generate RSA key pair
        $encryption = new \App\Encryption();
        $keyPair = $encryption::generateKeyPair();
        
        // Encrypt private key with user's password
        $encryptedPrivateKey = $encryption::encryptPrivateKey($keyPair['private_key'], $password);
        
        // Generate fingerprint (SHA256 hash of public key)
        $fingerprint = hash('sha256', $keyPair['public_key']);
        
        // Store keys in database
        $sql = "INSERT INTO user_encryption_keys 
                (user_id, public_key, encrypted_private_key, salt, iv, fingerprint)
                VALUES (?, ?, ?, ?, ?, ?)";
        
        $stmt = $db->prepare($sql);
        $result = $stmt->execute([
            $userId,
            $keyPair['public_key'],
            $encryptedPrivateKey['encrypted_key'],
            $encryptedPrivateKey['salt'],
            $encryptedPrivateKey['iv'],
            $fingerprint
        ]);
        
        if ($result) {
            // Log the action
            $sql = "CALL LogEncryptionAction(?, 'key_generated', 'Encryption keys generated', ?, ?)";
            $stmt = $db->prepare($sql);
            $stmt->execute([
                $userId,
                $_SERVER['REMOTE_ADDR'] ?? '',
                $_SERVER['HTTP_USER_AGENT'] ?? ''
            ]);
            
            echo json_encode([
                'success' => true,
                'message' => 'Encryption keys generated successfully',
                'fingerprint' => $fingerprint
            ]);
        } else {
            jsonError('Failed to store encryption keys');
        }
        
    } catch (Exception $e) {
        logError('Key generation error: ' . $e->getMessage());
        jsonError('Failed to generate keys: ' . $e->getMessage());
    }
    exit;
}

/**
 * Get user's public key
 */
function handleGetPublicKey($db) {
    $targetUserId = intval($_GET['user_id'] ?? 0);
    
    if (!$targetUserId) {
        jsonError('User ID is required');
    }
    
    try {
        $sql = "CALL GetUserPublicKey(?)";
        $stmt = $db->prepare($sql);
        $stmt->execute([$targetUserId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($result) {
            echo json_encode([
                'success' => true,
                'public_key' => $result['public_key'],
                'fingerprint' => $result['fingerprint']
            ]);
        } else {
            jsonError('User does not have encryption keys');
        }
        
    } catch (Exception $e) {
        logError('Get public key error: ' . $e->getMessage());
        jsonError('Failed to retrieve public key');
    }
    exit;
}

/**
 * Verify user has valid encryption keys
 */
function handleVerifyKeys($db, $userId) {
    try {
        $sql = "SELECT fingerprint, created_at FROM user_encryption_keys WHERE user_id = ?";
        $stmt = $db->prepare($sql);
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($result) {
            echo json_encode([
                'success' => true,
                'has_keys' => true,
                'fingerprint' => $result['fingerprint'],
                'key_age_days' => floor((time() - strtotime($result['created_at'])) / 86400)
            ]);
        } else {
            echo json_encode([
                'success' => true,
                'has_keys' => false
            ]);
        }
        
    } catch (Exception $e) {
        logError('Verify keys error: ' . $e->getMessage());
        jsonError('Failed to verify keys');
    }
    exit;
}

/**
 * Rotate encryption keys (generate new ones)
 */
function handleRotateKeys($db, $userId) {
    try {
        $password = $_POST['password'] ?? '';
        
        if (empty($password)) {
            jsonError('Password is required to rotate encryption keys');
        }
        
        // Verify current password by trying to decrypt current private key
        $sql = "SELECT encrypted_private_key, salt, iv FROM user_encryption_keys WHERE user_id = ?";
        $stmt = $db->prepare($sql);
        $stmt->execute([$userId]);
        $currentKeys = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$currentKeys) {
            jsonError('No existing keys found. Use generate_keys instead.');
        }
        
        $encryption = new \App\Encryption();
        $privateKey = $encryption::decryptPrivateKey([
            'encrypted_key' => $currentKeys['encrypted_private_key'],
            'salt' => $currentKeys['salt'],
            'iv' => $currentKeys['iv']
        ], $password);
        
        if ($privateKey === false) {
            jsonError('Invalid password');
        }
        
        // Generate new key pair
        $newKeyPair = $encryption::generateKeyPair();
        $encryptedPrivateKey = $encryption::encryptPrivateKey($newKeyPair['private_key'], $password);
        $fingerprint = hash('sha256', $newKeyPair['public_key']);
        
        // Update keys in database
        $sql = "UPDATE user_encryption_keys 
                SET public_key = ?, 
                    encrypted_private_key = ?, 
                    salt = ?, 
                    iv = ?, 
                    fingerprint = ?,
                    updated_at = CURRENT_TIMESTAMP
                WHERE user_id = ?";
        
        $stmt = $db->prepare($sql);
        $result = $stmt->execute([
            $newKeyPair['public_key'],
            $encryptedPrivateKey['encrypted_key'],
            $encryptedPrivateKey['salt'],
            $encryptedPrivateKey['iv'],
            $fingerprint,
            $userId
        ]);
        
        if ($result) {
            // Log the action
            $sql = "CALL LogEncryptionAction(?, 'key_rotated', 'Encryption keys rotated', ?, ?)";
            $stmt = $db->prepare($sql);
            $stmt->execute([
                $userId,
                $_SERVER['REMOTE_ADDR'] ?? '',
                $_SERVER['HTTP_USER_AGENT'] ?? ''
            ]);
            
            echo json_encode([
                'success' => true,
                'message' => 'Encryption keys rotated successfully',
                'fingerprint' => $fingerprint
            ]);
        } else {
            jsonError('Failed to rotate keys');
        }
        
    } catch (Exception $e) {
        logError('Key rotation error: ' . $e->getMessage());
        jsonError('Failed to rotate keys: ' . $e->getMessage());
    }
    exit;
}

/**
 * Get user's key fingerprint
 */
function handleGetFingerprint($db, $userId) {
    try {
        $sql = "SELECT fingerprint FROM user_encryption_keys WHERE user_id = ?";
        $stmt = $db->prepare($sql);
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($result) {
            echo json_encode([
                'success' => true,
                'fingerprint' => $result['fingerprint']
            ]);
        } else {
            jsonError('No encryption keys found');
        }
        
    } catch (Exception $e) {
        logError('Get fingerprint error: ' . $e->getMessage());
        jsonError('Failed to get fingerprint');
    }
    exit;
}
?>