<?php
// =============================================================
// DASHBOARD — обзор «как дела прямо сейчас»
// =============================================================
// KPI, PnL по периодам, топ/аутсайдеры трейдеров, мини-список
// открытых позиций, лента активности. Полные таблицы живут на
// своих страницах: traders / positions / journal / analytics.

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

require_auth();

// bot_log используется в collector/position_tracker, но dashboard
// не должен писать в основной лог бота — глушим вывод.
if (!function_exists('bot_log')) {
    function bot_log(string $message): void {}
}

require_once __DIR__ . '/../collector.php';
require_once __DIR__ . '/../price_fetcher.php';
require_once __DIR__ . '/../balance_tracker.php';
require_once __DIR__ . '/../position_tracker.php';
require_once __DIR__ . '/data.php';
require_once __DIR__ . '/lib/render.php';
require_once __DIR__ . '/lib/layout.php';

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

$walletsConfig  = load_wallets_config();
$wallets        = $walletsConfig['wallets'];
$globalSettings = $walletsConfig['global_settings'];

$walletAddressById = array_column($wallets, 'address', 'id');
$walletRatingById  = array_column($wallets, 'rating', 'id');

// Фильтр по трейдеру: ?wallet=w1, или "all" / отсутствует -> все
$selectedWalletId = $_GET['wallet'] ?? 'all';
if ($selectedWalletId !== 'all' && !isset($walletAddressById[$selectedWalletId])) {
    $selectedWalletId = 'all';
}
$filterWalletId = ($selectedWalletId === 'all') ? null : $selectedWalletId;

// Фильтр по периоду: ?period=7d|30d|90d|all
$periodOptions  = ['7d' => '7д', '30d' => '30д', '90d' => '90д', 'all' => 'Всё время'];
$selectedPeriod = $_GET['period'] ?? 'all';
if (!isset($periodOptions[$selectedPeriod])) {
    $selectedPeriod = 'all';
}
$periodFromTs = period_from_ts($selectedPeriod);

/**
 * Query string с сохранением текущих фильтров (дефолты не пишем в URL).
 */
function dash_qs(array $overrides = []): string
{
    global $selectedWalletId, $selectedPeriod;
    $params = array_merge(['wallet' => $selectedWalletId, 'period' => $selectedPeriod], $overrides);
    $params = array_filter($params, fn($v) => $v !== null && $v !== '' && $v !== 'all');
    $qs = http_build_query($params);
    return $qs === '' ? '' : '?' . $qs;
}

// --- Данные ---------------------------------------------------
$closedTrades = filter_trades_since(load_closed_trades($filterWalletId), $periodFromTs);
$summary      = calculate_summary($closedTrades);
$openPositions = load_open_positions($wallets, $filterWalletId);
$unrealized   = calculate_unrealized_pnl($openPositions);
$watchingPositions = load_watching_positions($wallets, $filterWalletId);
$signals      = filter_signals_since(load_signals($filterWalletId), $periodFromTs);
$walletsOverview = build_wallets_overview($wallets, $globalSettings, $periodFromTs);

$byDay   = group_pnl_by_period($closedTrades, 'day');
$byWeek  = group_pnl_by_period($closedTrades, 'week');
$byMonth = group_pnl_by_period($closedTrades, 'month');

$unrealizedTotal = array_sum(array_map(fn($p) => (float) ($p['pnl_usd'] ?? 0), $unrealized));
$posSizeTotal    = array_sum(array_map(fn($p) => (float) ($p['size_usd'] ?? 0), $unrealized));
$enabledCount    = count(array_filter($wallets, fn($w) => !empty($w['enabled'])));
$signalsToday    = count(array_filter(
    load_signals($filterWalletId),
    fn($s) => date('Y-m-d', strtotime($s['datetime'] ?? '')) === date('Y-m-d')
));

// Спарклайн Net PnL для KPI — дневная серия за 14 дней (без фильтра периода:
// это «пульс» последних двух недель)
$kpiSpark = daily_pnl_series(load_closed_trades($filterWalletId), 14);

// Герой: капитал — сумма виртуальных балансов (или баланс выбранного трейдера)
$heroRows = $filterWalletId === null
    ? $walletsOverview
    : array_values(array_filter($walletsOverview, fn($r) => $r['wallet_id'] === $filterWalletId));
$totalCapital = array_sum(array_map(fn($r) => (float) ($r['balance'] ?? 0), $heroRows));

// Топ трейдеров: 3 лучших + 2 худших по Net PnL за выбранный период.
// Спарклайны — по полной 14-дневной истории каждого.
$tradersWithHistory = array_values(array_filter($walletsOverview, fn($r) => $r['trades_count'] > 0));
usort($tradersWithHistory, fn($a, $b) => $b['net_pnl'] <=> $a['net_pnl']);
$topTraders    = array_slice($tradersWithHistory, 0, 3);
$topIds        = array_column($topTraders, 'wallet_id');
$bottomTraders = array_values(array_filter(
    array_slice($tradersWithHistory, -2),
    fn($r) => !in_array($r['wallet_id'], $topIds, true)
));
$sparkByWallet = [];
foreach (array_merge($topTraders, $bottomTraders) as $row) {
    $sparkByWallet[$row['wallet_id']] = daily_pnl_series(load_closed_trades($row['wallet_id']), 14)['usd'];
}

// Лента активности: 5 последних сделок + 4 последних сигнала, слитые по времени
$recentTrades  = array_slice(array_reverse($closedTrades), 0, 5);
$recentSignals = array_slice(array_reverse($signals), 0, 4);
$feed = [];
foreach ($recentTrades as $t) {
    $feed[] = ['at' => $t['close_time'] ?? '', 'wid' => $t['wallet_id'] ?? '', 'wlabel' => $t['wallet_label'] ?? '', 'type' => 'trade', 'data' => $t];
}
foreach ($recentSignals as $s) {
    $feed[] = ['at' => $s['datetime'] ?? '', 'wid' => $s['wallet_id'] ?? '', 'wlabel' => $s['wallet_label'] ?? '', 'type' => 'signal', 'data' => $s];
}
usort($feed, fn($a, $b) => strcmp($b['at'], $a['at']));
$feed = array_slice($feed, 0, 8);

layout_header(['title' => 'Обзор', 'page' => 'dashboard']);
?>

<!-- Герой: капитал портфеля -->
<section class="hero">
    <div style="display:flex; justify-content:space-between; align-items:flex-start; gap:10px">
        <div>
            <div class="h-label">Капитал портфеля<?= $filterWalletId !== null ? ' · трейдер' : '' ?></div>
            <div class="h-value"><?= number_format(floor($totalCapital), 0, '.', ' ') ?><small>.<?= substr(number_format($totalCapital, 2), -2) ?> $</small></div>
        </div>
    </div>
    <div class="h-chips">
        <span class="chip <?= ($summary['total_net_pnl'] ?? 0) >= 0 ? 'up' : 'down' ?>" style="cursor:default">Net <?= fmt_usd($summary['total_net_pnl']) ?></span>
        <span class="chip <?= $unrealizedTotal >= 0 ? 'up' : 'down' ?>" style="cursor:default">uPnL <?= fmt_usd($unrealizedTotal) ?></span>
        <span class="chip info" style="cursor:default">в позициях <?= number_format($posSizeTotal, 2) ?> $</span>
    </div>
    <div class="h-chart" id="hero-chart"></div>
</section>

<div class="toolbar">
    <div class="seg">
        <?php foreach ($periodOptions as $pKey => $pLabel): ?>
        <a href="index.php<?= dash_qs(['period' => $pKey]) ?>" class="<?= $selectedPeriod === $pKey ? 'active' : '' ?>"><?= $pLabel ?></a>
        <?php endforeach; ?>
    </div>
    <form method="GET" style="display:inline-flex; align-items:center; gap:8px">
        <?php if ($selectedPeriod !== 'all'): ?>
        <input type="hidden" name="period" value="<?= htmlspecialchars($selectedPeriod) ?>">
        <?php endif; ?>
        <select name="wallet" onchange="this.form.submit()" style="width:auto">
            <option value="all">Все трейдеры (<?= count($wallets) ?>)</option>
            <?php foreach ($wallets as $w): ?>
            <option value="<?= htmlspecialchars($w['id']) ?>" <?= $selectedWalletId === $w['id'] ? 'selected' : '' ?>>
                <?= htmlspecialchars($w['label'] ?? $w['id']) ?><?= empty($w['enabled']) ? ' (выкл)' : '' ?>
            </option>
            <?php endforeach; ?>
        </select>
        <?php if ($filterWalletId !== null): ?>
            <?= hyperdash_link($walletAddressById[$filterWalletId] ?? '') ?>
            <a href="trader.php?id=<?= urlencode($filterWalletId) ?>" style="font-size:12px; white-space:nowrap">Карточка →</a>
        <?php endif; ?>
    </form>
    <span class="count">копируются <b style="color:var(--text)"><?= $enabledCount ?> / <?= count($wallets) ?></b> · сигналов сегодня: <b style="color:var(--text)"><?= $signalsToday ?></b></span>
</div>

<div class="kpi-strip">
    <div class="kpi">
        <div class="k-label">Net PnL</div>
        <div class="k-value <?= pnl_class($summary['total_net_pnl']) ?>"><?= fmt_usd($summary['total_net_pnl']) ?></div>
        <div class="k-sub">gross <?= fmt_usd($summary['total_gross_pnl']) ?></div>
        <div class="k-spark" id="kpi-pnl-spark"></div>
    </div>
    <div class="kpi">
        <div class="k-label">Нереализованный</div>
        <div class="k-value <?= pnl_class($unrealizedTotal) ?>"><?= fmt_usd($unrealizedTotal) ?></div>
        <div class="k-sub"><?= count($unrealized) ?> открытых</div>
    </div>
    <div class="kpi">
        <div class="k-label">Win rate</div>
        <div class="k-value"><?= $summary['win_rate'] ?>%</div>
        <div class="k-sub"><?= $summary['wins'] ?>W / <?= $summary['losses'] ?>L · ROI <?= fmt_pct($summary['avg_pnl_pct']) ?></div>
    </div>
    <div class="kpi">
        <div class="k-label">Сделки</div>
        <div class="k-value"><?= $summary['total_trades'] ?></div>
        <div class="k-sub"><?= count($signals) ?> сигналов<?= $selectedPeriod !== 'all' ? ' за ' . $periodOptions[$selectedPeriod] : '' ?></div>
    </div>
    <div class="kpi">
        <div class="k-label">Комиссии</div>
        <div class="k-value neg"><?= fmt_usd(-$summary['total_fees']) ?></div>
        <div class="k-sub">слип. <?= fmt_pct($summary['avg_slippage']) ?> · funding <?= fmt_usd(-$summary['total_funding']) ?></div>
    </div>
</div>

<div class="card section">
    <div class="card-title">
        PnL по периодам
        <div class="seg" style="margin-left:auto" id="pnl-seg">
            <button data-k="day" class="active">Дни</button>
            <button data-k="week">Недели</button>
            <button data-k="month">Месяцы</button>
        </div>
    </div>
    <div class="chart-box" id="pnl-chart"></div>
    <div class="chart-legend">
        <span class="lg-item"><span class="lg-dot" style="background:var(--pos)"></span>прибыльный период</span>
        <span class="lg-item"><span class="lg-dot" style="background:var(--neg)"></span>убыточный период</span>
        <a href="analytics.php<?= $filterWalletId !== null ? '?wallet=' . urlencode($filterWalletId) : '' ?>" class="lg-item" style="margin-left:auto">Кривая капитала и просадка →</a>
    </div>
</div>

<div class="charts-2 section">
    <div class="card" style="margin-top:0">
        <div class="card-title">Трейдеры <span class="dim" style="font-weight:400">по PnL за период</span>
            <a class="link-all" href="traders.php">Все трейдеры →</a></div>
        <?php if (empty($tradersWithHistory)): ?>
            <div class="empty">Пока нет трейдеров со сделками</div>
        <?php else: ?>
            <?php
            $renderTraderRow = function (array $row) use ($sparkByWallet) {
                $spark = $sparkByWallet[$row['wallet_id']] ?? [];
                ?>
                <div class="row-link" data-href="trader.php?id=<?= urlencode($row['wallet_id']) ?>" style="display:flex; align-items:center; gap:12px; padding:9px 2px; border-bottom:1px solid var(--border); cursor:pointer">
                    <div style="flex:1; min-width:0">
                        <div style="font-weight:600; font-size:13px; display:flex; align-items:center; gap:6px">
                            <span style="overflow:hidden; text-overflow:ellipsis; white-space:nowrap"><?= htmlspecialchars($row['label']) ?></span>
                            <?= rating_badge((int) ($row['rating'] ?? 0)) ?>
                            <?php if ($row['score'] !== null): ?><span class="badge grade-<?= $row['grade'] ?>"><?= $row['grade'] ?> <?= $row['score'] ?></span><?php endif; ?>
                            <?= hyperdash_link($row['address'] ?? '') ?>
                        </div>
                        <div class="dim" style="font-size:11.5px"><?= $row['trades_count'] ?> сделок · WR <?= number_format($row['winrate'], 1) ?>%</div>
                    </div>
                    <div class="dash-spark" style="width:84px; flex-shrink:0" data-spark='<?= htmlspecialchars(json_encode($spark), ENT_QUOTES) ?>'></div>
                    <div class="num <?= pnl_class($row['net_pnl']) ?>" style="width:96px; text-align:right; font-weight:650; flex-shrink:0"><?= fmt_usd($row['net_pnl']) ?></div>
                </div>
                <?php
            };
            foreach ($topTraders as $row) {
                $renderTraderRow($row);
            }
            if (!empty($bottomTraders)) {
                echo '<div class="dim" style="font-size:10.5px; text-transform:uppercase; letter-spacing:.6px; padding:8px 2px 2px">Аутсайдеры</div>';
                foreach ($bottomTraders as $row) {
                    $renderTraderRow($row);
                }
            }
            ?>
        <?php endif; ?>
    </div>
    <div class="card" style="margin-top:0">
        <div class="card-title">Открытые позиции
            <a class="link-all" href="positions.php<?= $filterWalletId !== null ? '?wallet=' . urlencode($filterWalletId) : '' ?>">Все позиции →</a></div>
        <?php if (empty($unrealized)): ?>
            <div class="empty">Нет открытых позиций</div>
        <?php else: ?>
            <?php foreach (array_slice($unrealized, 0, 5) as $p): ?>
            <div style="display:flex; align-items:center; gap:10px; padding:9px 2px; border-bottom:1px solid var(--border)">
                <div style="flex:1; min-width:0">
                    <b><?= htmlspecialchars($p['symbol']) ?></b> <?= tradingview_link($p['symbol']) ?>
                    <span class="badge <?= $p['side'] ?>"><?= strtoupper($p['side']) ?></span>
                    <span class="dim">×<?= (int) ($p['leverage'] ?? 1) ?></span>
                    <div class="dim" style="font-size:11.5px; display:flex; align-items:center; gap:5px">
                        <a href="trader.php?id=<?= urlencode($p['wallet_id']) ?>" style="color:inherit"><?= htmlspecialchars($p['wallet_label']) ?></a>
                        <?= rating_badge((int) ($p['wallet_rating'] ?? 0)) ?>
                        <?= hyperdash_link($walletAddressById[$p['wallet_id']] ?? '') ?>
                        · <?= number_format((float) ($p['size_usd'] ?? 0), 2) ?> $
                    </div>
                </div>
                <div class="num <?= pnl_class($p['pnl_usd']) ?>" style="text-align:right; font-weight:650">
                    <?= fmt_usd($p['pnl_usd']) ?>
                    <div style="font-size:11px; font-weight:500"><?= fmt_pct($p['pnl_pct']) ?></div>
                </div>
            </div>
            <?php endforeach; ?>
            <div style="display:flex; justify-content:space-between; padding:10px 2px 0; font-weight:650">
                <span class="dim" style="font-weight:500"><?= count($unrealized) ?> позиций · watching: <?= count($watchingPositions) ?></span>
                <span class="<?= pnl_class($unrealizedTotal) ?>"><?= fmt_usd($unrealizedTotal) ?></span>
            </div>
        <?php endif; ?>
    </div>
</div>

<div class="card section">
    <div class="card-title">Последняя активность
        <a class="link-all" href="journal.php<?= $filterWalletId !== null ? '?wallet=' . urlencode($filterWalletId) : '' ?>">Весь журнал →</a></div>
    <?php if (empty($feed)): ?>
        <div class="empty">Пока нет активности<?= $selectedPeriod !== 'all' ? ' за выбранный период' : '' ?></div>
    <?php else: ?>
        <?php foreach ($feed as $f): ?>
        <div class="feed-row" style="display:flex; gap:12px; align-items:baseline; padding:8px 2px; border-bottom:1px solid var(--border); font-size:13px">
            <span class="dim num feed-time" style="font-size:11.5px; white-space:nowrap; width:96px; flex-shrink:0"><span data-reltime="<?= (int) strtotime($f['at']) ?>"><?= htmlspecialchars(substr($f['at'], 5, 11)) ?></span></span>
            <span class="feed-body" style="flex:1; min-width:0">
                <?php if ($f['type'] === 'trade'): $t = $f['data']; ?>
                    <b><?= htmlspecialchars($t['symbol']) ?></b> <?= tradingview_link($t['symbol']) ?>
                    <span class="badge <?= $t['side'] ?>"><?= strtoupper($t['side']) ?></span>
                    закрыта — <span class="<?= pnl_class((float) $t['net_pnl']) ?>" style="font-weight:650"><?= fmt_usd((float) $t['net_pnl']) ?></span>
                    <?php $reason = $t['exit_reason'] ?? 'signal'; ?>
                    <?php if ($reason === 'liquidation'): ?><span class="badge liq" title="Внутрисделочная ликвидация">LIQ</span>
                    <?php elseif ($reason === 'partial'): ?><span class="badge part" title="Частичное закрытие">PART</span><?php endif; ?>
                <?php else: $s = $f['data']; ?>
                    <b><?= htmlspecialchars($s['symbol']) ?></b> <?= tradingview_link($s['symbol']) ?>
                    <span class="badge <?= strtolower($s['side']) === 'long' ? 'long' : 'short' ?>"><?= strtoupper(htmlspecialchars($s['side'])) ?></span>
                    сигнал <span class="badge mode"><?= htmlspecialchars($s['mode']) ?></span>
                <?php endif; ?>
            </span>
            <span class="dim feed-who" style="font-size:11.5px; display:inline-flex; align-items:center; gap:5px; min-width:0; max-width:38%; flex-shrink:1">
                <a href="trader.php?id=<?= urlencode($f['wid']) ?>" style="color:inherit; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0"><?= htmlspecialchars($f['wlabel']) ?></a>
                <?= rating_badge((int) ($walletRatingById[$f['wid']] ?? 0)) ?>
                <?= hyperdash_link($walletAddressById[$f['wid']] ?? '') ?>
            </span>
        </div>
        <?php endforeach; ?>
    <?php endif; ?>
</div>

<script>
(function () {
    // Герой: накопительный Net PnL за 14 дней — живая кривая под капиталом
    document.getElementById('hero-chart').innerHTML =
        UI.sparkline(<?= json_encode($kpiSpark['usd']) ?>, 360, 96, UI.C.brand);

    // KPI-спарклайн Net PnL за 14 дней
    document.getElementById('kpi-pnl-spark').innerHTML =
        UI.sparkline(<?= json_encode($kpiSpark['usd']) ?>, 150, 30);

    // Спарклайны в топе трейдеров
    document.querySelectorAll('[data-spark]').forEach(el => {
        try { el.innerHTML = UI.sparkline(JSON.parse(el.dataset.spark), 84, 26); } catch (e) {}
    });

    // График «PnL по периодам» с переключателем Дни/Недели/Месяцы
    const series = {
        day:   { labels: <?= json_encode(array_column($byDay, 'label')) ?>,   usd: <?= json_encode(array_column($byDay, 'pnl_usd')) ?> },
        week:  { labels: <?= json_encode(array_column($byWeek, 'label')) ?>,  usd: <?= json_encode(array_column($byWeek, 'pnl_usd')) ?> },
        month: { labels: <?= json_encode(array_column($byMonth, 'label')) ?>, usd: <?= json_encode(array_column($byMonth, 'pnl_usd')) ?> },
    };
    function drawPnl(k) { UI.barChart('pnl-chart', series[k].labels, series[k].usd, ' $', { w: 1000, h: 165 }); }
    drawPnl('day');
    document.querySelectorAll('#pnl-seg button').forEach(b => b.addEventListener('click', () => {
        document.querySelectorAll('#pnl-seg button').forEach(x => x.classList.toggle('active', x === b));
        drawPnl(b.dataset.k);
    }));
})();
</script>

<?php layout_footer(); ?>
