<?php
// =============================================================
// BULK — массовые операции с трейдерами
// =============================================================
// Вкладки: Операции (выбор + enable/disable/delete/edit) /
// Массовый импорт (+ сброс state всех) / Теги.

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/auth.php';

require_auth();

if (isset($_GET['logout'])) {
    logout();
    header('Location: login.php');
    exit;
}

require_once __DIR__ . '/data.php';
require_once __DIR__ . '/lib/forms.php';
require_once __DIR__ . '/lib/render.php';
require_once __DIR__ . '/lib/wallets_handler.php';
require_once __DIR__ . '/lib/settings_handler.php';
require_once __DIR__ . '/lib/traders_xlsx.php';
require_once __DIR__ . '/lib/layout.php';

$message = '';
$messageType = '';

$config = load_wallets_config();

// Экспорт настроек всех трейдеров в XLSX (скачивание файла, без HTML)
if (($_GET['export'] ?? '') === 'traders_xlsx') {
    $file = traders_xlsx_export_file($config);
    if ($file === null) {
        http_response_code(500);
        die('Не удалось сформировать XLSX');
    }
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment; filename="traders_settings_' . date('Y-m-d') . '.xlsx"');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    @unlink($file);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_verify();
    $action = $_POST['action'] ?? '';

    // reset_all живёт в settings_handler (дублируется на вкладке «Импорт»)
    if ($action === 'reset_all') {
        $res = dashboard_handle_settings_post($_POST, $config);
    } elseif ($action === 'import_xlsx') {
        $res = dashboard_handle_traders_xlsx_import($_FILES, $_POST, $config);
    } else {
        $res = dashboard_handle_wallets_post($_POST, $config);
    }
    $message     = $res['message'];
    $messageType = $res['messageType'];
    $config = load_wallets_config();
}

$wallets        = $config['wallets'];
$globalSettings = $config['global_settings'];
$availableTags  = $config['available_tags'] ?? [];

// Компактная сводка для таблицы выбора
$walletScores = [];
foreach ($wallets as $w) {
    $wTrades = storage_get_closed_trades($w['id']);
    $walletScores[$w['id']] = [
        'score'  => calculate_wallet_score($wTrades),
        'netPnl' => calculate_summary($wTrades)['total_net_pnl'],
        'trades' => count($wTrades),
    ];
}

layout_header(['title' => 'Массовые операции', 'page' => 'bulk']);
layout_flash($message, $messageType);
?>

<div class="tabs">
    <button class="tab-btn active" data-tab="tp-ops" data-hash="ops">Операции с трейдерами</button>
    <button class="tab-btn" data-tab="tp-import" data-hash="import">Массовый импорт</button>
    <button class="tab-btn" data-tab="tp-xlsx" data-hash="xlsx">Экспорт / Импорт XLSX</button>
    <button class="tab-btn" data-tab="tp-tags" data-hash="tags">Теги</button>
</div>

<!-- ОПЕРАЦИИ -->
<div class="tab-panel active" id="tp-ops">
    <form method="POST" id="bulk-form">
        <?= csrf_field() ?>
        <input type="hidden" name="action" value="bulk_wallets">

        <div class="card" style="padding:13px 14px">
            <div class="search-box" style="margin-bottom:10px">
                <input type="text" id="f-search" placeholder="Поиск по названию или адресу…" autocomplete="off">
            </div>
            <div class="filter-grid">
                <div class="field">
                    <label>Статус</label>
                    <select id="f-status">
                        <option value="">Любой</option>
                        <?php foreach (['WATCH', 'TEST', 'ACTIVE', 'ARCHIVE'] as $st): ?>
                        <option><?= $st ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div class="field">
                    <label>Избранное</label>
                    <select id="f-star">
                        <option value="">Все</option>
                        <option value="1">Только избранные ★</option>
                        <option value="0">Только без звезды</option>
                    </select>
                </div>
                <div class="field">
                    <label>Копирование</label>
                    <select id="f-enabled">
                        <option value="">Все</option>
                        <option value="1">Включено</option>
                        <option value="0">Выключено</option>
                    </select>
                </div>
                <div class="field">
                    <label>Тег</label>
                    <select id="f-tag">
                        <option value="">Любой</option>
                        <?php foreach ($availableTags as $t): ?>
                        <option value="<?= htmlspecialchars($t) ?>"><?= htmlspecialchars($t) ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div class="field">
                    <label>Настройки</label>
                    <select id="f-ovr">
                        <option value="">Любые</option>
                        <option value="1">Есть свои</option>
                        <option value="0">Только глобальные</option>
                    </select>
                </div>
                <div class="field">
                    <label>Есть сделки</label>
                    <select id="f-trades">
                        <option value="">Любые</option>
                        <option value="1">Торговал</option>
                        <option value="0">Ни одной сделки</option>
                    </select>
                </div>
            </div>
            <div class="toolbar" style="margin:0">
                <label class="check"><input type="checkbox" id="sel-all"> выбрать всех видимых</label>
                <button type="button" class="btn ghost small" onclick="invertSel()">инвертировать</button>
                <button type="button" class="btn ghost small" onclick="resetFilters()">сбросить фильтры</button>
                <span class="count" id="f-count"></span>
                <span class="count" id="sel-count">выбрано: 0</span>
            </div>
        </div>

        <div class="table-wrap">
            <table class="stack" id="ops-table">
                <thead><tr><th style="width:36px" class="nosort"></th><th>Трейдер</th><th>Статус</th><th class="num">Score</th><th class="num">Net PnL</th><th class="num">Сделки</th><th>Вкл</th></tr></thead>
                <tbody>
                    <?php if (empty($wallets)): ?>
                    <tr><td colspan="7"><div class="empty">Пока нет трейдеров — добавьте на вкладке «Массовый импорт» или на странице Трейдеры</div></td></tr>
                    <?php else: ?>
                    <?php foreach ($wallets as $w): ?>
                    <?php
                        $wid = $w['id'];
                        $st  = $w['status'] ?? 'WATCH';
                        $sc  = $walletScores[$wid]['score'];
                        $pnl = $walletScores[$wid]['netPnl'];
                        $rat = (int) ($w['rating'] ?? 0);
                        $ovN = count(array_filter($w['settings'] ?? [], fn($v) => $v !== null));
                        $trN = $walletScores[$wid]['trades'];
                    ?>
                    <tr data-status="<?= htmlspecialchars($st) ?>"
                        data-star="<?= $rat > 0 ? '1' : '0' ?>"
                        data-enabled="<?= !empty($w['enabled']) ? '1' : '0' ?>"
                        data-tags="<?= htmlspecialchars(implode(',', $w['tags'] ?? [])) ?>"
                        data-ovr="<?= $ovN > 0 ? '1' : '0' ?>"
                        data-trades="<?= $trN > 0 ? '1' : '0' ?>"
                        data-search="<?= htmlspecialchars(mb_strtolower(($w['label'] ?? '') . ' ' . ($w['address'] ?? ''))) ?>">
                        <td class="nosort" style="width:36px" data-label="Выбор"><input type="checkbox" class="sel" name="wallet_ids[]" value="<?= htmlspecialchars($wid) ?>"></td>
                        <td class="stack-main">
                            <b><?= htmlspecialchars($w['label'] ?? $wid) ?></b>
                            <?= rating_badge($rat) ?>
                            <?php if ($ovN > 0): ?><span class="badge mode" title="Своих настроек: <?= $ovN ?>"><?= $ovN ?> свои</span><?php endif; ?>
                            <?= hyperdash_link($w['address'] ?? '') ?>
                            <span class="addr"><?= htmlspecialchars(substr($w['address'] ?? '', 0, 6)) ?>…<?= htmlspecialchars(substr($w['address'] ?? '', -4)) ?></span>
                            <?php foreach ($w['tags'] ?? [] as $tag) echo ' ' . tag_pill($tag); ?>
                        </td>
                        <td data-label="Статус"><span class="badge st-<?= htmlspecialchars($st) ?>"><?= htmlspecialchars($st) ?></span></td>
                        <td class="num" data-label="Score">
                            <?php if ($sc['score'] !== null): ?>
                                <span class="badge grade-<?= $sc['grade'] ?>"><?= $sc['grade'] ?> <?= $sc['score'] ?></span>
                            <?php else: ?>
                                <span class="dim">—</span>
                            <?php endif; ?>
                        </td>
                        <td class="num <?= pnl_class($pnl) ?>" data-label="Net PnL"><?= fmt_usd($pnl) ?></td>
                        <td class="num" data-label="Сделки"><?= $walletScores[$wid]['trades'] ?></td>
                        <td data-label="Вкл"><span class="badge <?= !empty($w['enabled']) ? 'on' : 'off' ?>"><?= !empty($w['enabled']) ? 'ВКЛ' : 'ВЫКЛ' ?></span></td>
                    </tr>
                    <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>
        </div>

        <!-- Плавающая панель действий -->
        <div class="bulk-actionbar" id="actionbar" style="display:none">
            <span class="cnt" id="ab-count"></span>
            <button type="submit" name="bulk_op" value="enable" class="btn small secondary">▶ Включить</button>
            <button type="submit" name="bulk_op" value="disable" class="btn small secondary">⏸ Приостановить</button>
            <button type="button" class="btn small secondary" onclick="toggleEditPanel()">✎ Изменить настройки</button>
            <button type="submit" name="bulk_op" value="delete" class="btn small danger"
                onclick="return confirm('Удалить выбранных трейдеров и весь их state? Это нельзя отменить.')">Удалить</button>
            <button type="button" class="btn small ghost" onclick="clearSel()" style="margin-left:auto">Сбросить</button>
        </div>

        <!-- Панель массового изменения настроек -->
        <div class="card" id="edit-panel" style="display:none">
            <div class="card-title">Массовое изменение настроек</div>
            <?php render_bulk_edit_fields($availableTags); ?>
            <button type="submit" name="bulk_op" value="edit" class="btn"
                onclick="return confirm('Применить отмеченные изменения ко всем выбранным трейдерам?')">Применить к выбранным</button>
        </div>
    </form>
</div>

<!-- ИМПОРТ -->
<div class="tab-panel" id="tp-import">
    <div class="card">
        <div class="card-title">Массовый импорт трейдеров</div>
        <form method="POST">
            <?= csrf_field() ?>
            <input type="hidden" name="action" value="bulk_import">
            <div class="field">
                <label>Адреса — по одному на строку</label>
                <div class="hint" style="margin-bottom:8px">Форматы: <code>0x1234…abcd</code> или <code>0x1234…abcd, Название трейдера</code>. Дубли уже добавленных адресов пропускаются.</div>
                <textarea name="addresses" rows="8" placeholder="0xabc…001&#10;0xabc…002, Trader Alpha&#10;0xabc…003, Trader Beta" required></textarea>
            </div>
            <label class="check" style="margin-bottom:14px"><input type="checkbox" name="import_enabled" value="1" checked> сразу включить копирование для всех импортированных</label>
            <div><button class="btn" type="submit">Импортировать</button></div>
        </form>
    </div>
    <div class="card danger-zone">
        <div class="card-title">Сброс state всех трейдеров</div>
        <div class="alert danger">Очищает seen/positions для <b>каждого</b> трейдера — бот встанет «на текущий момент», открытые позиции сбросятся. Точечный сброс — в карточке трейдера. Дублируется в Настройках → Система.</div>
        <form method="POST" onsubmit="return confirm('Точно сбросить state ВСЕХ трейдеров (<?= count($wallets) ?> шт.)? Открытые позиции и история дедупликации будут удалены.')">
            <?= csrf_field() ?>
            <input type="hidden" name="action" value="reset_all">
            <div style="display:flex; gap:14px; flex-wrap:wrap; margin-bottom:14px">
                <label class="check"><input type="checkbox" name="clear_logs" value="1"> очистить bot.log</label>
                <label class="check" style="color:var(--neg-text)"><input type="checkbox" name="clear_sqlite" value="1"> удалить сделки и сигналы из БД (необратимо)</label>
            </div>
            <button class="btn danger" type="submit">Сбросить state всех трейдеров (<?= count($wallets) ?>)</button>
        </form>
    </div>
</div>

<!-- ЭКСПОРТ / ИМПОРТ XLSX -->
<div class="tab-panel" id="tp-xlsx">
    <div class="card">
        <div class="card-title">Экспорт настроек всех трейдеров</div>
        <div class="card-sub">Один лист: строка = трейдер, колонки = профиль (id, label, address, статус, теги…) + все override-настройки из карточки трейдера.</div>
        <div class="hint" style="margin-bottom:12px">Пустая ячейка настройки = наследовать глобальное значение. Сложные поля: <code>allowed_symbols</code> — список через запятую; <code>symbol_leverage</code> — <code>BTC=5, ETH=2</code>; <code>stop_loss</code>/<code>take_profit</code>/<code>grid</code> — JSON.</div>
        <a class="btn" href="bulk.php?export=traders_xlsx">⬇ Скачать XLSX (<?= count($wallets) ?> трейдеров)</a>
    </div>
    <div class="card">
        <div class="card-title">Импорт настроек из XLSX</div>
        <div class="card-sub">Обычный сценарий: скачать экспорт → поправить в Excel → загрузить обратно.</div>
        <div class="hint" style="margin-bottom:12px">
            Строки сопоставляются по <code>id</code>, затем по <code>address</code>. Обновляются только колонки, присутствующие в файле
            (лишние можно удалить); настройки, которых нет в колонках, не трогаются. Пустая ячейка настройки
            сбрасывает override — трейдер вернётся к глобальному значению. Строка с неизвестным id/адресом добавляет
            трейдера (id из файла сохраняется — экспорт можно импортировать в чистую установку как бэкап).
        </div>
        <form method="POST" enctype="multipart/form-data">
            <?= csrf_field() ?>
            <input type="hidden" name="action" value="import_xlsx">
            <div class="field">
                <label>Файл .xlsx</label>
                <input type="file" name="xlsx_file" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" required>
            </div>
            <label class="check" style="margin-bottom:14px"><input type="checkbox" name="xlsx_create_new" value="1" checked> создавать новых трейдеров из строк с неизвестным адресом</label>
            <div><button class="btn" type="submit" onclick="return confirm('Применить настройки из файла ко всем совпавшим трейдерам?')">Импортировать настройки</button></div>
        </form>
    </div>
</div>

<!-- ТЕГИ -->
<div class="tab-panel" id="tp-tags">
    <div class="card">
        <div class="card-title">Управление тегами</div>
        <div class="card-sub">Теги доступны в фильтрах, карточках трейдеров и массовых изменениях.</div>
        <form method="POST">
            <?= csrf_field() ?>
            <input type="hidden" name="action" value="manage_tags">
            <div class="field">
                <label>Доступные теги — по одному на строку или через запятую</label>
                <textarea name="tags_list" rows="5" placeholder="btc-only&#10;scalper&#10;swing&#10;degen&#10;low-risk"><?= htmlspecialchars(implode("\n", $availableTags)) ?></textarea>
            </div>
            <div class="field" style="font-size:12px; color:var(--text-dim)">
                Текущие теги:
                <?php if (empty($availableTags)): ?>нет<?php else: ?>
                    <span style="display:inline-flex; gap:6px; flex-wrap:wrap; vertical-align:middle">
                    <?php foreach ($availableTags as $t) echo tag_pill($t); ?>
                    </span>
                <?php endif; ?>
            </div>
            <button class="btn" type="submit">Сохранить теги</button>
        </form>
    </div>
</div>

<script>
(function () {
    UI.initTabs();

    const selAll = document.getElementById('sel-all');
    const boxes = () => [...document.querySelectorAll('#ops-table .sel')];
    const rows  = () => [...document.querySelectorAll('#ops-table tbody tr[data-status]')];

    // Фильтр: id элемента управления -> как сопоставить строку.
    // Пустое значение фильтра = «не фильтровать по этому признаку».
    const FILTERS = [
        ['f-status',  (r, v) => r.dataset.status  === v],
        ['f-star',    (r, v) => r.dataset.star    === v],
        ['f-enabled', (r, v) => r.dataset.enabled === v],
        ['f-ovr',     (r, v) => r.dataset.ovr     === v],
        ['f-trades',  (r, v) => r.dataset.trades  === v],
        ['f-tag',     (r, v) => (r.dataset.tags || '').split(',').includes(v)],
        ['f-search',  (r, v) => (r.dataset.search || '').includes(v.toLowerCase().trim())],
    ];

    function visibleRows() {
        return rows().filter(r => r.style.display !== 'none');
    }

    function applyFilters() {
        rows().forEach(r => {
            const shown = FILTERS.every(([id, match]) => {
                const el = document.getElementById(id);
                const v = el ? el.value : '';
                return v === '' || match(r, v);
            });
            r.style.display = shown ? '' : 'none';
            // Скрытая строка не должна уехать в массовую операцию невидимой для
            // глаза: снимаем выбор при уходе из фильтра.
            if (!shown) {
                const cb = r.querySelector('.sel');
                if (cb) cb.checked = false;
            }
        });
        const shownCount = visibleRows().length;
        const total = rows().length;
        const el = document.getElementById('f-count');
        if (el) el.textContent = shownCount === total
            ? ('трейдеров: ' + total)
            : ('показано: ' + shownCount + ' из ' + total);
        updateBar();
    }

    function updateBar() {
        const checked = boxes().filter(cb => cb.checked);
        document.getElementById('sel-count').textContent = 'выбрано: ' + checked.length;
        document.getElementById('ab-count').textContent = checked.length + ' выбрано';
        document.getElementById('actionbar').style.display = checked.length ? 'flex' : 'none';
        if (!checked.length) document.getElementById('edit-panel').style.display = 'none';
        const vis = visibleRows().length;
        if (selAll) selAll.checked = vis > 0 && checked.length === vis;
    }

    boxes().forEach(cb => cb.addEventListener('change', updateBar));

    if (selAll) selAll.addEventListener('change', () => {
        const on = selAll.checked;
        boxes().forEach(cb => { cb.checked = false; });
        if (on) visibleRows().forEach(r => { const cb = r.querySelector('.sel'); if (cb) cb.checked = true; });
        updateBar();
    });

    FILTERS.forEach(([id]) => {
        const el = document.getElementById(id);
        if (!el) return;
        el.addEventListener(el.tagName === 'SELECT' ? 'change' : 'input', applyFilters);
    });

    window.invertSel = function () {
        visibleRows().forEach(r => { const cb = r.querySelector('.sel'); if (cb) cb.checked = !cb.checked; });
        updateBar();
    };
    window.resetFilters = function () {
        FILTERS.forEach(([id]) => { const el = document.getElementById(id); if (el) el.value = ''; });
        applyFilters();
    };
    window.clearSel = function () { boxes().forEach(cb => cb.checked = false); updateBar(); };
    window.toggleEditPanel = function () {
        const p = document.getElementById('edit-panel');
        p.style.display = p.style.display === 'none' ? '' : 'none';
        if (p.style.display !== 'none') p.scrollIntoView({ behavior: 'smooth', block: 'start' });
    };

    applyFilters();   // сам вызывает updateBar()
})();
</script>

<?php layout_footer(); ?>
