<?php
// STORAGE/POSITIONS — open_positions (load/save)
require_once __DIR__ . '/db.php';

// ---------------------------------------------------------------
// Открытые позиции (open_positions)
// ---------------------------------------------------------------

/**
 * Загружает все открытые позиции entity.
 * Возвращает массив ['SYMBOL' => [...поля позиции...]]
 */
function storage_load_positions(string $entityType, string $entityId): array
{
    $db   = storage_db();
    $stmt = $db->prepare('SELECT * FROM open_positions WHERE entity_type = ? AND entity_id = ?');
    $stmt->execute([$entityType, $entityId]);
    $rows = $stmt->fetchAll();

    $result = [];
    foreach ($rows as $row) {
        $result[$row['symbol']] = [
            'side'               => $row['side'],
            'entry_price'        => (float)   $row['entry_price'],
            'trader_entry_price' => $row['trader_entry_price'] !== null ? (float) $row['trader_entry_price'] : null,
            'size_usd'           => (float)   $row['size_usd'],
            'leverage'           => (int)     $row['leverage'],
            'entry_fee'          => (float)   $row['entry_fee'],
            'opened_at'          => (int)     $row['opened_at'],
            'trade_id'           => $row['trade_id'],
            'entry_reason'       => $row['entry_reason'] ?: 'normal',
            'owner_trader_id'    => $row['owner_trader_id'],
            'owner_trader_label' => $row['owner_trader_label'],
            'trader_size_coins'  => isset($row['trader_size_coins']) && $row['trader_size_coins'] !== null
                                        ? (float) $row['trader_size_coins'] : null,
            'symbol_exchange'    => $row['symbol_exchange'] ?? null,
        ];
    }

    return $result;
}

/**
 * Полностью заменяет позиции entity (DELETE + INSERT в транзакции).
 * Принимает массив ['SYMBOL' => [...поля...]] — тот же формат что load_positions.
 */
function storage_save_positions(string $entityType, string $entityId, array $positions): void
{
    $db = storage_db();
    storage_retry(function() use ($db, $entityType, $entityId, $positions) {
    $db->beginTransaction();
    try {
        $db->prepare('DELETE FROM open_positions WHERE entity_type = ? AND entity_id = ?')
           ->execute([$entityType, $entityId]);

        if (!empty($positions)) {
            $stmt = $db->prepare('
                INSERT INTO open_positions
                    (entity_type, entity_id, symbol, side, entry_price, trader_entry_price,
                     size_usd, leverage, entry_fee, opened_at, trade_id, entry_reason,
                     owner_trader_id, owner_trader_label, trader_size_coins, symbol_exchange)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ');

            foreach ($positions as $symbol => $pos) {
                $stmt->execute([
                    $entityType, $entityId, $symbol,
                    $pos['side'],
                    (float)  ($pos['entry_price']        ?? 0),
                    isset($pos['trader_entry_price']) && $pos['trader_entry_price'] !== null
                        ? (float) $pos['trader_entry_price'] : null,
                    (float)  ($pos['size_usd']           ?? 0),
                    (int)    ($pos['leverage']           ?? 1),
                    (float)  ($pos['entry_fee']          ?? 0),
                    (int)    ($pos['opened_at']          ?? 0),
                    $pos['trade_id']           ?? '',
                    $pos['entry_reason']       ?? 'normal',
                    $pos['owner_trader_id']    ?? null,
                    $pos['owner_trader_label'] ?? null,
                    isset($pos['trader_size_coins']) && $pos['trader_size_coins'] !== null
                        ? (float) $pos['trader_size_coins'] : null,
                    $pos['symbol_exchange']    ?? null,
                ]);
            }
        }

        $db->commit();
    } catch (Throwable $e) {
        $db->rollBack();
        throw $e;
    }
    }); // storage_retry
}
