<?php
/**
 * ROI Processing Endpoint
 * 
 * This endpoint processes ROI for all active investments and updates user balances.
 * It's designed to be called by a cron job or scheduled task.
 */

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/includes/Database.php';
require_once __DIR__ . '/includes/Security.php';

// Set headers for JSON response
header('Content-Type: application/json');
header('X-Content-Type-Options: nosniff');

// Initialize response array
$response = [
    'status' => 'error',
    'message' => '',
    'data' => [],
    'debug' => []
];

try {
    // Set up debug output to response and log file
function debug_log($message, $data = null) {
    global $response;
    $logFile = __DIR__ . '/../logs/roi_processing.log';
    $logMessage = date('[Y-m-d H:i:s] ') . $message . "\n";
    
    if ($data !== null) {
        $logMessage .= print_r($data, true) . "\n";
    }
    
    // Add to response
    $response['debug'][] = $logMessage;
    
    // Log to file
    file_put_contents($logFile, $logMessage, FILE_APPEND);
    
    // Output immediately for CLI
    if (php_sapi_name() === 'cli') {
        echo $logMessage;
    }
}

debug_log("=== Starting ROI Processing ===");

// Create logs directory if it doesn't exist
if (!is_dir(__DIR__ . '/../logs')) {
    mkdir(__DIR__ . '/../logs', 0755, true);
}

// Clear previous log file
file_put_contents(__DIR__ . '/../logs/roi_processing.log', "");

debug_log("=== Starting ROI Processing ===");

// Verify API key for security
$apiKey = '';
$input = [];
$testMode = false;

if (php_sapi_name() === 'cli') {
    // For CLI, get from command line arguments
    $options = getopt('', ['api-key::', 'test-mode::', 'data::']);
    
    // Get API key from command line
    if (isset($options['api-key'])) {
        $apiKey = $options['api-key'];
    } elseif (isset($_SERVER['HTTP_X_API_KEY'])) {
        $apiKey = $_SERVER['HTTP_X_API_KEY'];
    }
    
    // Parse JSON data if provided
    if (isset($options['data'])) {
        $input = json_decode($options['data'], true) ?: [];
    }
    
    // Set test mode
    $testMode = isset($options['test-mode']) || (isset($input['test_mode']) && $input['test_mode'] === true);
    
    debug_log("CLI Mode - API Key: " . ($apiKey ? '***' . substr($apiKey, -4) : 'Not Provided'));
    debug_log("Test Mode: " . ($testMode ? 'ON' : 'OFF'));
} else {
    // For web requests
    $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
    $input = json_decode(file_get_contents('php://input'), true) ?: [];
    $testMode = isset($input['test_mode']) && $input['test_mode'] === true;
}

$validApiKey = getenv('CRON_API_KEY') ?: 'test-key'; // Changed to match test key

// Debug logging
debug_log("API Key received: " . ($apiKey ? '***' . substr($apiKey, -4) : 'NONE'));
debug_log("Expected API Key: " . ($validApiKey ? '***' . substr($validApiKey, -4) : 'NONE'));

if (empty($apiKey) || $apiKey !== $validApiKey) {
    debug_log("❌ API Key validation failed");
    throw new Exception('Invalid or missing API key', 401);
}

debug_log("✅ API Key validation successful");
    
    // Get request data
$input = json_decode(file_get_contents('php://input'), true) ?: [];
$testMode = (bool)($input['test_mode'] ?? false);
$days = max(1, min(30, (int)($input['days'] ?? 1))); // Default to 1 day, max 30 days

debug_log("Test Mode: " . ($testMode ? 'ON' : 'OFF'));
debug_log("Processing for $days day(s)");

debug_log("Input data:", $input);
    
    // Initialize database connection
try {
    $db = Database::getInstance();
    $pdo = $db->getConnection();
    debug_log("✅ Database connection established");
    
    // Test database connection with a simple query
    $testQuery = $pdo->query("SELECT COUNT(*) as count FROM investments");
    $result = $testQuery->fetch(PDO::FETCH_ASSOC);
    debug_log("Test query result:", $result);
} catch (Exception $e) {
    error_log("❌ Database connection failed: " . $e->getMessage());
    throw $e;
}

// Start transaction
try {
    $pdo->beginTransaction();
    error_log("✅ Database transaction started");
} catch (Exception $e) {
    error_log("❌ Failed to start transaction: " . $e->getMessage());
    throw $e;
}
    
    // Get active investments from investments table
debug_log("Fetching active investments...");
try {
    $sql = "
        SELECT i.*, u.id as user_id, u.balance, u.email, u.username, p.name as plan_name, p.roi_percentage, p.duration_days 
        FROM investments i
        JOIN users u ON i.user_id = u.id
        JOIN investment_plans p ON i.plan_id = p.id
        WHERE i.status = 'active' AND i.end_date > NOW() AND i.start_date <= NOW()
        ORDER BY i.id ASC
        LIMIT 10
    ";
    
    debug_log("SQL Query:", $sql);
    
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $investments = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    debug_log("Query executed successfully");
    debug_log("Number of active investments found: " . count($investments));
    debug_log("Sample investment data:", $investments ? array_slice($investments, 0, 1) : []);
    
    if (empty($investments)) {
        error_log("No active investments found for ROI processing");
    }
    
} catch (Exception $e) {
    error_log("❌ Error fetching investments: " . $e->getMessage());
    throw $e;
}
    
    $processedCount = 0;
    $totalRoi = 0;
    $now = date('Y-m-d H:i:s');
    
    foreach ($investments as $investment) {
        // Calculate ROI for the specified number of days
        $dailyRoi = $investment['amount'] * ($investment['roi_percentage'] / 100) / $investment['duration_days'];
        $totalRoiForPeriod = $dailyRoi * $days;
        
        // Update investment
        // First, get the current ROI value
        $getRoiStmt = $pdo->prepare("SELECT roi FROM investments WHERE id = :id");
        $getRoiStmt->execute([':id' => $investment['id']]);
        $currentRoi = $getRoiStmt->fetchColumn();
        
        // Calculate new values
        $newRoi = $currentRoi + $totalRoiForPeriod;
        $totalReturn = $investment['amount'] + $newRoi;
        
        // Update investment with calculated values (total_return = amount + roi)
        $updateStmt = $pdo->prepare("
            UPDATE investments 
            SET 
                roi = :new_roi,
                total_return = amount + :new_roi,
                updated_at = :now
            WHERE id = :id
        ");
        
        $updateStmt->execute([
            ':new_roi' => $newRoi,
            ':now' => $now,
            ':id' => $investment['id']
        ]);
        
        error_log("Updated investment #{$investment['id']} with ROI: $totalRoiForPeriod");
        
        // Update user balance and total_earned
        $updateBalanceStmt = $pdo->prepare("
            UPDATE users 
            SET balance = balance + :roi,
                total_earned = COALESCE(total_earned, 0) + :roi,
                updated_at = :now
            WHERE id = :user_id
        ");
        
        $updateBalanceStmt->execute([
            ':roi' => $totalRoiForPeriod,
            ':user_id' => $investment['user_id'],
            ':now' => $now
        ]);
        
        // Record transaction
        $transactionReference = 'ROI-' . time() . '-' . $investment['id'];
        $transactionDetails = "ROI for investment #{$investment['id']} for {$days} day(s)";
        
        // First, check the transactions table structure
        $checkTable = $pdo->query("SHOW COLUMNS FROM transactions");
        $columns = $checkTable->fetchAll(PDO::FETCH_COLUMN);
        error_log("Transactions table columns: " . print_r($columns, true));
        
        // Build the query based on actual table structure
        $transactionStmt = $pdo->prepare("
            INSERT INTO transactions (
                user_id,
                type,
                amount,
                details,
                reference,
                created_at
            ) VALUES (
                :user_id,
                'profit',
                :amount,
                :details,
                :reference,
                :now
            )
        ");
        
        $params = [
            'user_id' => $investment['user_id'],
            'amount' => $totalRoiForPeriod,
            'details' => $transactionDetails,
            'reference' => $transactionReference,
            'now' => $now
        ];
        
        error_log("Recording transaction with params: " . json_encode($params));
        error_log("SQL Query: " . $transactionStmt->queryString);
        
        try {
            if (!$transactionStmt->execute($params)) {
                $error = $transactionStmt->errorInfo();
                error_log("Failed to insert transaction: " . print_r($error, true));
                throw new Exception("Failed to record transaction: " . ($error[2] ?? 'Unknown error'));
            }
            error_log("Transaction recorded successfully");
        } catch (PDOException $e) {
            error_log("PDO Exception: " . $e->getMessage());
            error_log("SQL State: " . $e->getCode());
            throw $e;
        }
        
        $processedCount++;
        $totalRoi += $totalRoiForPeriod;
    }
    
    // Commit transaction if not in test mode
    if (!$testMode) {
        $pdo->commit();
    } else {
        $pdo->rollBack(); // Rollback in test mode
    }
    
    // Prepare success response
    $response = [
        'status' => 'success',
        'message' => 'ROI processing completed successfully',
        'data' => [
            'processed_investments' => $processedCount,
            'total_roi_processed' => $totalRoi,
            'test_mode' => $testMode
        ]
    ];
    
} catch (Exception $e) {
    // Rollback on error
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    
    // Get detailed error information
    $errorInfo = [
        'message' => $e->getMessage(),
        'code' => $e->getCode(),
        'file' => $e->getFile(),
        'line' => $e->getLine(),
        'trace' => $e->getTraceAsString()
    ];
    
    $response = [
        'status' => 'error',
        'message' => $e->getMessage(),
        'code' => $e->getCode() ?: 500,
        'debug' => $errorInfo
    ];
    
    // Log the error with full details
    error_log("ROI Processing Error: " . print_r($errorInfo, true));
}

// Output JSON response
echo json_encode($response, JSON_PRETTY_PRINT);
?>
