<?php

require_once __DIR__ . '/admin_tool_helper.php';

if (!function_exists('e')) {
    function e($value) {
        return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
    }
}

function ssr_table_exists(string $table): bool {
    try {
        $stmt = db()->prepare('SHOW TABLES LIKE ?');
        $stmt->execute([$table]);
        return (bool)$stmt->fetchColumn();
    } catch (Throwable $e) {
        return false;
    }
}

function ssr_setting_get(string $key, string $default = ''): string {
    try {
        if (!ssr_table_exists('system_settings')) return $default;
        $stmt = db()->prepare('SELECT setting_value FROM system_settings WHERE setting_key = ? ORDER BY id DESC LIMIT 1');
        $stmt->execute([$key]);
        $value = $stmt->fetchColumn();
        return $value !== false ? (string)$value : $default;
    } catch (Throwable $e) {
        return $default;
    }
}

function ssr_setting_save(string $key, string $value): void {
    if (!ssr_table_exists('system_settings')) {
        throw new RuntimeException('system_settings table was not found.');
    }

    try {
        $stmt = db()->prepare('SELECT id FROM system_settings WHERE setting_key = ? ORDER BY id DESC LIMIT 1');
        $stmt->execute([$key]);
        $id = (int)$stmt->fetchColumn();

        if ($id > 0) {
            $sql = 'UPDATE system_settings SET setting_value = ?';
            $params = [$value];
            try {
                $checkUpdated = db()->prepare('SHOW COLUMNS FROM system_settings LIKE ?');
                $checkUpdated->execute(['updated_at']);
                if ($checkUpdated->fetchColumn()) {
                    $sql .= ', updated_at = NOW()';
                }
            } catch (Throwable $e) {}
            $sql .= ' WHERE id = ?';
            $params[] = $id;
            db()->prepare($sql)->execute($params);
            return;
        }

        $columns = ['setting_key', 'setting_value'];
        $placeholders = ['?', '?'];
        $params = [$key, $value];
        foreach (['created_at', 'updated_at'] as $column) {
            try {
                $check = db()->prepare('SHOW COLUMNS FROM system_settings LIKE ?');
                $check->execute([$column]);
                if ($check->fetchColumn()) {
                    $columns[] = $column;
                    $placeholders[] = 'NOW()';
                }
            } catch (Throwable $e) {}
        }
        db()->prepare('INSERT INTO system_settings (' . implode(',', $columns) . ') VALUES (' . implode(',', $placeholders) . ')')->execute($params);
    } catch (Throwable $e) {
        throw $e;
    }
}

$settings = [
    'master' => [
        'title' => 'Master Controls',
        'subtitle' => 'Control whether the platform can create and notify users about new suggested setups.',
        'fields' => [
            'suggest_derived_setups_enabled' => ['label' => 'Enable suggested setups', 'type' => 'bool', 'default' => '1', 'help' => 'Allow the alert engine to save a new review-only setup when a valid execution candidate forms outside the original tracked zone.'],
            'derived_setup_notify_email' => ['label' => 'Notify by email', 'type' => 'bool', 'default' => '1', 'help' => 'Send a review-only suggested setup notification by email.'],
            'derived_setup_notify_telegram' => ['label' => 'Notify by Telegram', 'type' => 'bool', 'default' => '1', 'help' => 'Send a review-only suggested setup notification by Telegram.'],
        ],
    ],
    'integrity' => [
        'title' => 'Setup Integrity Gates',
        'subtitle' => 'Protect the original tracked setup so a new opportunity cannot silently replace it.',
        'fields' => [
            'derived_setup_require_same_direction' => ['label' => 'Require same direction', 'type' => 'bool', 'default' => '1', 'help' => 'Suggested setup must keep the same BUY/SELL direction as the source setup.'],
            'derived_setup_require_outside_original_zone' => ['label' => 'Require entry outside original zone', 'type' => 'bool', 'default' => '1', 'help' => 'Only create suggestions when the recalculated entry no longer belongs to the old tracked zone.'],
            'derived_setup_zone_buffer_percent' => ['label' => 'Outside-zone tolerance (%)', 'type' => 'number', 'default' => '10', 'min' => '0', 'max' => '50', 'step' => '0.5', 'help' => 'Small tolerance around the original zone before a new candidate is treated as outside-zone.'],
            'derived_setup_require_clean_execution_prices' => ['label' => 'Require entry, SL and TP1', 'type' => 'bool', 'default' => '1', 'help' => 'Suggested setup must have clean execution prices.'],
            'derived_setup_require_execution_geometry' => ['label' => 'Require correct BUY/SELL geometry', 'type' => 'bool', 'default' => '1', 'help' => 'BUY must have SL below entry and TP above entry; SELL must have SL above entry and TP below entry.'],
        ],
    ],
    'market' => [
        'title' => 'Market and Confirmation Gates',
        'subtitle' => 'Avoid suggesting setups from stale, closed-market, or weak confirmation data.',
        'fields' => [
            'derived_setup_require_market_open' => ['label' => 'Require market open', 'type' => 'bool', 'default' => '1', 'help' => 'Do not create suggested setups while the relevant market is closed.'],
            'derived_setup_require_fresh_quote' => ['label' => 'Require fresh live quote', 'type' => 'bool', 'default' => '1', 'help' => 'Require a fresh quote instead of only a saved candle close.'],
            'derived_setup_fresh_quote_max_age_seconds' => ['label' => 'Fresh quote max age (seconds)', 'type' => 'number', 'default' => '300', 'min' => '60', 'max' => '3600', 'step' => '30', 'help' => 'Maximum accepted live quote age for suggested setup creation.'],
            'derived_setup_require_structure_confirmation' => ['label' => 'Require BOS/CHoCH structure confirmation', 'type' => 'bool', 'default' => '1', 'help' => 'Require fresh structure confirmation before a suggestion can be created.'],
            'derived_setup_require_candle_close_confirmation' => ['label' => 'Require candle-close confirmation', 'type' => 'bool', 'default' => '1', 'help' => 'Require a closed confirmation candle before creating a suggestion.'],
            'derived_setup_require_news_preference' => ['label' => 'Respect user/news preference', 'type' => 'bool', 'default' => '1', 'help' => 'Do not suggest a new setup if user/news settings disallow it at that time.'],
        ],
    ],
    'location' => [
        'title' => 'Institutional Location Gates',
        'subtitle' => 'Require premium/supply for SELL ideas and discount/demand for BUY ideas across HTF/LTF context.',
        'fields' => [
            'derived_setup_require_htf_location' => ['label' => 'Require HTF premium/discount alignment', 'type' => 'bool', 'default' => '1', 'help' => 'SELL should be in premium/supply context; BUY should be in discount/demand context on the higher timeframe.'],
            'derived_setup_require_ltf_location' => ['label' => 'Require LTF premium/discount alignment', 'type' => 'bool', 'default' => '1', 'help' => 'The refined lower-timeframe entry must also support the direction.'],
            'derived_setup_min_location_score' => ['label' => 'Minimum location score', 'type' => 'number', 'default' => '65', 'min' => '0', 'max' => '100', 'step' => '1', 'help' => 'Minimum accepted HTF/LTF location score for suggestion creation.'],
            'derived_setup_allow_midrange_continuation' => ['label' => 'Allow midrange continuation setups', 'type' => 'bool', 'default' => '0', 'help' => 'Keep disabled by default. Enable only if you want strong continuation setups around equilibrium to be suggested.'],
        ],
    ],
    'quality' => [
        'title' => 'Quality and Anti-Spam Limits',
        'subtitle' => 'Control quality thresholds, suggestion expiry and how often users can receive suggestions from one setup.',
        'fields' => [
            'derived_setup_min_quality_score' => ['label' => 'Minimum setup quality score', 'type' => 'number', 'default' => '65', 'min' => '0', 'max' => '100', 'step' => '1', 'help' => 'Minimum engine quality score required before a suggested setup is created.'],
            'derived_setup_suggestion_cooldown_minutes' => ['label' => 'Suggestion cooldown (minutes)', 'type' => 'number', 'default' => '60', 'min' => '5', 'max' => '1440', 'step' => '5', 'help' => 'Prevents repeated suggestions for the same source alert.'],
            'derived_setup_suggestion_expiry_minutes' => ['label' => 'Suggestion expiry (minutes)', 'type' => 'number', 'default' => '240', 'min' => '30', 'max' => '4320', 'step' => '30', 'help' => 'How long a suggested setup remains reviewable before expiring.'],
            'derived_setup_max_suggestions_per_source' => ['label' => 'Max suggestions per original setup', 'type' => 'number', 'default' => '2', 'min' => '1', 'max' => '10', 'step' => '1', 'help' => 'Caps how many suggested setups one original tracked setup can generate.'],
        ],
    ],
];

$flatSettings = [];
foreach ($settings as $group) {
    foreach ($group['fields'] as $key => $field) {
        $flatSettings[$key] = $field;
        if (ssr_setting_get($key, '') === '') {
            try { ssr_setting_save($key, (string)$field['default']); } catch (Throwable $e) {}
        }
    }
}

$message = '';
$error = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        foreach ($flatSettings as $key => $field) {
            if (($field['type'] ?? 'text') === 'bool') {
                $value = isset($_POST['settings'][$key]) ? '1' : '0';
            } else {
                $raw = trim((string)($_POST['settings'][$key] ?? $field['default']));
                if (($field['type'] ?? '') === 'number') {
                    $num = is_numeric($raw) ? (float)$raw : (float)$field['default'];
                    if (isset($field['min'])) $num = max((float)$field['min'], $num);
                    if (isset($field['max'])) $num = min((float)$field['max'], $num);
                    $step = (string)($field['step'] ?? '1');
                    $value = strpos($step, '.') !== false ? rtrim(rtrim(number_format($num, 4, '.', ''), '0'), '.') : (string)(int)round($num);
                } else {
                    $value = $raw;
                }
            }
            ssr_setting_save($key, $value);
        }
        $message = 'Suggested setup rules updated successfully.';
    } catch (Throwable $e) {
        $error = $e->getMessage();
    }
}

$stats = [
    'pending' => 0,
    'accepted' => 0,
    'ignored' => 0,
    'expired' => 0,
];
try {
    if (ssr_table_exists('institutional_suggested_setups')) {
        $rows = db()->query("SELECT status, COUNT(*) AS total FROM institutional_suggested_setups GROUP BY status")->fetchAll(PDO::FETCH_ASSOC) ?: [];
        foreach ($rows as $row) {
            $key = strtolower((string)($row['status'] ?? ''));
            if (isset($stats[$key])) $stats[$key] = (int)($row['total'] ?? 0);
        }
    }
} catch (Throwable $e) {}

admin_layout_header('Suggested Setup Rules');
?>

<style>
.ssr-wrap{max-width:1450px;margin:0 auto}.ssr-hero{background:linear-gradient(135deg,#020617,#0f172a,#1e293b);border-radius:32px;padding:34px;color:#fff;margin-bottom:24px}.ssr-kicker{display:inline-flex;background:rgba(59,130,246,.16);color:#bfdbfe;padding:7px 11px;border-radius:999px;font-size:11px;font-weight:900;text-transform:uppercase;letter-spacing:.08em}.ssr-title{font-size:42px;font-weight:950;letter-spacing:-.05em;margin-top:14px}.ssr-sub{max-width:940px;color:#cbd5e1;line-height:1.7;margin-top:10px}.ssr-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:22px}.ssr-stat{background:#fff;border:1px solid #e2e8f0;border-radius:22px;padding:18px;box-shadow:0 10px 24px rgba(15,23,42,.05)}.ssr-stat span{display:block;font-size:11px;font-weight:900;letter-spacing:.08em;text-transform:uppercase;color:#64748b}.ssr-stat strong{display:block;margin-top:8px;font-size:32px;letter-spacing:-.04em;color:#020617}.ssr-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.ssr-card{background:#fff;border:1px solid #e2e8f0;border-radius:26px;overflow:hidden;box-shadow:0 10px 24px rgba(15,23,42,.05)}.ssr-card-head{padding:22px 24px;border-bottom:1px solid #e2e8f0;background:linear-gradient(135deg,rgba(37,99,235,.06),rgba(15,23,42,.02))}.ssr-card-title{font-size:22px;font-weight:950;letter-spacing:-.03em;color:#020617}.ssr-card-sub{margin-top:6px;color:#64748b;font-size:13px;line-height:1.5}.ssr-card-body{padding:22px 24px;display:grid;gap:16px}.ssr-field{display:grid;gap:7px}.ssr-field-row{display:flex;gap:10px;align-items:flex-start;justify-content:space-between}.ssr-label{font-size:13px;font-weight:900;color:#0f172a}.ssr-help{font-size:12px;color:#64748b;line-height:1.5}.ssr-input{width:180px;max-width:100%;border:1px solid #cbd5e1;border-radius:14px;padding:11px 12px;font-weight:800;color:#0f172a}.ssr-toggle{position:relative;width:46px;height:26px;flex:0 0 auto}.ssr-toggle input{opacity:0;width:0;height:0}.ssr-slider{position:absolute;cursor:pointer;inset:0;background:#cbd5e1;border-radius:999px;transition:.2s}.ssr-slider:before{content:"";position:absolute;width:20px;height:20px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.2s;box-shadow:0 2px 5px rgba(0,0,0,.2)}.ssr-toggle input:checked + .ssr-slider{background:#2563eb}.ssr-toggle input:checked + .ssr-slider:before{transform:translateX(20px)}.ssr-actions{position:sticky;bottom:0;margin-top:22px;background:rgba(248,250,252,.88);backdrop-filter:blur(10px);border:1px solid #e2e8f0;border-radius:24px;padding:16px;display:flex;justify-content:space-between;align-items:center;gap:14px}.ssr-btn{border:0;border-radius:14px;padding:13px 18px;font-weight:950;cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;justify-content:center}.ssr-btn-primary{background:#2563eb;color:#fff}.ssr-btn-dark{background:#0f172a;color:#fff}.ssr-notice{padding:14px 16px;border-radius:16px;margin-bottom:16px;font-weight:800}.ssr-ok{background:#dcfce7;color:#065f46;border:1px solid #86efac}.ssr-err{background:#fee2e2;color:#991b1b;border:1px solid #fecaca}.ssr-note{background:#eff6ff;border:1px solid #bfdbfe;color:#1e3a8a;border-radius:20px;padding:18px;line-height:1.7;margin-bottom:22px}@media(max-width:900px){.ssr-grid{grid-template-columns:1fr}.ssr-title{font-size:34px}.ssr-actions{position:static;flex-direction:column;align-items:stretch}.ssr-btn{width:100%}}
</style>

<div class="ssr-wrap">
    <section class="ssr-hero">
        <div class="ssr-kicker">Alert Engine</div>
        <div class="ssr-title">Suggested Setup Rules</div>
        <div class="ssr-sub">Control when the platform may suggest a new setup after the original tracked zone is no longer the valid execution area. These rules protect user trust: the old setup is preserved, and the new setup is review-only until the user accepts it.</div>
    </section>

    <?php if ($message): ?><div class="ssr-notice ssr-ok"><?= e($message) ?></div><?php endif; ?>
    <?php if ($error): ?><div class="ssr-notice ssr-err"><?= e($error) ?></div><?php endif; ?>

    <section class="ssr-stats">
        <?php foreach ($stats as $label => $value): ?>
            <div class="ssr-stat"><span><?= e($label) ?> suggestions</span><strong><?= e($value) ?></strong></div>
        <?php endforeach; ?>
    </section>

    <div class="ssr-note"><strong>Institutional default:</strong> SELL suggestions should require premium/supply context and BUY suggestions should require discount/demand context on both higher and lower timeframes. Keep these rules strict unless you are intentionally testing a more aggressive model.</div>

    <form method="post">
        <div class="ssr-grid">
            <?php foreach ($settings as $group): ?>
                <section class="ssr-card">
                    <div class="ssr-card-head">
                        <div class="ssr-card-title"><?= e($group['title']) ?></div>
                        <div class="ssr-card-sub"><?= e($group['subtitle']) ?></div>
                    </div>
                    <div class="ssr-card-body">
                        <?php foreach ($group['fields'] as $key => $field): $value = ssr_setting_get($key, (string)$field['default']); ?>
                            <label class="ssr-field">
                                <div class="ssr-field-row">
                                    <div>
                                        <div class="ssr-label"><?= e($field['label']) ?></div>
                                        <div class="ssr-help"><?= e($field['help']) ?></div>
                                    </div>
                                    <?php if (($field['type'] ?? '') === 'bool'): ?>
                                        <span class="ssr-toggle"><input type="checkbox" name="settings[<?= e($key) ?>]" value="1" <?= $value === '1' ? 'checked' : '' ?>><span class="ssr-slider"></span></span>
                                    <?php else: ?>
                                        <input class="ssr-input" type="number" name="settings[<?= e($key) ?>]" value="<?= e($value) ?>" min="<?= e($field['min'] ?? '') ?>" max="<?= e($field['max'] ?? '') ?>" step="<?= e($field['step'] ?? '1') ?>">
                                    <?php endif; ?>
                                </div>
                            </label>
                        <?php endforeach; ?>
                    </div>
                </section>
            <?php endforeach; ?>
        </div>

        <div class="ssr-actions">
            <div style="color:#64748b;font-size:13px;line-height:1.5;">Changes are saved to <strong>system_settings</strong> and used by <strong>AlertService</strong> on the next alert-worker evaluation.</div>
            <div style="display:flex;gap:10px;flex-wrap:wrap;">
                <a class="ssr-btn ssr-btn-dark" href="control_panel.php">Back to Control Panel</a>
                <button class="ssr-btn ssr-btn-primary" type="submit">Save Suggested Setup Rules</button>
            </div>
        </div>
    </form>
</div>

<?php admin_layout_footer(); ?>
