<?php
/**
 * API Endpoint: Trading Positions
 * Devuelve las posiciones abiertas del cliente
 */

session_start();
// Permitir modo invitado: devolver lista vacía sin error
$isAuthorized = (isset($_SESSION['client_id']) && (($_SESSION['client_status'] ?? 'inactive') === 'active'));
if (!$isAuthorized) {
    header('Content-Type: application/json');
    echo json_encode(['success' => true, 'positions' => [], 'total_count' => 0]);
    exit;
}

// Configuración de la base de datos
require_once __DIR__ . '/../../../database/connection.php';

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

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

    $client_id = $_SESSION['client_id'];
    $accountNumber = isset($_GET['account_number']) ? trim($_GET['account_number']) : null;
    
    // Obtener cuenta de trading del cliente
    if ($accountNumber) {
        $stmt = $pdo->prepare("SELECT id FROM trading_accounts WHERE client_id = ? AND account_number = ? AND status = 'active' LIMIT 1");
        $stmt->execute([$client_id, $accountNumber]);
    } else {
        $stmt = $pdo->prepare("SELECT id FROM trading_accounts WHERE client_id = ? AND status = 'active' ORDER BY created_at DESC LIMIT 1");
        $stmt->execute([$client_id]);
    }
    $account = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$account) {
        echo json_encode([
            'success' => true,
            'positions' => [],
            'total_count' => 0,
            'total_pnl' => 0,
            'message' => 'No se encontró cuenta de trading'
        ]);
        exit;
    }
    
    $account_id = $account['id'];
    
    $status = isset($_GET['status']) ? strtolower(trim($_GET['status'])) : 'open';
    if (!in_array($status, ['open','closed'])) $status = 'open';

    // Obtener posiciones según estado
    $stmt = $pdo->prepare("
        SELECT 
            tp.*,
            ti.name as instrument_name,
            ti.pip_size,
            ti.base_currency,
            ti.quote_currency,
            ti.contract_size,
            ti.margin_rate
        FROM trading_positions tp
        LEFT JOIN trading_instruments ti ON tp.symbol = ti.symbol
        WHERE tp.account_id = ? AND tp.status = 'open'
        ORDER BY tp.opened_at DESC
    ");
    
    if ($status === 'open') {
        $stmt->execute([$account_id]);
        $positions = $stmt->fetchAll(PDO::FETCH_ASSOC);
    } else {
        $stmt = $pdo->prepare("SELECT tp.* FROM trading_positions tp WHERE tp.account_id = ? AND tp.status = 'closed' ORDER BY tp.closed_at DESC");
        $stmt->execute([$account_id]);
        $positions = $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    // Si son abiertas, obtener precios reales desde Finage para calcular P&L
    require_once __DIR__ . '/../finage_api.php';
    $finage = getFinageAPI();
    $symbols = array_values(array_unique(array_map(function($pos){ return $pos['symbol']; }, $positions)));
    $realPrices = [];
    try {
        if (count($symbols) > 0) {
            $realPrices = $finage->getMultiplePrices($symbols);
        }
    } catch (\Throwable $e) {
        error_log('Finage getMultiplePrices error (positions): ' . $e->getMessage());
        $realPrices = [];
    }
    
    $totalPnl = 0;
    
    // Calcular P&L para cada posición con precios Finage y pip value fiable
    foreach ($positions as &$position) {
        $symbol = $position['symbol'];
        $type = strtolower($position['type']);
        $volume = floatval($position['volume']);
        $openPrice = floatval($position['open_price']);
        $quote = $position['quote_currency'] ?? substr($symbol, -3);
        $contractSize = isset($position['contract_size']) ? floatval($position['contract_size']) : 100000;
        $pipSize = isset($position['pip_size']) && is_numeric($position['pip_size']) ? floatval($position['pip_size']) : ((strpos($symbol, 'JPY') !== false) ? 0.01 : 0.0001);

        // Precio actual: usar BID/ASK según lado cuando disponible; si no, mid = promedio
        if ($status === 'closed') {
            // Para cerradas, mantener datos de cierre
            $position['current_price'] = isset($position['close_price']) ? floatval($position['close_price']) : $openPrice;
            $position['pnl'] = isset($position['profit']) ? floatval($position['profit']) : floatval($position['pnl'] ?? 0);
            $position['pnl_formatted'] = ($position['pnl'] >= 0 ? '+' : '') . number_format($position['pnl'], 2);
            $position['volume_formatted'] = number_format($volume, 2);
            $position['closed_at_formatted'] = isset($position['closed_at']) ? date('d/m/Y H:i:s', strtotime($position['closed_at'])) : '';
            continue;
        }
        $currentPrice = null;
        if (isset($realPrices[$symbol])) {
            $rp = $realPrices[$symbol];
            $bid = isset($rp['bid']) ? floatval($rp['bid']) : null;
            $ask = isset($rp['ask']) ? floatval($rp['ask']) : null;
            if (is_numeric($bid) && is_numeric($ask)) {
                $currentPrice = ($type === 'buy') ? $bid : $ask; // evaluación conservadora
            } else {
                $p = isset($rp['price']) ? floatval($rp['price']) : null;
                $currentPrice = is_numeric($p) ? $p : null;
            }
        }
        if (!is_numeric($currentPrice)) $currentPrice = $openPrice; // fallback para no romper cálculo

        // Delta y pips
        $delta = ($type === 'buy') ? ($currentPrice - $openPrice) : ($openPrice - $currentPrice);
        $pips = $pipSize > 0 ? ($delta / $pipSize) : 0;

        // Pip value por lote en USD fiable
        $pipValuePerLotUSD = 10.0;
        if (strtoupper($quote) !== 'USD') {
            $pipValuePerLotUSD = ($contractSize * $pipSize) / max($currentPrice, 1e-9);
        }

        $pnl = $pips * $pipValuePerLotUSD * $volume;

        $position['current_price'] = $currentPrice;
        $position['pnl'] = $pnl;
        $position['pnl_pips'] = $pips;

        // Formatear valores
        $decimals = (strpos($symbol, 'JPY') !== false) ? 3 : 5;
        $position['open_price_formatted'] = number_format($openPrice, $decimals);
        $position['current_price_formatted'] = is_numeric($currentPrice) ? number_format($currentPrice, $decimals) : '-';
        $position['pnl_formatted'] = ($pnl >= 0 ? '+' : '') . number_format($pnl, 2);
        $position['pnl_pips_formatted'] = ($pips >= 0 ? '+' : '') . number_format($pips, 1);
        $position['volume_formatted'] = number_format($volume, 2);

        // Margen usado basado en leverage o margin_rate del instrumento
        $leverage = isset($position['leverage']) ? floatval($position['leverage']) : 100.0;
        $marginRate = isset($position['margin_rate']) ? floatval($position['margin_rate']) : null;
        $notional = $contractSize * $volume * max($currentPrice, $openPrice);
        $marginUsed = ($marginRate && $marginRate > 0) ? ($notional * $marginRate) : ($leverage > 0 ? ($notional / $leverage) : 0);
        $position['margin_used'] = $marginUsed;
        $position['pnl_percent'] = $marginUsed > 0 ? ($pnl / $marginUsed) * 100 : 0;
        $position['pnl_percent_formatted'] = ($position['pnl_percent'] >= 0 ? '+' : '') . number_format($position['pnl_percent'], 2) . '%';
        
        // Determinar estado de la posición
        $position['status_class'] = $pnl >= 0 ? 'profit' : 'loss';
        $position['type_class'] = strtolower($type);
        
        // Información adicional
        $position['opened_at_formatted'] = date('d/m/Y H:i:s', strtotime($position['opened_at']));
        $position['duration'] = calculateDuration($position['opened_at']);
        
        $totalPnl += $pnl;
    }
    
    // Estadísticas generales
    $profitablePositions = array_filter($positions, function($pos) { return $pos['pnl'] > 0; });
    $losingPositions = array_filter($positions, function($pos) { return $pos['pnl'] < 0; });
    
    if ($status === 'closed') {
        echo json_encode([
            'success' => true,
            'positions' => $positions,
            'statistics' => [
                'total_count' => count($positions)
            ],
            'last_updated' => date('Y-m-d H:i:s')
        ]);
    } else {
        echo json_encode([
            'success' => true,
            'positions' => $positions,
            'statistics' => [
                'total_count' => count($positions),
                'profitable_count' => count($profitablePositions),
                'losing_count' => count($losingPositions),
                'total_pnl' => $totalPnl,
                'total_pnl_formatted' => ($totalPnl >= 0 ? '+' : '') . number_format($totalPnl, 2),
                'win_rate' => count($positions) > 0 ? (count($profitablePositions) / count($positions)) * 100 : 0
            ],
            'last_updated' => date('Y-m-d H:i:s')
        ]);
    }
    
} catch (Exception $e) {
    error_log("Error en positions.php: " . $e->getMessage());
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'Error interno del servidor'
    ]);
}

/**
 * Calcular duración desde la apertura
 */
function calculateDuration($openedAt) {
    $opened = new DateTime($openedAt);
    $now = new DateTime();
    $interval = $opened->diff($now);
    
    if ($interval->days > 0) {
        return $interval->days . 'd ' . $interval->h . 'h';
    } elseif ($interval->h > 0) {
        return $interval->h . 'h ' . $interval->i . 'm';
    } else {
        return $interval->i . 'm ' . $interval->s . 's';
    }
}
?>
