<?php
/**
 * ============================================================================
 * chat/ajax/generate-keys.php - FINAL FIX with Correct OpenSSL Path
 * ============================================================================
 */

// FIX THE OPENSSL PATH - THIS IS THE CRITICAL LINE!
putenv('OPENSSL_CONF=C:/Server/xampp/apache/conf/openssl.cnf');

define('AIMS_ACCESS', true);
require_once __DIR__ . '/../../config/config.php';

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

// Enable error logging
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);

if (!isLoggedIn()) {
    http_response_code(401);
    echo json_encode([
        'success' => false,
        'message' => 'Not authenticated. Please log in again.'
    ]);
    exit;
}

try {
    $userId = getUserId();
    $password = isset($_POST['password']) ? trim($_POST['password']) : '';
    
    error_log("===== Generate Keys Request =====");
    error_log("User ID: $userId");
    error_log("Password length: " . strlen($password));
    
    // Validate password
    if (empty($password)) {
        http_response_code(400);
        echo json_encode([
            'success' => false,
            'message' => 'Password is required'
        ]);
        exit;
    }
    
    if (strlen($password) < 8) {
        http_response_code(400);
        echo json_encode([
            'success' => false,
            'message' => 'Password must be at least 8 characters long'
        ]);
        exit;
    }
    
    // Get database connection
    $database = \App\Database::getInstance();
    $db = $database->getConnection();
    
    if (!$db) {
        throw new \Exception('Failed to connect to database');
    }
    
    error_log("Database connected");
    
    // Check if user already has keys
    $checkSql = "SELECT id FROM user_encryption_keys WHERE user_id = ?";
    $stmt = $db->prepare($checkSql);
    $stmt->execute([$userId]);
    
    if ($stmt->fetch()) {
        echo json_encode([
            'success' => false,
            'message' => 'Encryption keys already exist. You are already set up!'
        ]);
        exit;
    }
    
    error_log("No existing keys found");
    
    // Generate RSA key pair
    error_log("Generating RSA key pair...");
    $keys = \App\Encryption::generateKeyPair();
    
    if (!$keys || !isset($keys['public_key']) || !isset($keys['private_key'])) {
        error_log("Key generation failed");
        throw new \Exception('Failed to generate encryption keys. Please check Apache error log for details.');
    }
    
    error_log("Keys generated successfully");
    error_log("Public key length: " . strlen($keys['public_key']));
    error_log("Private key length: " . strlen($keys['private_key']));
    
    // Encrypt private key with user's password
    error_log("Encrypting private key...");
    $encryptedPrivateKey = \App\Encryption::encryptPrivateKey(
        $keys['private_key'],
        $password
    );
    
    if (!$encryptedPrivateKey || !isset($encryptedPrivateKey['encrypted_key'])) {
        error_log("Private key encryption failed");
        throw new \Exception('Failed to encrypt private key');
    }
    
    error_log("Private key encrypted successfully");
    
    // Generate fingerprint
    $fingerprint = \App\Encryption::generateFingerprint($keys['public_key']);
    error_log("Fingerprint: $fingerprint");
    
    // Store keys in database
    error_log("Storing keys in database...");
    $insertSql = "INSERT INTO user_encryption_keys (
                    user_id,
                    public_key,
                    encrypted_private_key,
                    salt,
                    iv,
                    fingerprint,
                    created_at,
                    updated_at
                  ) VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())";
    
    $stmt = $db->prepare($insertSql);
    $success = $stmt->execute([
        $userId,
        $keys['public_key'],
        $encryptedPrivateKey['encrypted_key'],
        $encryptedPrivateKey['salt'],
        $encryptedPrivateKey['iv'],
        $fingerprint
    ]);
    
    if (!$success) {
        $errorInfo = $stmt->errorInfo();
        error_log("Database insert failed: " . print_r($errorInfo, true));
        throw new \Exception('Failed to store keys: ' . $errorInfo[2]);
    }
    
    $keyId = $db->lastInsertId();
    error_log("Keys stored with ID: $keyId");
    
    // Create audit log
    try {
        $logSql = "INSERT INTO encryption_audit_log (
                    user_id,
                    action_type,
                    description,
                    ip_address,
                    user_agent,
                    created_at
                  ) VALUES (?, 'key_generated', 'User generated encryption keys', ?, ?, NOW())";
        
        $stmt = $db->prepare($logSql);
        $stmt->execute([
            $userId,
            $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
        ]);
        
        error_log("Audit log created");
    } catch (\Exception $e) {
        error_log("Audit log failed (non-critical): " . $e->getMessage());
    }
    
    // Store password in session
    $_SESSION['encryption_password'] = $password;
    $_SESSION['encryption_enabled'] = true;
    
    error_log("Password stored in session");
    error_log("===== Generate Keys Success =====");
    
    echo json_encode([
        'success' => true,
        'message' => 'Encryption keys generated successfully!',
        'fingerprint' => substr($fingerprint, 0, 16) . '...'
    ]);
    
} catch (\PDOException $e) {
    error_log('PDO Exception: ' . $e->getMessage());
    error_log('Stack trace: ' . $e->getTraceAsString());
    
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Database error: ' . $e->getMessage()
    ]);
    
} catch (\Exception $e) {
    error_log('Exception: ' . $e->getMessage());
    error_log('Stack trace: ' . $e->getTraceAsString());
    
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => $e->getMessage()
    ]);
}