<?php
// =============================================================
// DASHBOARD/LIB/RENDER — HTML-хелперы форм (view-слой)
// =============================================================
// Печатают HTML; в юнит-тестах не участвуют. Вынесены из страниц,
// чтобы отделить разметку форм от логики обработки.

require_once __DIR__ . '/forms.php';
require_once __DIR__ . '/settings_render.php';   // каталог настроек — единый источник подписей

// --- Ссылка на трейдера в HyperDash --------------------------

/**
 * URL страницы трейдера на HyperDash по адресу кошелька.
 */
function hyperdash_url(string $address): string
{
    return 'https://hyperdash.com/address/' . rawurlencode($address);
}

/**
 * Маленькая кнопка-ссылка (квадратик со стрелкой ↗) на страницу трейдера
 * в HyperDash. Возвращает готовый HTML; при пустом адресе — пустую строку.
 * stopPropagation — чтобы клик по ссылке не срабатывал как клик по строке/карточке.
 */
function hyperdash_link(?string $address): string
{
    if ($address === null || $address === '') {
        return '';
    }

    return '<a class="hd-link" href="' . htmlspecialchars(hyperdash_url($address)) . '"'
        . ' target="_blank" rel="noopener" title="Открыть на HyperDash"'
        . ' onclick="event.stopPropagation()">'
        . '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">'
        . '<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>'
        . '<polyline points="15 3 21 3 21 9"/>'
        . '<line x1="10" y1="14" x2="21" y2="3"/>'
        . '</svg></a>';
}

// --- Ссылка на монету в TradingView --------------------------

/**
 * URL графика торговой пары на TradingView. Символ трейда/позиции (BTC, ETH,
 * kPEPE…) приводится к паре с USDT — TradingView сам подбирает биржу.
 */
function tradingview_url(string $symbol): string
{
    $coin = strtoupper(preg_replace('/[^A-Za-z0-9]/', '', $symbol));
    return 'https://www.tradingview.com/chart/?symbol=' . rawurlencode($coin . 'USDT');
}

/**
 * Маленькая кнопка-ссылка (иконка свечей) на график монеты в TradingView —
 * по аналогии с hyperdash_link у трейдеров. Открывает соответствующую
 * торговую пару в формате USDT. Пустой символ → пустая строка.
 * stopPropagation — чтобы клик по ссылке не срабатывал как клик по строке/карточке.
 */
function tradingview_link(?string $symbol): string
{
    if ($symbol === null || trim($symbol) === '') {
        return '';
    }

    return '<a class="tv-link" href="' . htmlspecialchars(tradingview_url($symbol)) . '"'
        . ' target="_blank" rel="noopener" title="Открыть график на TradingView"'
        . ' onclick="event.stopPropagation()">'
        . '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">'
        . '<line x1="8" y1="3" x2="8" y2="21"/><rect x="5" y="7" width="6" height="8" rx="1"/>'
        . '<line x1="16" y1="5" x2="16" y2="19"/><rect x="13" y="9.5" width="6" height="6" rx="1"/>'
        . '</svg></a>';
}

// --- Теги кошельков ------------------------------------------

/**
 * Детерминированный оттенок (0-359) для тега: один и тот же тег всегда
 * окрашен одинаково, разные теги визуально различимы. Используется как
 * CSS-переменная --tag-h в .tag-pill.
 */
function tag_hue(string $tag): int
{
    return abs(crc32(mb_strtolower(trim($tag)))) % 360;
}

/**
 * HTML-пилюля тега с индивидуальным цветом.
 */
function tag_pill(string $tag): string
{
    return '<span class="tag-pill" style="--tag-h: ' . tag_hue($tag) . '">'
        . htmlspecialchars($tag) . '</span>';
}

/**
 * Компактный индикатор рейтинга трейдера — одна золотая звёздочка с цифрой.
 * Ненавязчивый маркер «избранного» для списков (сделки, журнал, реестр, лента).
 * Пустая строка при рейтинге 0 — чтобы вставлять прямо в шаблон без обёрток.
 */
function rating_badge(int $rating): string
{
    $rating = max(0, min(5, $rating));
    if ($rating <= 0) {
        return '';
    }
    return '<span class="star-badge" title="Избранный трейдер · рейтинг ' . $rating . '/5">'
        . '★<span class="sb-n">' . $rating . '</span></span>';
}

/**
 * Полный ряд из 5 звёзд (★ заполненные + ☆ пустые) — для карточки трейдера.
 * Пустая строка при рейтинге 0.
 */
function rating_stars(int $rating): string
{
    $rating = max(0, min(5, $rating));
    if ($rating <= 0) {
        return '';
    }
    return '<span class="stars" title="Рейтинг ' . $rating . '/5">'
        . str_repeat('★', $rating) . str_repeat('☆', 5 - $rating) . '</span>';
}

// --- render_overrides_fields (из wallets.php) ----------------

/**
 * Индивидуальные настройки трейдера. Скалярные поля рендерятся из общего
 * каталога (lib/settings_schema.php) в режиме override: пустое поле =
 * наследовать глобальное, а само унаследованное значение показано прямо в
 * подсказке — сверять со второй вкладкой не нужно.
 *
 * Составные блоки (стоп-лосс, тейк-профит, сетка) в каталог не входят: это не
 * одно значение, а тройка «вкл + тип + значение», и переопределяются они
 * блоком целиком по чекбоксу.
 */
function render_overrides_fields(string $prefix, array $overrides, array $globalSettings = []): void
{
    if (empty($globalSettings)) {
        $globalSettings = GLOBAL_SETTINGS_DEFAULTS;
    }

    render_settings_expand_toggle();

    foreach (['size', 'entry', 'leverage', 'exec', 'notify'] as $group) {
        render_settings_group($group, $overrides, 'override', $prefix, $globalSettings);
    }

    // --- Составные блоки прямой торговли ---
    $sl   = is_array($overrides['stop_loss'] ?? null) ? $overrides['stop_loss'] : null;
    $tp   = is_array($overrides['take_profit'] ?? null) ? $overrides['take_profit'] : null;
    $grid = is_array($overrides['grid'] ?? null) ? $overrides['grid'] : null;

    $protTypes = [
        'pnl_pct'   => 'Процент от маржи (с учётом плеча)',
        'price_pct' => 'Процент движения цены',
        'price'     => 'Абсолютная цена',
    ];
    $protHints = [
        'pnl_pct'   => 'Значение в % от МАРЖИ. При плече 5 «50%» = движение цены всего на 10%.',
        'price_pct' => 'Значение в % ЦЕНЫ. «2» = цена ушла на 2% от входа, плечо не учитывается.',
        'price'     => 'Значение — конкретная цена монеты, например 61500.',
    ];
    ?>
    <div class="card">
        <div class="card-title">Защита позиции на бирже</div>
        <div class="card-sub">
            Работает только в режиме «Напрямую на биржу»: ордера ставятся на самой Hyperliquid
            и срабатывают без участия бота. В режиме вебхуков эти блоки игнорируются.
        </div>

        <?php foreach ([['sl', 'Стоп-лосс', 'закрыть в убыток', $sl, 50],
                        ['tp', 'Тейк-профит', 'закрыть в прибыль', $tp, 80]] as [$f, $title, $verb, $cfg, $defVal]): ?>
        <div class="set-field<?= $cfg !== null ? ' is-overridden' : '' ?>">
            <div class="set-head">
                <label><?= htmlspecialchars($title) ?></label>
                <?php if ($cfg !== null): ?><span class="set-ovr-flag">свой</span><?php endif; ?>
            </div>
            <label class="check set-toggle">
                <input type="checkbox" name="<?= $prefix . 'override_' . $f ?>" value="1" <?= $cfg !== null ? 'checked' : '' ?>>
                задать свой <?= htmlspecialchars($title) ?> для этого трейдера
            </label>
            <div class="row3">
                <div class="field">
                    <label>Состояние</label>
                    <select name="<?= $prefix . $f . '_enabled' ?>">
                        <option value="0" <?= $cfg && empty($cfg['enabled']) ? 'selected' : '' ?>>Выключен</option>
                        <option value="1" <?= $cfg && !empty($cfg['enabled']) ? 'selected' : '' ?>>Включён</option>
                    </select>
                </div>
                <div class="field">
                    <label>Считать от чего</label>
                    <select name="<?= $prefix . $f . '_type' ?>">
                        <?php foreach ($protTypes as $k => $lbl): ?>
                            <option value="<?= $k ?>" <?= ($cfg['type'] ?? 'pnl_pct') === $k ? 'selected' : '' ?>><?= htmlspecialchars($lbl) ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div class="field">
                    <label>Значение</label>
                    <input type="number" step="any" min="0" name="<?= $prefix . $f . '_value' ?>"
                           value="<?= htmlspecialchars((string) ($cfg['value'] ?? $defVal)) ?>">
                </div>
            </div>
            <div class="set-what">Когда сработает — <?= htmlspecialchars($verb) ?> позицию целиком.</div>
            <div class="set-example"><?= htmlspecialchars(implode(' ', $protHints)) ?></div>
        </div>
        <?php endforeach; ?>

        <div class="set-field<?= $grid !== null ? ' is-overridden' : '' ?>">
            <div class="set-head">
                <label>Сетка добора</label>
                <?php if ($grid !== null): ?><span class="set-ovr-flag">свой</span><?php endif; ?>
            </div>
            <label class="check set-toggle">
                <input type="checkbox" name="<?= $prefix ?>override_grid" value="1" <?= $grid !== null ? 'checked' : '' ?>>
                задать свою сетку для этого трейдера
            </label>
            <div class="row3">
                <div class="field">
                    <label>Состояние</label>
                    <select name="<?= $prefix ?>grid_enabled">
                        <option value="0" <?= $grid && empty($grid['enabled']) ? 'selected' : '' ?>>Выключена</option>
                        <option value="1" <?= $grid && !empty($grid['enabled']) ? 'selected' : '' ?>>Включена</option>
                    </select>
                </div>
                <div class="field">
                    <label>Доп. ордеров, шт</label>
                    <input type="number" step="1" min="0" name="<?= $prefix ?>grid_levels" value="<?= htmlspecialchars((string) ($grid['levels'] ?? 3)) ?>">
                </div>
                <div class="field">
                    <label>Шаг, % цены</label>
                    <input type="number" step="any" min="0" name="<?= $prefix ?>grid_step_pct" value="<?= htmlspecialchars((string) ($grid['step_pct'] ?? 1.0)) ?>">
                </div>
            </div>
            <div class="row2">
                <div class="field">
                    <label>Множитель размера, ×</label>
                    <input type="number" step="any" min="0" name="<?= $prefix ?>grid_size_factor" value="<?= htmlspecialchars((string) ($grid['size_factor'] ?? 1.0)) ?>">
                </div>
                <div class="field">
                    <label>Как растёт объём</label>
                    <select name="<?= $prefix ?>grid_distribution">
                        <option value="equal" <?= ($grid['distribution'] ?? 'equal') === 'equal' ? 'selected' : '' ?>>Равными долями</option>
                        <option value="multiplicative" <?= ($grid['distribution'] ?? 'equal') === 'multiplicative' ? 'selected' : '' ?>>Мартингейл — каждый следующий больше</option>
                    </select>
                </div>
            </div>
            <div class="set-what">Докупает позицию лимитными ордерами, если цена идёт против входа.</div>
            <div class="set-example">3 ордера с шагом 1% и множителем 1 → доборы на −1%, −2%, −3% от входа, каждый размером с основной.</div>
            <div class="set-warn">Мартингейл наращивает объём очень быстро: множитель 2 при 3 уровнях = ×2, ×4, ×8 от основного ордера.</div>
        </div>
    </div>
    <?php
}

// --- render_bulk_edit_fields (из wallets.php) ----------------

/**
 * Поля панели массового изменения настроек кошельков (bulk_wallets, op=edit).
 * Каждое поле активируется своим чекбоксом bulk_apply_<поле>; имена значений —
 * bulk_<поле>, чтобы разбираться общим parse_wallet_overrides (см.
 * parse_bulk_wallet_edits в forms.php). Пустое значение отмеченного поля =
 * вернуть кошелькам наследование глобальной настройки.
 */
function render_bulk_edit_fields(array $availableTags): void
{
    // Профильные поля кошелька — не settings-overrides, поэтому в каталоге их
    // нет и они описываются здесь.
    $profileFields = [
        ['status', 'Статус', 'select', ['WATCH' => 'WATCH', 'TEST' => 'TEST', 'ACTIVE' => 'ACTIVE', 'ARCHIVE' => 'ARCHIVE'],
            'Метка для твоей аналитики и фильтров — на работу бота не влияет.'],
        ['rating', 'Избранное (рейтинг)', 'select',
            ['0' => 'убрать из избранного', '1' => '★', '2' => '★★', '3' => '★★★', '4' => '★★★★', '5' => '★★★★★'],
            'Рейтинг больше нуля = трейдер в избранном; по нему фильтруются списки.'],
    ];

    echo '<div class="alert info" style="margin-bottom:14px">'
        . 'Применяется только к <b>отмеченным галочкой</b> полям и только к <b>выбранным</b> трейдерам. '
        . 'Пустое значение отмеченного поля = вернуть трейдеров к глобальной настройке. '
        . 'Стоп-лосс, тейк-профит и сетка задаются индивидуально в карточке трейдера.'
        . '</div>';

    echo '<div style="display:flex; gap:10px; flex-wrap:wrap; margin-bottom:14px">'
        . '<button type="button" class="btn ghost small" onclick="bulkEditCheckAll(true)">Отметить все поля</button>'
        . '<button type="button" class="btn ghost small" onclick="bulkEditCheckAll(false)">Снять все</button>'
        . '<span class="count" id="bulk-edit-count" style="margin-left:0"></span>'
        . '</div>';

    // --- Профиль ---
    echo '<div class="form-group-title">Профиль</div>';
    echo '<div class="row2">';
    foreach ($profileFields as [$name, $label, $type, $options, $hint]) {
        render_bulk_field($name, $label, $type, $options, '', $hint);
    }
    echo '</div>';

    // --- Остальное берётся из общего каталога настроек ---
    foreach (settings_schema() as $group) {
        $fields = array_filter($group['fields'], fn($f) => !empty($f['bulk']));
        if (empty($fields)) {
            continue;
        }
        echo '<div class="form-group-title">' . htmlspecialchars($group['title']) . '</div>';
        foreach (array_chunk(array_values($fields), 2) as $chunk) {
            echo '<div class="row2">';
            foreach ($chunk as $field) {
                render_bulk_field(
                    $field['key'],
                    settings_field_label($field['key']),
                    $field['type'],
                    $field['options'] ?? [],
                    $field['attrs'] ?? '',
                    $field['what'] ?? ''
                );
            }
            echo '</div>';
        }
    }

    if (!empty($availableTags)) {
        ?>
        <div class="form-group-title">Теги</div>
        <div class="row">
            <div class="field">
                <label>Что сделать с тегами</label>
                <select name="bulk_tags_mode">
                    <option value="">— не менять —</option>
                    <option value="add">добавить отмеченные</option>
                    <option value="remove">убрать отмеченные</option>
                    <option value="replace">заменить на отмеченные</option>
                </select>
            </div>
            <div class="field">
                <label>Теги</label>
                <div class="tag-checkbox-grid">
                    <?php foreach ($availableTags as $tag): ?>
                    <div class="tag-checkbox-item">
                        <input type="checkbox" name="bulk_tags[]" value="<?= htmlspecialchars($tag) ?>"
                            id="bulk-tag-<?= htmlspecialchars($tag) ?>">
                        <label for="bulk-tag-<?= htmlspecialchars($tag) ?>" style="font-size:11px; color:var(--text); text-transform:none">
                            <?= tag_pill($tag) ?>
                        </label>
                    </div>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
        <?php
    }
    ?>
    <script>
    function bulkEditCount() {
        var n = document.querySelectorAll('.bulk-apply:checked').length;
        var el = document.getElementById('bulk-edit-count');
        if (el) el.textContent = n ? 'изменяется полей: ' + n : 'ни одно поле не отмечено';
    }
    function bulkEditCheckAll(on) {
        document.querySelectorAll('.bulk-apply').forEach(function (cb) {
            cb.checked = on;
            var t = document.getElementById(cb.dataset.target);
            if (t) t.disabled = !on;
        });
        bulkEditCount();
    }
    document.addEventListener('DOMContentLoaded', bulkEditCount);
    </script>
    <?php
}

/**
 * Одно поле панели массового изменения: чекбокс «применять» + сам ввод.
 * Имена — bulk_apply_<ключ> / bulk_<ключ>, чтобы разбираться общим
 * parse_bulk_wallet_edits (forms.php).
 */
function render_bulk_field(string $name, string $label, string $type, array $options, string $attrs, string $hint): void
{
    $inputId = 'bulk_' . $name;
    $applyId = 'bulk_apply_' . $name;
    // symbols/leverage_map в bulk вводятся обычным текстом — их чекбокс
    // «применять» служит и признаком override (см. parse_bulk_wallet_edits).
    $isSelect = $type === 'select';
    $inputType = $type === 'number' ? 'number' : 'text';
    ?>
    <div class="field">
        <div class="checkbox-row" style="margin-bottom:6px;">
            <input type="checkbox" class="bulk-apply" name="<?= $applyId ?>" id="<?= $applyId ?>" value="1" data-target="<?= $inputId ?>"
                onchange="document.getElementById('<?= $inputId ?>').disabled = !this.checked; if (window.bulkEditCount) bulkEditCount();">
            <label for="<?= $applyId ?>" style="margin:0; text-transform:none; font-size:12px;"><?= htmlspecialchars($label) ?></label>
        </div>
        <?php if ($isSelect): ?>
        <select name="<?= $inputId ?>" id="<?= $inputId ?>" disabled>
            <option value="">— вернуть к глобальному —</option>
            <?php foreach ($options as $v => $lbl): ?>
            <option value="<?= htmlspecialchars((string) $v) ?>"><?= htmlspecialchars($lbl) ?></option>
            <?php endforeach; ?>
        </select>
        <?php else: ?>
        <input type="<?= $inputType ?>" <?= $attrs ?> name="<?= $inputId ?>" id="<?= $inputId ?>"
            <?= strpos($attrs, 'placeholder=') === false ? 'placeholder="пусто = глобальное"' : '' ?> disabled>
        <?php endif; ?>
        <?php if ($hint !== ''): ?><div class="hint"><?= htmlspecialchars($hint) ?></div><?php endif; ?>
    </div>
    <?php
}

// --- render_webhooks_form (из pools.php) ---------------------
function render_webhooks_form(array $webhooks, string $prefix): void
{
    // Дополняем до 3 слотов
    while (count($webhooks) < 3) {
        $webhooks[] = ['service' => '', 'enabled' => false];
    }

    foreach ($webhooks as $i => $wh) {
        $service = $wh['service'] ?? '';
        $p = $prefix . $i . '_';
        ?>
        <div class="webhook-slot" style="background:var(--bg); border:1px solid var(--border); border-radius:4px; padding:12px; margin-bottom:10px;">
            <div class="row">
                <div class="field">
                    <label>Сервис #<?= $i + 1 ?></label>
                    <select name="<?= $p ?>service" onchange="var v=this.value; this.closest('.webhook-slot').querySelectorAll('.wh-fields > div').forEach(function(el){ el.style.display = el.className === 'wh-' + v ? '' : 'none'; })">
                        <option value="">— не используется —</option>
                        <option value="katoshi"  <?= $service === 'katoshi'  ? 'selected' : '' ?>>Katoshi</option>
                        <option value="altrady"  <?= $service === 'altrady'  ? 'selected' : '' ?>>Altrady</option>
                        <option value="custom"   <?= $service === 'custom'   ? 'selected' : '' ?>>Custom</option>
                        <option value="telegram" <?= $service === 'telegram' ? 'selected' : '' ?>>Telegram (уведомления)</option>
                    </select>
                </div>
                <div class="field" style="padding-top:22px;">
                    <div class="checkbox-row">
                        <input type="checkbox" name="<?= $p ?>enabled" value="1" <?= !empty($wh['enabled']) ? 'checked' : '' ?> id="whe-<?= $p ?>">
                        <label for="whe-<?= $p ?>" style="margin:0; text-transform:none; font-size:12px;">Включён</label>
                    </div>
                </div>
            </div>
            <div class="wh-fields wh-<?= $service ?>">
                <!-- Katoshi -->
                <div class="wh-katoshi" style="<?= $service !== 'katoshi' ? 'display:none' : '' ?>">
                    <div class="row">
                        <div class="field">
                            <label>API Key</label>
                            <input type="text" name="<?= $p ?>api_key" value="<?= htmlspecialchars($wh['api_key'] ?? '') ?>" placeholder="katoshi API key">
                        </div>
                        <div class="field">
                            <label>Bot ID</label>
                            <input type="number" name="<?= $p ?>bot_id" value="<?= htmlspecialchars($wh['bot_id'] ?? '') ?>" placeholder="12345">
                            <div class="hint">Bot ID из настроек бота в katoshi.ai</div>
                        </div>
                    </div>
                </div>
                <!-- Altrady -->
                <div class="wh-altrady" style="<?= $service !== 'altrady' ? 'display:none' : '' ?>">
                    <div class="row">
                        <div class="field">
                            <label>API Key</label>
                            <input type="text" name="<?= $p ?>api_key" value="<?= htmlspecialchars($wh['api_key'] ?? '') ?>">
                        </div>
                        <div class="field">
                            <label>API Secret</label>
                            <input type="password" name="<?= $p ?>api_secret" value="<?= htmlspecialchars($wh['api_secret'] ?? '') ?>">
                        </div>
                    </div>
                    <div class="row">
                        <div class="field">
                            <label>Exchange code</label>
                            <input type="text" name="<?= $p ?>exchange" value="<?= htmlspecialchars($wh['exchange'] ?? 'HYPE') ?>" placeholder="HYPE">
                            <div class="hint">Код биржи в Altrady для Hyperliquid</div>
                        </div>
                        <div class="field">
                            <label>Symbol prefix</label>
                            <input type="text" name="<?= $p ?>symbol_prefix" value="<?= htmlspecialchars($wh['symbol_prefix'] ?? 'HYPE_USDT_') ?>" placeholder="HYPE_USDT_">
                            <div class="hint">Префикс перед тикером: HYPE_USDT_BTC</div>
                        </div>
                    </div>
                </div>
                <!-- Telegram -->
                <div class="wh-telegram" style="<?= $service !== 'telegram' ? 'display:none' : '' ?>">
                    <div class="row">
                        <div class="field">
                            <label>Bot token</label>
                            <input type="password" name="<?= $p ?>bot_token" value="<?= htmlspecialchars($wh['bot_token'] ?? '') ?>" placeholder="123456:ABC-DEF…">
                            <div class="hint">Токен бота из @BotFather</div>
                        </div>
                        <div class="field">
                            <label>Chat ID</label>
                            <input type="text" name="<?= $p ?>chat_id" value="<?= htmlspecialchars($wh['chat_id'] ?? '') ?>" placeholder="-1001234567890">
                            <div class="hint">ID чата/канала или свой user id (@userinfobot)</div>
                        </div>
                    </div>
                </div>
                <!-- Custom -->
                <div class="wh-custom" style="<?= $service !== 'custom' ? 'display:none' : '' ?>">
                    <div class="row">
                        <div class="field">
                            <label>URL</label>
                            <input type="text" name="<?= $p ?>url" value="<?= htmlspecialchars($wh['url'] ?? '') ?>" placeholder="https://your-service.com/webhook">
                        </div>
                        <div class="field">
                            <label>Метод</label>
                            <select name="<?= $p ?>method">
                                <option value="POST" <?= ($wh['method'] ?? 'POST') === 'POST' ? 'selected' : '' ?>>POST</option>
                                <option value="GET"  <?= ($wh['method'] ?? '') === 'GET'  ? 'selected' : '' ?>>GET</option>
                            </select>
                        </div>
                    </div>
                    <div class="field">
                        <label>Заголовки (Key: Value, по одному в строке)</label>
                        <textarea name="<?= $p ?>headers_raw" rows="2" style="width:100%; background:var(--bg); border:1px solid var(--border); color:var(--text); padding:6px; border-radius:4px; font-family:var(--mono); font-size:11px; resize:vertical;"><?php
                            $headersRaw = [];
                            foreach ($wh['headers'] ?? [] as $k => $v) $headersRaw[] = $k . ': ' . $v;
                            echo htmlspecialchars(implode("\n", $headersRaw));
                        ?></textarea>
                    </div>
                    <div class="field">
                        <label>JSON шаблон (плейсхолдеры: {{action}}, {{symbol}}, {{side}}, {{size_usd}}, {{price}}, {{is_buy}}, {{leverage}}, {{timestamp}})</label>
                        <textarea name="<?= $p ?>body_template" rows="4" style="width:100%; background:var(--bg); border:1px solid var(--border); color:var(--text); padding:6px; border-radius:4px; font-family:var(--mono); font-size:11px; resize:vertical;"><?= htmlspecialchars($wh['body_template'] ?? '') ?></textarea>
                        <div class="hint">Оставьте пустым для стандартного JSON с основными полями.</div>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }
}
