<?php
// STORAGE/HL_ORDERS — учёт ордеров прямой торговли
require_once __DIR__ . '/db.php';

// ---------------------------------------------------------------
// Учёт ордеров прямой торговли (hl_orders)
// ---------------------------------------------------------------

/** Регистрирует наш ордер (kind: main|grid|sl|tp) для последующей отмены. */
function storage_hl_order_add(
    string $entityType,
    string $entityId,
    string $symbol,
    string $cloid,
    string $kind,
    ?int $oid = null
): void {
    storage_retry(function () use ($entityType, $entityId, $symbol, $cloid, $kind, $oid) {
        $db = storage_db();
        $db->prepare('
            INSERT INTO hl_orders (entity_type, entity_id, symbol, cloid, oid, kind)
            VALUES (?, ?, ?, ?, ?, ?)
        ')->execute([$entityType, $entityId, $symbol, $cloid, $oid, $kind]);
    });
}

/** Все наши ордера по (entity, symbol). */
function storage_hl_orders_get(string $entityType, string $entityId, string $symbol): array
{
    $db = storage_db();
    $stmt = $db->prepare('
        SELECT cloid, oid, kind FROM hl_orders
        WHERE entity_type = ? AND entity_id = ? AND symbol = ?
        ORDER BY id ASC
    ');
    $stmt->execute([$entityType, $entityId, $symbol]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

/**
 * Атомарно захватывает лизу владения символом на КОНКРЕТНОМ аккаунте (субаккаунт
 * direct-сущности или мастер). Одна позиция на символ — на аккаунт. Возвращает
 * true, если символ теперь наш (или уже был наш на этом аккаунте), false — если
 * им на этом аккаунте владеет ДРУГАЯ сущность. Захватывать нужно ДО marketOpen и
 * освобождать (storage_hl_release_symbol) при закрытии/аборте.
 */
function storage_hl_try_claim_symbol(string $account, string $entityType, string $entityId, string $symbol): bool
{
    return storage_retry(function () use ($account, $entityType, $entityId, $symbol) {
        $db = storage_db();
        // Атомарный захват: INSERT OR IGNORE по PRIMARY KEY (account, symbol).
        $stmt = $db->prepare('
            INSERT OR IGNORE INTO hl_locks (account, symbol, entity_type, entity_id, claimed_at)
            VALUES (?, ?, ?, ?, ?)
        ');
        $stmt->execute([$account, $symbol, $entityType, $entityId, time()]);
        if ($stmt->rowCount() > 0) {
            return true;   // мы захватили лизу
        }
        // Лиза уже есть — проверяем, наша ли она.
        $sel = $db->prepare('SELECT entity_type, entity_id FROM hl_locks WHERE account = ? AND symbol = ?');
        $sel->execute([$account, $symbol]);
        $row = $sel->fetch(PDO::FETCH_ASSOC);
        return $row !== false
            && $row['entity_type'] === $entityType
            && $row['entity_id'] === $entityId;
    });
}

/** Освобождает лизу символа на аккаунте, только если ею владеет данная сущность. */
function storage_hl_release_symbol(string $account, string $entityType, string $entityId, string $symbol): void
{
    storage_retry(function () use ($account, $entityType, $entityId, $symbol) {
        $db = storage_db();
        $db->prepare('
            DELETE FROM hl_locks
            WHERE account = ? AND symbol = ? AND entity_type = ? AND entity_id = ?
        ')->execute([$account, $symbol, $entityType, $entityId]);
    });
}

/**
 * Все лизы данной сущности на аккаунте: [['symbol' => .., 'claimed_at' => int], ...].
 * Нужно реконсиляции direct-слоя: обойти символы, которыми сущность владеет,
 * и сверить их с реальными позициями на бирже.
 */
function storage_hl_entity_leases(string $account, string $entityType, string $entityId): array
{
    $db = storage_db();
    $stmt = $db->prepare('
        SELECT symbol, claimed_at FROM hl_locks
        WHERE account = ? AND entity_type = ? AND entity_id = ?
        ORDER BY symbol ASC
    ');
    $stmt->execute([$account, $entityType, $entityId]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

/**
 * ВСЕ лизы сущности НЕЗАВИСИМО от аккаунта: [['account','symbol','claimed_at'],...].
 * Нужно hl_teardown_entity при удалении/сбросе сущности из дашборда: у сущности
 * могли остаться лизы под старым субаккаунтом (оператор сменил hl_subaccount),
 * и все они должны быть свёрнуты, а не только текущего аккаунта.
 */
function storage_hl_all_entity_leases(string $entityType, string $entityId): array
{
    $db = storage_db();
    $stmt = $db->prepare('
        SELECT account, symbol, claimed_at FROM hl_locks
        WHERE entity_type = ? AND entity_id = ?
        ORDER BY account ASC, symbol ASC
    ');
    $stmt->execute([$entityType, $entityId]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

/** Текущий владелец лизы символа на аккаунте ['entity_type','entity_id'] или null. */
function storage_hl_symbol_owner(string $account, string $symbol): ?array
{
    $db = storage_db();
    $stmt = $db->prepare('SELECT entity_type, entity_id FROM hl_locks WHERE account = ? AND symbol = ?');
    $stmt->execute([$account, $symbol]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    return $row === false ? null : $row;
}

/** Удаляет учёт наших ордеров по (entity, symbol) — после закрытия/отмены. */
function storage_hl_orders_clear(string $entityType, string $entityId, string $symbol): void
{
    storage_retry(function () use ($entityType, $entityId, $symbol) {
        $db = storage_db();
        $db->prepare('
            DELETE FROM hl_orders
            WHERE entity_type = ? AND entity_id = ? AND symbol = ?
        ')->execute([$entityType, $entityId, $symbol]);
    });
}
