<?php
// =============================================================
// DASHBOARD/LIB/SETTINGS_RENDER — рендер полей из каталога
// =============================================================
// Два режима на одном каталоге (settings_schema.php):
//
//   'global'   — глобальные дефолты. В поле всегда стоит значение.
//   'override' — карточка трейдера. Пустое поле = наследовать глобальное;
//                унаследованное значение показывается прямо в подсказке,
//                чтобы не приходилось открывать вторую вкладку и сверять.
//
// Имена полей формы совпадают с ключами каталога (в режиме override — с
// префиксом), поэтому существующие парсеры POST менять не требуется.
// =============================================================

require_once __DIR__ . '/settings_schema.php';

/**
 * Значение настройки в виде строки для input/подсказки.
 * Массивы разворачиваются в тот же формат, который принимают парсеры форм.
 */
function settings_value_to_string(string $type, $value): string
{
    if ($value === null) {
        return '';
    }
    if ($type === 'symbols') {
        return is_array($value) ? implode(', ', $value) : (string) $value;
    }
    if ($type === 'leverage_map') {
        if (!is_array($value)) {
            return (string) $value;
        }
        $pairs = [];
        foreach ($value as $sym => $lev) {
            $pairs[] = $sym . '=' . $lev;
        }
        return implode(', ', $pairs);
    }
    if (is_bool($value)) {
        return $value ? '1' : '0';
    }
    return (string) $value;
}

/**
 * Человеческое представление значения для строки «сейчас глобально: …».
 * Пустые значения проговариваются словами — «не задано» информативнее пустоты.
 */
function settings_value_display(array $field, $value): string
{
    $type = $field['type'] ?? 'text';

    if ($type === 'select') {
        $str = settings_value_to_string($type, $value);
        return $field['options'][$str] ?? ($str === '' ? 'не задано' : $str);
    }

    $str = settings_value_to_string($type, $value);
    if ($str === '') {
        return $type === 'symbols' ? 'все монеты' : 'не задано';
    }
    if ($type === 'password') {
        return 'задан';
    }

    // 0 у лимитов и издержек значит «выключено» — говорим об этом прямо.
    if (($type === 'number') && (float) $str === 0.0
        && in_array($field['key'], ['position_min_usd', 'position_max_usd',
            'slippage_pct_per_side', 'funding_rate_hourly_pct', 'cooldown_seconds',
            'poll_interval_minutes', 'copy_after_drawdown_ttl_hours'], true)
    ) {
        return '0 — выключено';
    }

    return $str . (($field['unit'] ?? '') !== '' ? ' ' . $field['unit'] : '');
}

/**
 * Одно поле каталога.
 *
 * @param array  $field       описание из settings_schema()
 * @param mixed  $value       текущее значение (в режиме override — только override, может быть null)
 * @param string $mode        'global' | 'override'
 * @param string $prefix      префикс имён полей формы (режим override)
 * @param mixed  $inherited   значение, которое наследуется, если поле оставить пустым
 */
function render_setting_field(array $field, $value, string $mode = 'global', string $prefix = '', $inherited = null): void
{
    $key      = $field['key'];
    $type     = $field['type'] ?? 'text';
    $name     = $prefix . $key;
    $isOvr    = $mode === 'override';
    $unit     = $field['unit'] ?? '';
    $attrs    = $field['attrs'] ?? '';
    $valueStr = settings_value_to_string($type, $value);

    // Условие показа: поле имеет смысл только при определённом значении другого.
    $depAttr = '';
    if (!empty($field['depends'])) {
        $depKey = array_key_first($field['depends']);
        $depAttr = ' data-dep-on="' . htmlspecialchars($prefix . $depKey) . '"'
                 . ' data-dep-val="' . htmlspecialchars((string) $field['depends'][$depKey]) . '"';
    }

    // Для symbols/leverage_map в режиме override нужен явный чекбокс: пустое
    // поле и «не переопределять» — разные вещи (пустой список = ВСЕ монеты).
    $needsToggle = $isOvr && in_array($type, ['symbols', 'leverage_map'], true);
    $toggleName  = $prefix . ($type === 'symbols' ? 'override_symbols' : 'override_symbol_leverage');
    $isOverridden = $value !== null;
    ?>
    <div class="set-field<?= $isOvr && $isOverridden ? ' is-overridden' : '' ?>" data-key="<?= htmlspecialchars($name) ?>"<?= $depAttr ?>>
        <div class="set-head">
            <label for="<?= htmlspecialchars($name) ?>"><?= htmlspecialchars($field['label']) ?></label>
            <?php if ($unit !== ''): ?><span class="set-unit"><?= htmlspecialchars($unit) ?></span><?php endif; ?>
            <?php if ($isOvr && $isOverridden): ?><span class="set-ovr-flag" title="Переопределено для этого трейдера">свой</span><?php endif; ?>
        </div>

        <?php if ($needsToggle): ?>
        <label class="check set-toggle">
            <input type="checkbox" name="<?= htmlspecialchars($toggleName) ?>" value="1"
                   <?= $isOverridden ? 'checked' : '' ?>
                   onchange="document.getElementById('<?= htmlspecialchars($name) ?>').disabled = !this.checked; SettingsUI.mark(this);">
            задать свой список для этого трейдера
        </label>
        <?php endif; ?>

        <?php if ($type === 'select'): ?>
            <select name="<?= htmlspecialchars($name) ?>" id="<?= htmlspecialchars($name) ?>" onchange="SettingsUI.sync()">
                <?php if ($isOvr): ?>
                    <option value="">Как глобально — <?= htmlspecialchars(settings_value_display($field, $inherited)) ?></option>
                <?php endif; ?>
                <?php foreach ($field['options'] as $optVal => $optLabel): ?>
                    <option value="<?= htmlspecialchars((string) $optVal) ?>" <?= $valueStr === (string) $optVal ? 'selected' : '' ?>>
                        <?= htmlspecialchars($optLabel) ?>
                    </option>
                <?php endforeach; ?>
            </select>
        <?php else: ?>
            <?php
            $inputType = $type === 'number' ? 'number' : ($type === 'password' ? 'password' : 'text');
            $placeholder = '';
            if ($isOvr) {
                $placeholder = 'Как глобально — ' . settings_value_display($field, $inherited);
            } elseif (strpos($attrs, 'placeholder=') === false && $type === 'symbols') {
                $placeholder = 'пусто = все монеты';
            }
            ?>
            <input type="<?= $inputType ?>" <?= $attrs ?>
                   name="<?= htmlspecialchars($name) ?>" id="<?= htmlspecialchars($name) ?>"
                   value="<?= htmlspecialchars($valueStr) ?>"
                   <?= $placeholder !== '' && strpos($attrs, 'placeholder=') === false
                        ? 'placeholder="' . htmlspecialchars($placeholder) . '"' : '' ?>
                   <?= $needsToggle && !$isOverridden ? 'disabled' : '' ?>
                   oninput="SettingsUI.mark(this)">
        <?php endif; ?>

        <div class="set-what"><?= htmlspecialchars($field['what']) ?></div>
        <?php
        // Пример и предупреждение по умолчанию свёрнуты: если показывать все три
        // блока текста у каждого поля, страница превращается в простыню и её
        // перестают читать вовсе. Суть («что делает») видна всегда, детали —
        // в один тап. Раскрытое состояние запоминается на весь список полей.
        $hasMore = !empty($field['example']) || !empty($field['warn']);
        if ($hasMore):
        ?>
        <details class="set-more"<?= !empty($field['warn']) ? ' data-has-warn="1"' : '' ?>>
            <summary>Подробнее<?= !empty($field['warn']) ? ' · есть важное' : '' ?></summary>
            <?php if (!empty($field['example'])): ?>
                <div class="set-example"><?= htmlspecialchars($field['example']) ?></div>
            <?php endif; ?>
            <?php if (!empty($field['warn'])): ?>
                <div class="set-warn"><?= htmlspecialchars($field['warn']) ?></div>
            <?php endif; ?>
        </details>
        <?php endif; ?>
    </div>
    <?php
}

/**
 * Группа каталога целиком. В режиме override поля со scope='global'
 * пропускаются — их нельзя задать на трейдера.
 */
function render_settings_group(string $groupKey, array $values, string $mode = 'global', string $prefix = '', array $inheritedValues = []): void
{
    $schema = settings_schema();
    if (!isset($schema[$groupKey])) {
        return;
    }
    $group = $schema[$groupKey];

    echo '<div class="card">';
    echo '<div class="card-title">' . htmlspecialchars($group['title']) . '</div>';
    if (!empty($group['intro'])) {
        echo '<div class="card-sub">' . htmlspecialchars($group['intro']) . '</div>';
    }

    foreach ($group['fields'] as $field) {
        if ($mode === 'override' && ($field['scope'] ?? 'both') === 'global') {
            continue;
        }
        $key = $field['key'];
        render_setting_field(
            $field,
            $values[$key] ?? null,
            $mode,
            $prefix,
            $inheritedValues[$key] ?? null
        );
    }

    echo '</div>';
}

/**
 * Общий JS для полей каталога: скрытие неприменимых полей (depends) и
 * пометка «свой» на изменённых override-полях. Подключать один раз на страницу.
 */
function render_settings_expand_toggle(): void
{
    echo '<div class="set-tools">'
       . '<button type="button" class="btn ghost small" id="set-expand-toggle" '
       . 'onclick="SettingsUI.expandAll(!document.querySelector(\'details.set-more[open]\'))">'
       . 'Показать все пояснения</button></div>';
}

function render_settings_ui_script(): void
{
    ?>
    <script>
    window.SettingsUI = (function () {
        function valueOf(name) {
            var el = document.getElementById(name);
            return el ? el.value : null;
        }
        function sync() {
            document.querySelectorAll('.set-field[data-dep-on]').forEach(function (f) {
                var current = valueOf(f.dataset.depOn);
                // Пустое значение управляющего поля = «как глобально»: не знаем
                // итогового режима, поэтому показываем поле, а не прячем.
                var show = current === null || current === '' || current === f.dataset.depVal;
                f.classList.toggle('dep-hidden', !show);
            });
        }
        function mark(el) {
            var field = el.closest('.set-field');
            if (!field) return;
            var input = field.querySelector('input:not([type=checkbox]), select');
            var toggle = field.querySelector('.set-toggle input');
            var has = toggle ? toggle.checked : !!(input && input.value !== '');
            field.classList.toggle('is-overridden', has);
        }
        // Раскрыть/свернуть все пояснения разом. Выбор запоминается локально,
        // чтобы не раскрывать их заново на каждой вкладке и после сохранения.
        function expandAll(on) {
            document.querySelectorAll('details.set-more').forEach(function (d) { d.open = on; });
            try { localStorage.setItem('ha-set-expanded', on ? '1' : '0'); } catch (e) {}
            var btn = document.getElementById('set-expand-toggle');
            if (btn) btn.textContent = on ? 'Свернуть пояснения' : 'Показать все пояснения';
        }
        function restore() {
            var on = false;
            try { on = localStorage.getItem('ha-set-expanded') === '1'; } catch (e) {}
            if (on) expandAll(true);
            var btn = document.getElementById('set-expand-toggle');
            if (btn) btn.textContent = on ? 'Свернуть пояснения' : 'Показать все пояснения';
        }
        document.addEventListener('DOMContentLoaded', function () { sync(); restore(); });
        return { sync: sync, mark: mark, expandAll: expandAll };
    })();
    </script>
    <?php
}
