<!--
Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
-->
{% extends "base.html" %}

{% block title %}Settings - AISBF Dashboard{% endblock %}

{% block content %}
<style>
.settings-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 28px; border-bottom: 2px solid #0f3460; padding-bottom: 0; }
.settings-tab { padding: 10px 18px; cursor: pointer; border-radius: 6px 6px 0 0; color: var(--color-muted); font-size: .9em; border: 1px solid transparent; border-bottom: none; margin-bottom: -2px; transition: background .15s, color .15s; }
.settings-tab:hover { background: var(--bg-accent); color: var(--color-text); }
.settings-tab.active { background: var(--bg-panel); color: var(--color-primary); border-color: var(--color-border); border-bottom-color: var(--bg-panel); font-weight: 600; }
.settings-section { display: none; }
.settings-section.active { display: block; }
.section-title { font-size: 1.1em; font-weight: 600; color: var(--color-primary); margin: 0 0 20px; padding-bottom: 8px; border-bottom: 1px solid var(--color-border); }
.tri-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:16px; }
</style>

{% macro tri_state_select(field_name, selected_value, label, help_text='') %}
<div class="form-group">
    <label for="{{ field_name }}">{{ label }}</label>
    <select id="{{ field_name }}" name="{{ field_name }}">
        <option value="inherit" {% if selected_value == 'inherit' %}selected{% endif %}>Inherit</option>
        <option value="enabled" {% if selected_value == 'enabled' %}selected{% endif %}>Enabled</option>
        <option value="disabled" {% if selected_value == 'disabled' %}selected{% endif %}>Disabled</option>
    </select>
    {% if help_text %}<small style="color: var(--color-subtle); display: block; margin-top: 5px;">{{ help_text }}</small>{% endif %}
</div>
{% endmacro %}

{% macro bool_mode_select(field_name, selected_value, label, help_text='') %}
<div class="form-group">
    <label for="{{ field_name }}">{{ label }}</label>
    <select id="{{ field_name }}" name="{{ field_name }}">
        <option value="enabled" {% if selected_value == 'enabled' %}selected{% endif %}>Enabled</option>
        <option value="disabled" {% if selected_value == 'disabled' %}selected{% endif %}>Disabled</option>
    </select>
    {% if help_text %}<small style="color: var(--color-subtle); display: block; margin-top: 5px;">{{ help_text }}</small>{% endif %}
</div>
{% endmacro %}

<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:24px;">
    <h2 style="margin:0;">Server Settings</h2>
</div>

{% if success %}
<div class="alert alert-success">{{ success }}</div>
{% endif %}

{% if error %}
<div class="alert alert-error">{{ error }}</div>
{% endif %}

{% if warning == 'default_password' %}
<div style="background:#b71c1c; border:2px solid #e53935; color:#fff; padding:16px 20px; border-radius:6px; margin-bottom:20px; display:flex; align-items:flex-start; gap:12px;">
    <span style="font-size:1.4em; line-height:1;">&#9888;</span>
    <div>
        <strong>Security Warning: Default password in use.</strong><br>
        You are logged in with the factory-default <code style="background:rgba(0,0,0,.3);padding:1px 5px;border-radius:3px;">admin / admin</code> credentials.
        Please change your password immediately using the <strong>Admin</strong> tab below before using AISBF.
    </div>
</div>
{% endif %}

<div class="settings-tabs">
    <div class="settings-tab active" onclick="switchTab('server')"><i class="fas fa-server"></i><span data-i18n="settings_page.tab_server">Server</span></div>
    <div class="settings-tab" onclick="switchTab('auth')"><i class="fas fa-key"></i><span data-i18n="settings_page.tab_auth">Auth &amp; MCP</span></div>
    <div class="settings-tab" onclick="switchTab('models')"><i class="fas fa-brain"></i><span data-i18n="settings_page.tab_models">Models</span></div>
    <div class="settings-tab" onclick="switchTab('database')"><i class="fas fa-database"></i><span data-i18n="settings_page.tab_database">Database</span></div>
    <div class="settings-tab" onclick="switchTab('cache')"><i class="fas fa-bolt"></i><span data-i18n="settings_page.tab_cache">Cache</span></div>
    <div class="settings-tab" onclick="switchTab('classification')"><i class="fas fa-filter"></i><span data-i18n="settings_page.tab_classification">Features</span></div>
    <div class="settings-tab" onclick="switchTab('tor')"><i class="fas fa-user-secret"></i><span data-i18n="settings_page.tab_tor">TOR</span></div>
    <div class="settings-tab" onclick="switchTab('signup')"><i class="fas fa-user-plus"></i><span data-i18n="settings_page.tab_signup">Signup</span></div>
    <div class="settings-tab" onclick="switchTab('oauth2')"><i class="fab fa-openid"></i><span data-i18n="settings_page.tab_oauth2">OAuth2</span></div>
    <div class="settings-tab" onclick="switchTab('smtp')"><i class="fas fa-envelope"></i><span data-i18n="settings_page.tab_smtp">SMTP</span></div>
    <div class="settings-tab" onclick="switchTab('batching')"><i class="fas fa-layer-group"></i><span data-i18n="settings_page.tab_batching">Batching</span></div>
    <div class="settings-tab" onclick="switchTab('ratelimit')"><i class="fas fa-tachometer-alt"></i><span data-i18n="settings_page.tab_ratelimit">Rate Limiting</span></div>
    <div class="settings-tab" onclick="switchTab('admin')"><i class="fas fa-shield-alt"></i><span data-i18n="settings_page.tab_admin">Admin</span></div>
</div>

<form method="POST">
    <input type="hidden" name="active_tab" id="active_tab_input" value="{{ active_tab if active_tab else 'server' }}">
    <div class="settings-section active" id="tab-server">
    <div class="section-title"><i class="fas fa-server"></i> <span data-i18n="settings_page.section_server">Server Configuration</span></div>
    
    <div class="form-group">
        <label for="host" data-i18n="settings_page.lbl_host">Host</label>
        <input type="text" id="host" name="host" value="{{ config.server.host }}" required>
    </div>
    
    <div class="form-group">
        <label for="port" data-i18n="settings_page.lbl_port">Port</label>
        <input type="number" id="port" name="port" value="{{ config.server.port }}" required>
    </div>
    
    <div class="form-group">
        <label for="protocol" data-i18n="settings_page.lbl_protocol">Protocol</label>
        <select id="protocol" name="protocol" onchange="toggleSSLFields()">
            <option value="http" {% if config.server.protocol == 'http' %}selected{% endif %}>HTTP</option>
            <option value="https" {% if config.server.protocol == 'https' %}selected{% endif %}>HTTPS</option>
        </select>
    </div>
    
    <div id="ssl-fields" style="display: {% if config.server.protocol == 'https' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="public_domain" data-i18n="settings_page.lbl_public_domain">Public Domain (for Let's Encrypt)</label>
            <input type="text" id="public_domain" name="public_domain" value="{{ config.server.public_domain or '' }}" placeholder="example.com (optional)">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">If specified, Let's Encrypt will be used to generate valid SSL certificates. Leave empty to use self-signed certificates.</small>
        </div>
        
        <div class="form-group">
            <label for="ssl_cert" data-i18n="settings_page.lbl_ssl_cert">SSL Certificate Path</label>
            <input type="text" id="ssl_cert" name="ssl_cert" value="{{ config.server.ssl_cert or '' }}" placeholder="~/.aisbf/cert.pem (default)">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Path to SSL certificate file. Leave empty to use default (~/.aisbf/cert.pem). Auto-generated using Let's Encrypt if public domain is set, otherwise self-signed.</small>
        </div>
        
        <div class="form-group">
            <label for="ssl_key" data-i18n="settings_page.lbl_ssl_key">SSL Key Path</label>
            <input type="text" id="ssl_key" name="ssl_key" value="{{ config.server.ssl_key or '' }}" placeholder="~/.aisbf/key.pem (default)">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Path to SSL private key file. Leave empty to use default (~/.aisbf/key.pem). Auto-generated with certificate.</small>
        </div>
    </div>
    </div><!-- /tab-server -->
    
    <div class="settings-section" id="tab-auth">
    <div class="section-title"><i class="fas fa-key"></i> <span data-i18n="settings_page.section_auth">Authentication</span></div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="auth_enabled" {% if config.auth.enabled %}checked{% endif %}>
            <span data-i18n="settings_page.lbl_enable_auth">Enable API Authentication</span>
        </label>
    </div>
    
    <div class="form-group">
        <label for="auth_tokens" data-i18n="settings_page.lbl_auth_tokens">Auth Tokens (one per line)</label>
        <textarea id="auth_tokens" name="auth_tokens" style="min-height: 100px;">{{ '\n'.join(config.auth.tokens) }}</textarea>
    </div>
    
    <div class="section-title" style="margin-top:28px;"><i class="fas fa-network-wired"></i> <span data-i18n="settings_page.section_mcp">MCP Server</span></div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="mcp_enabled" {% if config.mcp.enabled %}checked{% endif %}>
            <span data-i18n="settings_page.lbl_enable_mcp">Enable MCP Server</span>
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Model Context Protocol server for remote agent configuration</small>
    </div>
    
    <div class="form-group">
        <label for="autoselect_tokens" data-i18n="settings_page.lbl_autoselect_tokens">Autoselect Tokens (one per line)</label>
        <textarea id="autoselect_tokens" name="autoselect_tokens" style="min-height: 80px;" placeholder="Tokens for autoselection/autorotation access">{{ '\n'.join(config.mcp.autoselect_tokens) if config.mcp.autoselect_tokens else '' }}</textarea>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Tokens that give access to autoselection and autorotation settings + standard APIs</small>
    </div>
    
    <div class="form-group">
        <label for="fullconfig_tokens" data-i18n="settings_page.lbl_fullconfig_tokens">Full Config Tokens (one per line)</label>
        <textarea id="fullconfig_tokens" name="fullconfig_tokens" style="min-height: 80px;" placeholder="Tokens for full configuration access">{{ '\n'.join(config.mcp.fullconfig_tokens) if config.mcp.fullconfig_tokens else '' }}</textarea>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Tokens that give access to full system configuration + standard APIs</small>
    </div>
    </div><!-- /tab-auth -->
    
    <div class="settings-section" id="tab-models">
    <div class="section-title"><i class="fas fa-brain"></i> <span data-i18n="settings_page.section_models">Internal Models</span></div>

    <datalist id="meta-targets-dl">
        {% for t in meta_targets or [] %}<option value="{{ t }}">{% endfor %}
    </datalist>

    <div class="form-group">
        <label for="condensation_model_id" data-i18n="settings_page.lbl_condensation_model">Condensation Model ID</label>
        <div style="display:flex; gap:8px; align-items:center;">
            <input type="text" id="condensation_model_id" name="condensation_model_id" value="{{ config.internal_model.condensation_model_id }}" required style="flex:1;">
            <button type="button" class="btn btn-secondary" style="white-space:nowrap; padding:6px 12px; font-size:.85em;" onclick="clearModelCache(document.getElementById('condensation_model_id').value, 'condensation', this)"><i class="fas fa-trash-alt"></i> Clear Cache</button>
        </div>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Used when condensation model is set to "internal"</small>
        <label for="condensation_override" style="margin-top:8px;">↳ Rotation/Autoselect override <span style="color:var(--color-subtle);font-weight:normal;">(optional — overrides the local model above)</span></label>
        <input type="text" id="condensation_override" name="condensation_override" list="meta-targets-dl" value="{{ config.internal_model.condensation_override or '' }}" placeholder="rotation or autoselect name (leave empty to use local model)" style="width:100%;">
    </div>

    <div class="form-group">
        <label for="condensation_max_tokens">Condensation Max Tokens</label>
        <input type="number" id="condensation_max_tokens" name="condensation_max_tokens" value="{{ config.internal_model.condensation_max_tokens or 1000 }}" min="64" max="32000" style="width:160px;">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Max tokens the condensation model can generate per summary (default 1000).</small>
    </div>

    <div class="form-group">
        <label for="autoselect_model_id" data-i18n="settings_page.lbl_autoselect_model">Autoselect Model ID</label>
        <div style="display:flex; gap:8px; align-items:center;">
            <input type="text" id="autoselect_model_id" name="autoselect_model_id" value="{{ config.internal_model.autoselect_model_id }}" required style="flex:1;">
            <button type="button" class="btn btn-secondary" style="white-space:nowrap; padding:6px 12px; font-size:.85em;" onclick="clearModelCache(document.getElementById('autoselect_model_id').value, 'autoselect', this)"><i class="fas fa-trash-alt"></i> Clear Cache</button>
        </div>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Used when autoselect selection_model is set to "internal"</small>
        <label for="autoselect_override" style="margin-top:8px;">↳ Rotation/Autoselect override <span style="color:var(--color-subtle);font-weight:normal;">(optional — overrides the local model above)</span></label>
        <input type="text" id="autoselect_override" name="autoselect_override" list="meta-targets-dl" value="{{ config.internal_model.autoselect_override or '' }}" placeholder="rotation or autoselect name (leave empty to use local model)" style="width:100%;">
    </div>

    <div class="form-group">
        <label for="autoselect_max_tokens" data-i18n="settings_page.lbl_autoselect_max_tokens">Autoselect Context Limit (tokens)</label>
        <input type="number" id="autoselect_max_tokens" name="autoselect_max_tokens" value="{{ config.internal_model.autoselect_max_tokens or 8000 }}" min="256" max="200000" style="width:160px;">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Max tokens of conversation context sent to the internal autoselect model (default 8000). Ignored when selection_model is a rotation or provider/model.</small>
    </div>

    <div class="form-group">
        <label for="nsfw_classifier" data-i18n="settings_page.lbl_nsfw_classifier">NSFW Classifier Model ID</label>
        <div style="display:flex; gap:8px; align-items:center;">
            <input type="text" id="nsfw_classifier" name="nsfw_classifier" value="{{ config.internal_model.nsfw_classifier or 'michelleli99/NSFW_text_classifier' }}" required style="flex:1;">
            <button type="button" class="btn btn-secondary" style="white-space:nowrap; padding:6px 12px; font-size:.85em;" onclick="clearModelCache(document.getElementById('nsfw_classifier').value, 'nsfw', this)"><i class="fas fa-trash-alt"></i> Clear Cache</button>
        </div>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Model used for NSFW content detection</small>
        <label for="nsfw_classifier_override" style="margin-top:8px;">↳ Rotation/Autoselect override <span style="color:var(--color-subtle);font-weight:normal;">(optional — prompts a chat model for YES/NO, falls back to local)</span></label>
        <input type="text" id="nsfw_classifier_override" name="nsfw_classifier_override" list="meta-targets-dl" value="{{ config.internal_model.nsfw_classifier_override or '' }}" placeholder="rotation or autoselect name (leave empty to use local classifier)" style="width:100%;">
    </div>

    <div class="form-group">
        <label for="privacy_classifier" data-i18n="settings_page.lbl_privacy_classifier">Privacy Classifier Model ID</label>
        <div style="display:flex; gap:8px; align-items:center;">
            <input type="text" id="privacy_classifier" name="privacy_classifier" value="{{ config.internal_model.privacy_classifier or 'iiiorg/piiranha-v1-detect-personal-information' }}" required style="flex:1;">
            <button type="button" class="btn btn-secondary" style="white-space:nowrap; padding:6px 12px; font-size:.85em;" onclick="clearModelCache(document.getElementById('privacy_classifier').value, 'privacy', this)"><i class="fas fa-trash-alt"></i> Clear Cache</button>
        </div>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Model used for privacy-sensitive information detection</small>
        <label for="privacy_classifier_override" style="margin-top:8px;">↳ Rotation/Autoselect override <span style="color:var(--color-subtle);font-weight:normal;">(optional — prompts a chat model for YES/NO, falls back to local)</span></label>
        <input type="text" id="privacy_classifier_override" name="privacy_classifier_override" list="meta-targets-dl" value="{{ config.internal_model.privacy_classifier_override or '' }}" placeholder="rotation or autoselect name (leave empty to use local classifier)" style="width:100%;">
    </div>

    <div class="form-group">
        <label for="semantic_vectorization" data-i18n="settings_page.lbl_semantic_vectorization">Semantic Vectorization Model ID</label>
        <div style="display:flex; gap:8px; align-items:center;">
            <input type="text" id="semantic_vectorization" name="semantic_vectorization" value="{{ config.internal_model.semantic_vectorization or 'sentence-transformers/all-MiniLM-L6-v2' }}" required style="flex:1;">
            <button type="button" class="btn btn-secondary" style="white-space:nowrap; padding:6px 12px; font-size:.85em;" onclick="clearModelCache(document.getElementById('semantic_vectorization').value, 'semantic', this)"><i class="fas fa-trash-alt"></i> Clear Cache</button>
        </div>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Model used for semantic embedding and vectorization</small>
    </div>

    <div style="margin-top:20px; padding-top:16px; border-top:1px solid #0f3460;">
        <button type="button" class="btn" style="background:#b71c1c; border-color:#b71c1c;" onclick="clearAllModelCaches(this)">
            <i class="fas fa-trash-alt"></i> Clear All Local Model Caches
        </button>
        <small style="color:#666; display:block; margin-top:8px;">Removes all locally cached model files and unloads them from memory. Models will be re-downloaded from HuggingFace on next use.</small>
    </div>
    </div><!-- /tab-models -->

    <div class="settings-section" id="tab-database">
    <div class="section-title"><i class="fas fa-database"></i> <span data-i18n="settings_page.section_database">Database Configuration</span></div>

    <div class="form-group">
        <label for="database_type" data-i18n="settings_page.lbl_database_type">Database Type</label>
        <select id="database_type" name="database_type" onchange="toggleDatabaseFields()">
            <option value="sqlite" {% if config.database and config.database.type == 'sqlite' %}selected{% endif %}>SQLite</option>
            <option value="mysql" {% if config.database and config.database.type == 'mysql' %}selected{% endif %}>MySQL</option>
        </select>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Choose the database backend (SQLite is recommended for most users)</small>
    </div>

    <div id="sqlite-fields" style="display: {% if not config.database or config.database.type == 'sqlite' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="db_sqlite_path" data-i18n="settings_page.lbl_sqlite_path">SQLite Database Path</label>
            <input type="text" id="db_sqlite_path" name="sqlite_path" value="{{ config.database.sqlite_path if config.database and config.database.sqlite_path else '~/.aisbf/aisbf.db' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Path to SQLite database file (supports ~ expansion)</small>
        </div>
    </div>

    <div id="mysql-fields" style="display: {% if config.database and config.database.type == 'mysql' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="mysql_host" data-i18n="settings_page.lbl_mysql_host">MySQL Host</label>
            <input type="text" id="mysql_host" name="mysql_host" value="{{ config.database.mysql_host if config.database and config.database.mysql_host else 'localhost' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL server hostname or IP address</small>
        </div>

        <div class="form-group">
            <label for="mysql_port" data-i18n="settings_page.lbl_mysql_port">MySQL Port</label>
            <input type="number" id="mysql_port" name="mysql_port" value="{{ config.database.mysql_port if config.database and config.database.mysql_port else 3306 }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL server port (default: 3306)</small>
        </div>

        <div class="form-group">
            <label for="mysql_user" data-i18n="settings_page.lbl_mysql_user">MySQL Username</label>
            <input type="text" id="mysql_user" name="mysql_user" value="{{ config.database.mysql_user if config.database and config.database.mysql_user else 'aisbf' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL database username</small>
        </div>

        <div class="form-group">
            <label for="mysql_password" data-i18n="settings_page.lbl_mysql_password">MySQL Password</label>
            <input type="password" id="mysql_password" name="mysql_password" placeholder="Leave blank to keep current">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL database password</small>
        </div>

        <div class="form-group">
            <label for="mysql_database" data-i18n="settings_page.lbl_mysql_database">MySQL Database Name</label>
            <input type="text" id="mysql_database" name="mysql_database" value="{{ config.database.mysql_database if config.database and config.database.mysql_database else 'aisbf' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL database name</small>
        </div>
    </div>
    </div><!-- /tab-database -->

    <div class="settings-section" id="tab-cache">
    <div class="section-title"><i class="fas fa-bolt"></i> <span data-i18n="settings_page.section_cache">Cache Configuration</span></div>

    <div class="form-group">
        <label for="cache_type" data-i18n="settings_page.lbl_cache_type">Cache Type</label>
        <select id="cache_type" name="cache_type" onchange="toggleCacheFields()">
            <option value="sqlite" {% if config.cache and config.cache.type == 'sqlite' %}selected{% endif %}>SQLite</option>
            <option value="mysql" {% if config.cache and config.cache.type == 'mysql' %}selected{% endif %}>MySQL</option>
            <option value="redis" {% if config.cache and config.cache.type == 'redis' %}selected{% endif %}>Redis</option>
            <option value="file" {% if config.cache and config.cache.type == 'file' %}selected{% endif %}>File-based</option>
            <option value="memory" {% if not config.cache or config.cache.type == 'memory' %}selected{% endif %}>Memory</option>
        </select>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Choose the cache backend for model embeddings and other cached data (SQLite recommended for most users)</small>
    </div>

    <div id="sqlite-cache-fields" style="display: {% if config.cache and config.cache.type == 'sqlite' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="cache_sqlite_path" data-i18n="settings_page.lbl_cache_sqlite_path">SQLite Cache Path</label>
            <input type="text" id="cache_sqlite_path" name="sqlite_path" value="{{ config.cache.sqlite_path if config.cache and config.cache.sqlite_path else '~/.aisbf/cache.db' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Path to SQLite cache database file (supports ~ expansion)</small>
        </div>
    </div>

    <div id="mysql-cache-fields" style="display: {% if config.cache and config.cache.type == 'mysql' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="mysql_cache_host" data-i18n="settings_page.lbl_mysql_host">MySQL Host</label>
            <input type="text" id="mysql_cache_host" name="mysql_cache_host" value="{{ config.cache.mysql_host if config.cache and config.cache.mysql_host else 'localhost' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL server hostname or IP address</small>
        </div>

        <div class="form-group">
            <label for="mysql_cache_port" data-i18n="settings_page.lbl_mysql_port">MySQL Port</label>
            <input type="number" id="mysql_cache_port" name="mysql_cache_port" value="{{ config.cache.mysql_port if config.cache and config.cache.mysql_port else 3306 }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL server port (default: 3306)</small>
        </div>

        <div class="form-group">
            <label for="mysql_cache_user" data-i18n="settings_page.lbl_mysql_user">MySQL Username</label>
            <input type="text" id="mysql_cache_user" name="mysql_cache_user" value="{{ config.cache.mysql_user if config.cache and config.cache.mysql_user else 'aisbf' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL database username</small>
        </div>

        <div class="form-group">
            <label for="mysql_cache_password" data-i18n="settings_page.lbl_mysql_password">MySQL Password</label>
            <input type="password" id="mysql_cache_password" name="mysql_cache_password" placeholder="Leave blank to keep current">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL database password</small>
        </div>

        <div class="form-group">
            <label for="mysql_cache_database" data-i18n="settings_page.lbl_mysql_database">MySQL Database Name</label>
            <input type="text" id="mysql_cache_database" name="mysql_cache_database" value="{{ config.cache.mysql_database if config.cache and config.cache.mysql_database else 'aisbf_cache' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">MySQL database name for cache</small>
        </div>
    </div>

    <div id="redis-cache-fields" style="display: {% if config.cache and config.cache.type == 'redis' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="redis_host" data-i18n="settings_page.lbl_redis_host">Redis Host</label>
            <input type="text" id="redis_host" name="redis_host" value="{{ config.cache.redis_host if config.cache and config.cache.redis_host else 'localhost' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Redis server hostname or IP address</small>
        </div>

        <div class="form-group">
            <label for="redis_port" data-i18n="settings_page.lbl_redis_port">Redis Port</label>
            <input type="number" id="redis_port" name="redis_port" value="{{ config.cache.redis_port if config.cache and config.cache.redis_port else 6379 }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Redis server port (default: 6379)</small>
        </div>

        <div class="form-group">
            <label for="redis_db" data-i18n="settings_page.lbl_redis_db">Redis Database</label>
            <input type="number" id="redis_db" name="redis_db" value="{{ config.cache.redis_db if config.cache and config.cache.redis_db else 0 }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Redis database number (default: 0)</small>
        </div>

        <div class="form-group">
            <label for="redis_password" data-i18n="settings_page.lbl_redis_password">Redis Password</label>
            <input type="password" id="redis_password" name="redis_password" placeholder="Leave blank if no password">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Redis password (optional)</small>
        </div>

        <div class="form-group">
            <label for="redis_key_prefix" data-i18n="settings_page.lbl_redis_key_prefix">Redis Key Prefix</label>
            <input type="text" id="redis_key_prefix" name="redis_key_prefix" value="{{ config.cache.redis_key_prefix if config.cache and config.cache.redis_key_prefix else 'aisbf:' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Prefix for Redis keys (default: aisbf:)</small>
        </div>
    </div>

    <h3 style="margin: 24px 0 16px; font-size:1em; color:#a0a0a0; border-bottom: 1px solid var(--color-border); padding-bottom:8px;">Response Cache Configuration</h3>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="response_cache_enabled" {% if config.response_cache and config.response_cache.enabled %}checked{% endif %}>
            Enable Response Cache
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Cache API responses to improve performance and reduce costs</small>
    </div>
    
    <div class="form-group">
        <label for="response_cache_backend" data-i18n="settings_page.lbl_response_cache_backend">Response Cache Backend</label>
        <select id="response_cache_backend" name="response_cache_backend" onchange="toggleResponseCacheFields()">
            <option value="memory" {% if config.response_cache and config.response_cache.backend == 'memory' %}selected{% endif %}>Memory</option>
            <option value="sqlite" {% if config.response_cache and config.response_cache.backend == 'sqlite' %}selected{% endif %}>SQLite</option>
            <option value="redis" {% if config.response_cache and config.response_cache.backend == 'redis' %}selected{% endif %}>Redis</option>
            <option value="mysql" {% if config.response_cache and config.response_cache.backend == 'mysql' %}selected{% endif %}>MySQL</option>
        </select>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Choose the backend for response caching</small>
    </div>
    
    <div class="form-group">
        <label for="response_cache_ttl" data-i18n="settings_page.lbl_cache_ttl">Cache TTL (seconds)</label>
        <input type="number" id="response_cache_ttl" name="response_cache_ttl" value="{{ config.response_cache.ttl if config.response_cache else 600 }}" min="1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Time to live for cached responses (default: 600 seconds)</small>
    </div>
    
    <div class="form-group">
        <label for="response_cache_max_memory" data-i18n="settings_page.lbl_cache_max_memory">Max Memory Cache Size</label>
        <input type="number" id="response_cache_max_memory" name="response_cache_max_memory" value="{{ config.response_cache.max_memory_cache if config.response_cache else 1000 }}" min="1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Maximum number of items in memory cache (default: 1000)</small>
    </div>
    
    <div id="response-cache-redis-fields" style="display: {% if config.response_cache and config.response_cache.backend == 'redis' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="response_cache_redis_host" data-i18n="settings_page.lbl_redis_host">Redis Host</label>
            <input type="text" id="response_cache_redis_host" name="response_cache_redis_host" value="{{ config.response_cache.redis_host if config.response_cache else 'localhost' }}">
        </div>
        
        <div class="form-group">
            <label for="response_cache_redis_port" data-i18n="settings_page.lbl_redis_port">Redis Port</label>
            <input type="number" id="response_cache_redis_port" name="response_cache_redis_port" value="{{ config.response_cache.redis_port if config.response_cache else 6379 }}">
        </div>
        
        <div class="form-group">
            <label for="response_cache_redis_db" data-i18n="settings_page.lbl_redis_db">Redis Database</label>
            <input type="number" id="response_cache_redis_db" name="response_cache_redis_db" value="{{ config.response_cache.redis_db if config.response_cache else 0 }}">
        </div>
        
        <div class="form-group">
            <label for="response_cache_redis_password" data-i18n="settings_page.lbl_redis_password">Redis Password</label>
            <input type="password" id="response_cache_redis_password" name="response_cache_redis_password" placeholder="Leave blank if no password">
        </div>
        
        <div class="form-group">
            <label for="response_cache_redis_key_prefix" data-i18n="settings_page.lbl_redis_key_prefix">Redis Key Prefix</label>
            <input type="text" id="response_cache_redis_key_prefix" name="response_cache_redis_key_prefix" value="{{ config.response_cache.redis_key_prefix if config.response_cache else 'aisbf:response:' }}">
        </div>
    </div>
    
    <div id="response-cache-sqlite-fields" style="display: {% if config.response_cache and config.response_cache.backend == 'sqlite' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="response_cache_sqlite_path" data-i18n="settings_page.lbl_sqlite_path">SQLite Path</label>
            <input type="text" id="response_cache_sqlite_path" name="response_cache_sqlite_path" value="{{ config.response_cache.sqlite_path if config.response_cache else '~/.aisbf/response_cache.db' }}">
        </div>
    </div>
    
    <div id="response-cache-mysql-fields" style="display: {% if config.response_cache and config.response_cache.backend == 'mysql' %}block{% else %}none{% endif %};">
        <div class="form-group">
            <label for="response_cache_mysql_host" data-i18n="settings_page.lbl_mysql_host">MySQL Host</label>
            <input type="text" id="response_cache_mysql_host" name="response_cache_mysql_host" value="{{ config.response_cache.mysql_host if config.response_cache else 'localhost' }}">
        </div>
        
        <div class="form-group">
            <label for="response_cache_mysql_port" data-i18n="settings_page.lbl_mysql_port">MySQL Port</label>
            <input type="number" id="response_cache_mysql_port" name="response_cache_mysql_port" value="{{ config.response_cache.mysql_port if config.response_cache else 3306 }}">
        </div>
        
        <div class="form-group">
            <label for="response_cache_mysql_user" data-i18n="settings_page.lbl_mysql_user">MySQL Username</label>
            <input type="text" id="response_cache_mysql_user" name="response_cache_mysql_user" value="{{ config.response_cache.mysql_user if config.response_cache else 'aisbf' }}">
        </div>
        
        <div class="form-group">
            <label for="response_cache_mysql_password" data-i18n="settings_page.lbl_mysql_password">MySQL Password</label>
            <input type="password" id="response_cache_mysql_password" name="response_cache_mysql_password" placeholder="Leave blank to keep current">
        </div>
        
        <div class="form-group">
            <label for="response_cache_mysql_database" data-i18n="settings_page.lbl_mysql_database">MySQL Database</label>
            <input type="text" id="response_cache_mysql_database" name="response_cache_mysql_database" value="{{ config.response_cache.mysql_database if config.response_cache else 'aisbf_response_cache' }}">
        </div>
    </div>

    <h3 style="margin: 24px 0 16px; font-size:1em; color:var(--color-muted); border-bottom: 1px solid var(--color-border); padding-bottom:8px;">Response Cache</h3>
    
    <div id="cache-stats" style="margin-bottom: 20px; padding: 15px; background: var(--bg-accent); border-radius: 6px; border-left: 4px solid var(--color-border);">
        <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
            <strong>Status:</strong>
            <span id="cache-stats-text" style="color: var(--color-subtle);">Loading...</span>
        </div>
        <div id="cache-stats-details" style="display: none; margin-top: 10px;">
            <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;">
                <div style="background: var(--bg-panel); padding: 10px; border-radius: 4px;">
                    <div style="color: var(--color-subtle); font-size: 0.9em;">Hits</div>
                    <div id="cache-hits" style="font-size: 1.2em; font-weight: bold; color: #4ade80;">0</div>
                </div>
                <div style="background: var(--bg-panel); padding: 10px; border-radius: 4px;">
                    <div style="color: var(--color-subtle); font-size: 0.9em;">Misses</div>
                    <div id="cache-misses" style="font-size: 1.2em; font-weight: bold; color: #fbbf24;">0</div>
                </div>
                <div style="background: var(--bg-panel); padding: 10px; border-radius: 4px;">
                    <div style="color: var(--color-subtle); font-size: 0.9em;">Hit Rate</div>
                    <div id="cache-hit-rate" style="font-size: 1.2em; font-weight: bold; color: var(--color-link);">0%</div>
                </div>
                <div style="background: var(--bg-panel); padding: 10px; border-radius: 4px;">
                    <div style="color: var(--color-subtle); font-size: 0.9em;">Size</div>
                    <div id="cache-size" style="font-size: 1.2em; font-weight: bold; color: var(--color-text);">0</div>
                </div>
                <div style="background: var(--bg-panel); padding: 10px; border-radius: 4px;">
                    <div style="color: var(--color-subtle); font-size: 0.9em;">Evictions</div>
                    <div id="cache-evictions" style="font-size: 1.2em; font-weight: bold; color: var(--alert-error-fg);">0</div>
                </div>
                <div style="background: var(--bg-panel); padding: 10px; border-radius: 4px;">
                    <div style="color: var(--color-subtle); font-size: 0.9em;">Backend</div>
                    <div id="cache-backend" style="font-size: 1.2em; font-weight: bold; color: var(--color-link);">-</div>
                </div>
            </div>
            <div style="margin-top: 10px;">
                <button type="button" onclick="clearResponseCache()" class="btn btn-danger" style="border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">Clear Cache</button>
                <button type="button" onclick="refreshCacheStats()" class="btn btn-secondary" style="margin-left: 10px; padding: 8px 16px; border-radius: 4px; cursor: pointer;">Refresh</button>
            </div>
        </div>
    </div>

    </div><!-- /tab-cache -->

    <div class="settings-section" id="tab-classification">
    <div class="section-title"><i class="fas fa-filter"></i> <span data-i18n="settings_page.section_classification">Features &amp; Prompt Analysis</span></div>
    <p style="color: var(--color-muted); margin-bottom: 18px;">Global defaults for legacy classifiers, execution features, and prompt analysis / security controls.</p>

    <div class="form-group">
        <label>
            <input type="checkbox" name="classify_nsfw" {% if config.classify_nsfw %}checked{% endif %}>
            Enable NSFW Classification
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Enable automatic NSFW content detection for model selection</small>
    </div>

    <div class="form-group">
        <label>
            <input type="checkbox" name="classify_privacy" {% if config.classify_privacy %}checked{% endif %}>
            Enable Privacy Classification
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Enable automatic privacy-sensitive content detection for model selection</small>
    </div>

    <div class="form-group">
        <label>
            <input type="checkbox" name="classify_semantic" {% if config.classify_semantic %}checked{% endif %}>
            Enable Semantic Classification
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Enable semantic content classification using the configured model</small>
    </div>

    <div class="section-title" style="margin-top:28px;"><i class="fas fa-sliders-h"></i> Global Feature Defaults</div>
    <p style="color:var(--color-muted);margin-bottom:16px;font-size:.9em;">These are the global defaults used by provider, model, rotation, and autoselect overrides when they inherit behavior.</p>
    {% set feature_controls = config.feature_controls if config.feature_controls else none %}
    {% set prompt_security = feature_controls.prompt_security if feature_controls and feature_controls.prompt_security else none %}
    <div class="tri-grid">
        {{ bool_mode_select('feature_nsfw_classification_mode', feature_controls.nsfw_classification.mode if feature_controls and feature_controls.nsfw_classification else 'disabled', 'NSFW Classification', 'Default NSFW classification behavior.') }}
        {{ bool_mode_select('feature_privacy_classification_mode', feature_controls.privacy_classification.mode if feature_controls and feature_controls.privacy_classification else 'disabled', 'Privacy Classification', 'Default privacy classification behavior.') }}
        {{ bool_mode_select('feature_context_condensation_mode', feature_controls.context_condensation.mode if feature_controls and feature_controls.context_condensation else 'disabled', 'Context Condensation', 'Default context condensation behavior.') }}
        {{ bool_mode_select('feature_response_cache_mode', feature_controls.response_cache.mode if feature_controls and feature_controls.response_cache else 'disabled', 'Response Cache', 'Default response-cache behavior.') }}
        {{ bool_mode_select('feature_prompt_batching_mode', feature_controls.prompt_batching.mode if feature_controls and feature_controls.prompt_batching else 'disabled', 'Prompt Batching', 'Default batching behavior.') }}
        {{ bool_mode_select('feature_prompt_security_mode', prompt_security.security_scan.mode if prompt_security and prompt_security.security_scan else 'disabled', 'Prompt Security', 'Default local prompt scanning behavior.') }}
        {{ bool_mode_select('feature_context_lens_mode', prompt_security.context_lens.mode if prompt_security and prompt_security.context_lens else 'disabled', 'Context Lens Analytics', 'Default prompt composition analytics behavior.') }}
        {{ bool_mode_select('feature_block_high_risk_prompts_mode', prompt_security.block_high_risk_prompts.mode if prompt_security and prompt_security.block_high_risk_prompts else 'disabled', 'Block High-Risk Prompts', 'Default local high-risk blocking behavior.') }}
    </div>

    <div class="section-title" style="margin-top:28px;"><i class="fas fa-shield-alt"></i> Prompt Security Persistence</div>
    <p style="color:var(--color-muted);margin-bottom:16px;font-size:.9em;">Controls how prompt analysis findings are stored when prompt-security features are active.</p>
    <div class="tri-grid">
        {{ bool_mode_select('feature_persist_prompt_text_mode', prompt_security.persist_prompt_text.mode if prompt_security and prompt_security.persist_prompt_text else 'disabled', 'Persist Prompt Text', 'Store prompt text with prompt-analysis records when allowed.') }}
        {{ bool_mode_select('feature_redact_before_persist_mode', prompt_security.redact_before_persist.mode if prompt_security and prompt_security.redact_before_persist else 'enabled', 'Redact Before Persist', 'Redact sensitive fragments before storing prompt-analysis records.') }}
    </div>

    <div class="form-group" style="margin-top: 18px; max-width: 340px;">
        <label for="feature_risk_threshold">Prompt Security Risk Threshold</label>
        <select id="feature_risk_threshold" name="feature_risk_threshold">
            {% set risk_threshold = prompt_security.risk_threshold if prompt_security and prompt_security.risk_threshold else 'high' %}
            <option value="low" {% if risk_threshold == 'low' %}selected{% endif %}>Low</option>
            <option value="medium" {% if risk_threshold == 'medium' %}selected{% endif %}>Medium</option>
            <option value="high" {% if risk_threshold == 'high' %}selected{% endif %}>High</option>
        </select>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Minimum risk level that should be treated as high-risk for blocking and alerting.</small>
    </div>
    </div><!-- /tab-classification -->

    <div class="settings-section" id="tab-tor">
    <div class="section-title"><i class="fas fa-user-secret"></i> <span data-i18n="settings_page.section_tor">TOR Hidden Service</span></div>
    
    <div id="tor-status" style="margin-bottom: 20px; padding: 15px; background: var(--bg-accent); border-radius: 6px; border-left: 4px solid #16213e;">
        <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
            <strong>Status:</strong>
            <span id="tor-status-text" style="color: var(--color-subtle);">Loading...</span>
        </div>
        <div id="tor-onion-address" style="display: none; margin-top: 10px;">
            <strong>Onion Address:</strong>
            <code id="tor-onion-value" style="background: var(--bg-panel); padding: 5px 10px; border-radius: 4px; display: inline-block; margin-left: 10px;"></code>
        </div>
    </div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="tor_enabled" id="tor_enabled" {% if config.tor and config.tor.enabled %}checked{% endif %} onchange="toggleTorFields()">
            <span data-i18n="settings_page.lbl_enable_tor">Enable TOR Hidden Service</span>
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Expose AISBF over TOR network as a hidden service</small>
    </div>
    
    <div id="tor-fields" style="display: {% if config.tor and config.tor.enabled %}block{% else %}none{% endif %};">
        
        <!-- torrc Configuration Instructions -->
        <div style="background: var(--bg-panel); padding: 15px; border-radius: 6px; margin-bottom: 20px; border-left: 4px solid var(--color-link);">
            <h4 style="margin: 0 0 10px 0; color: var(--color-link);">⚙️ Required torrc Configuration</h4>
            <p style="margin: 0 0 10px 0; color: var(--color-muted);">Before enabling Tor, you must configure your torrc file (usually <code style="background: var(--bg-accent); padding: 2px 6px; border-radius: 3px;">/etc/tor/torrc</code>):</p>
            
            <div style="background: var(--bg-accent); padding: 12px; border-radius: 4px; margin-bottom: 10px;">
                <strong style="color: #4ade80;">Step 1: Generate Password Hash</strong>
                <pre style="margin: 8px 0 0 0; padding: 8px; background: var(--bg-page); border-radius: 3px; overflow-x: auto;"><code>tor --hash-password "your_secure_password"</code></pre>
            </div>
            
            <div style="background: var(--bg-accent); padding: 12px; border-radius: 4px; margin-bottom: 10px;">
                <strong style="color: #4ade80;">Step 2: Add to torrc</strong>
                <div style="margin-top: 8px;">
                    <button type="button" onclick="toggleTorrcExample('ephemeral')" class="btn btn-secondary" style="padding: 6px 12px; border-radius: 3px; cursor: pointer; margin-right: 8px;">Ephemeral Service</button>
                    <button type="button" onclick="toggleTorrcExample('persistent')" class="btn btn-secondary" style="padding: 6px 12px; border-radius: 3px; cursor: pointer;">Persistent Service</button>
                </div>
                
                <div id="torrc-ephemeral" style="display: none; margin-top: 10px;">
                    <p style="margin: 0 0 8px 0; color: #ccc; font-size: 0.9em;">For temporary hidden service (new address each restart):</p>
                    <pre style="margin: 0; padding: 8px; background: #000; border-radius: 3px; overflow-x: auto;"><code>ControlPort 9051
HashedControlPassword 16:YOUR_HASHED_PASSWORD_HERE</code></pre>
                    <p style="margin: 8px 0 0 0; color: #ff9800; font-size: 0.85em;">⚠️ Leave "Hidden Service Directory" field blank below for ephemeral service</p>
                </div>
                
                <div id="torrc-persistent" style="display: none; margin-top: 10px;">
                    <p style="margin: 0 0 8px 0; color: #ccc; font-size: 0.9em;">For permanent hidden service (same address across restarts):</p>
                    <pre style="margin: 0; padding: 8px; background: #000; border-radius: 3px; overflow-x: auto;"><code>ControlPort 9051
HashedControlPassword 16:YOUR_HASHED_PASSWORD_HERE

HiddenServiceDir <span id="torrc-hs-dir">/home/yourusername/.aisbf/tor_hidden_service</span>
HiddenServicePort <span id="torrc-hs-port">80</span> 127.0.0.1:<span id="torrc-local-port">{{ config.server.port if config.server else 17765 }}</span></code></pre>
                    <p style="margin: 8px 0 0 0; color: #ff9800; font-size: 0.85em;">⚠️ Replace <code style="background: var(--bg-panel); padding: 2px 4px; border-radius: 2px;">/home/yourusername</code> with your actual home directory path (torrc does NOT expand ~)</p>
                </div>
            </div>
            
            <div style="background: var(--bg-accent); padding: 12px; border-radius: 4px;">
                <strong style="color: #4caf50;">Step 3: Restart Tor</strong>
                <pre style="margin: 8px 0 0 0; padding: 8px; background: #000; border-radius: 3px; overflow-x: auto;"><code>sudo systemctl restart tor  # Linux
brew services restart tor   # macOS</code></pre>
            </div>
        </div>
        
        <div class="form-group">
            <label for="tor_control_host" data-i18n="settings_page.lbl_tor_control_host">TOR Control Host</label>
            <input type="text" id="tor_control_host" name="tor_control_host" value="{{ config.tor.control_host if config.tor else '127.0.0.1' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">TOR control port host (default: 127.0.0.1)</small>
        </div>
        
        <div class="form-group">
            <label for="tor_control_port" data-i18n="settings_page.lbl_tor_control_port">TOR Control Port</label>
            <input type="number" id="tor_control_port" name="tor_control_port" value="{{ config.tor.control_port if config.tor else 9051 }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">TOR control port (default: 9051) - must match ControlPort in torrc</small>
        </div>
        
        <div class="form-group">
            <label for="tor_control_password" data-i18n="settings_page.lbl_tor_control_password">TOR Control Password</label>
            <input type="password" id="tor_control_password" name="tor_control_password" value="{{ config.tor.control_password if config.tor and config.tor.control_password else '' }}" placeholder="Enter the password you used to generate the hash">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">The password you used with <code>tor --hash-password</code> (NOT the hash itself)</small>
        </div>
        
        <div class="form-group">
            <label for="tor_hidden_service_dir" data-i18n="settings_page.lbl_tor_service_dir">Hidden Service Directory</label>
            <div style="display: flex; gap: 10px; align-items: flex-start;">
                <input type="text" id="tor_hidden_service_dir" name="tor_hidden_service_dir" value="{{ config.tor.hidden_service_dir if config.tor and config.tor.hidden_service_dir else '' }}" placeholder="Leave blank for ephemeral service" style="flex: 1;" onchange="updateTorrcExample()">
                <button type="button" onclick="createPersistentService()" class="btn btn-secondary" style="white-space: nowrap;">Use Default</button>
            </div>
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">
                <strong>Ephemeral:</strong> Leave blank for temporary service (new address each restart)<br>
                <strong>Persistent:</strong> Enter full absolute path (e.g., /home/username/.aisbf/tor_hidden_service) - must match HiddenServiceDir in torrc<br>
                <span style="color: #ff9800;">⚠️ Note: torrc does NOT expand ~ - use full paths like /home/username instead</span>
            </small>
        </div>
        
        <div class="form-group">
            <label for="tor_hidden_service_port" data-i18n="settings_page.lbl_tor_service_port">Hidden Service Port</label>
            <input type="number" id="tor_hidden_service_port" name="tor_hidden_service_port" value="{{ config.tor.hidden_service_port if config.tor else 80 }}" onchange="updateTorrcExample()">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Port exposed on the onion address (default: 80) - must match HiddenServicePort in torrc for persistent services</small>
        </div>
        
        <div class="form-group">
            <label for="tor_socks_host" data-i18n="settings_page.lbl_socks_host">SOCKS Proxy Host</label>
            <input type="text" id="tor_socks_host" name="tor_socks_host" value="{{ config.tor.socks_host if config.tor else '127.0.0.1' }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">TOR SOCKS proxy host (default: 127.0.0.1)</small>
        </div>
        
        <div class="form-group">
            <label for="tor_socks_port" data-i18n="settings_page.lbl_socks_port">SOCKS Proxy Port</label>
            <input type="number" id="tor_socks_port" name="tor_socks_port" value="{{ config.tor.socks_port if config.tor else 9050 }}">
            <small style="color: var(--color-subtle); display: block; margin-top: 5px;">TOR SOCKS proxy port (default: 9050)</small>
        </div>
    </div>
    </div><!-- /tab-tor -->

    <div class="settings-section" id="tab-signup">
    <div class="section-title"><i class="fas fa-user-plus"></i> User Signup</div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="signup_enabled" {% if config.signup and config.signup.enabled %}checked{% endif %}>
            Enable User Signup
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Allow users to create accounts via signup form</small>
    </div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="signup_require_verification" {% if config.signup and config.signup.require_email_verification %}checked{% endif %}>
            <span data-i18n="settings_page.lbl_require_email">Require Email Verification</span>
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Users must verify their email before they can login</small>
    </div>
    
    <div class="form-group">
        <label for="verification_token_expiry" data-i18n="settings_page.lbl_token_expiry">Verification Token Expiry (hours)</label>
        <input type="number" id="verification_token_expiry" name="verification_token_expiry"
               value="{{ config.signup.verification_token_expiry_hours if config.signup else 24 }}"
               min="1" max="168">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">How long verification links remain valid (1-168 hours)</small>
    </div>
    </div><!-- /tab-signup -->

    <div class="settings-section" id="tab-oauth2">
    <div class="section-title"><i class="fab fa-openid"></i> <span data-i18n="settings_page.section_oauth2">OAuth2 Authentication</span></div>

    <div class="section-title" style="font-size:.95em; margin-top:0;"><i class="fab fa-google"></i> <span data-i18n="settings_page.section_google_oauth2">Google OAuth2</span></div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="oauth2_google_enabled" {% if config.oauth2 and config.oauth2.google and config.oauth2.google.enabled %}checked{% endif %}>
            Enable Google OAuth2 Authentication
        </label>
    </div>
    
    <div class="form-group">
        <label for="oauth2_google_client_id" data-i18n="settings_page.lbl_google_client_id">Google Client ID</label>
        <input type="text" id="oauth2_google_client_id" name="oauth2_google_client_id" value="{{ config.oauth2.google.client_id if config.oauth2 and config.oauth2.google else '' }}" placeholder="Client ID from Google Cloud Console">
    </div>
    
    <div class="form-group">
        <label for="oauth2_google_client_secret" data-i18n="settings_page.lbl_google_client_secret">Google Client Secret</label>
        <input type="password" id="oauth2_google_client_secret" name="oauth2_google_client_secret" value="{{ config.oauth2.google.client_secret if config.oauth2 and config.oauth2.google else '' }}" placeholder="Client Secret from Google Cloud Console">
    </div>

    <h4 style="margin: 25px 0 15px; color:#a0a0a0;">GitHub OAuth2</h4>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="oauth2_github_enabled" {% if config.oauth2 and config.oauth2.github and config.oauth2.github.enabled %}checked{% endif %}>
            Enable GitHub OAuth2 Authentication
        </label>
    </div>
    
    <div class="form-group">
        <label for="oauth2_github_client_id" data-i18n="settings_page.lbl_github_client_id">GitHub Client ID</label>
        <input type="text" id="oauth2_github_client_id" name="oauth2_github_client_id" value="{{ config.oauth2.github.client_id if config.oauth2 and config.oauth2.github else '' }}" placeholder="Client ID from GitHub Developer Settings">
    </div>
    
    <div class="form-group">
        <label for="oauth2_github_client_secret" data-i18n="settings_page.lbl_github_client_secret">GitHub Client Secret</label>
        <input type="password" id="oauth2_github_client_secret" name="oauth2_github_client_secret" value="{{ config.oauth2.github.client_secret if config.oauth2 and config.oauth2.github else '' }}" placeholder="Client Secret from GitHub Developer Settings">
    </div>
    </div><!-- /tab-oauth2 -->

    <div class="settings-section" id="tab-smtp">
    <div class="section-title"><i class="fas fa-envelope"></i> SMTP Email Configuration</div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="smtp_enabled" {% if config.smtp and config.smtp.enabled %}checked{% endif %}>
            Enable SMTP Email
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Enable email sending functionality for password resets, account verification, and notifications</small>
    </div>

    <div class="form-group">
        <label for="smtp_host" data-i18n="settings_page.lbl_smtp_host">SMTP Host</label>
        <input type="text" id="smtp_host" name="smtp_host"
               value="{{ config.smtp.host if config.smtp else 'localhost' }}" required>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">SMTP server hostname (e.g., smtp.gmail.com)</small>
    </div>
    
    <div class="form-group">
        <label for="smtp_port" data-i18n="settings_page.lbl_smtp_port">SMTP Port</label>
        <input type="number" id="smtp_port" name="smtp_port"
               value="{{ config.smtp.port if config.smtp else 587 }}" required>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">SMTP server port (587 for TLS, 465 for SSL, 25 for no encryption)</small>
    </div>
    
    <div class="form-group">
        <label for="smtp_username" data-i18n="settings_page.lbl_smtp_username">SMTP Username</label>
        <input type="text" id="smtp_username" name="smtp_username"
               value="{{ config.smtp.username if config.smtp else '' }}">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">SMTP authentication username (leave blank if not required)</small>
    </div>
    
    <div class="form-group">
        <label for="smtp_password" data-i18n="settings_page.lbl_smtp_password">SMTP Password</label>
        <input type="password" id="smtp_password" name="smtp_password" placeholder="Leave blank to keep current">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">SMTP authentication password</small>
    </div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="smtp_use_tls" {% if not config.smtp or config.smtp.use_tls %}checked{% endif %}>
            Use TLS
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Use STARTTLS for secure connection (recommended for port 587)</small>
    </div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="smtp_use_ssl" {% if config.smtp and config.smtp.use_ssl %}checked{% endif %}>
            Use SSL
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Use SSL/TLS from the start (for port 465)</small>
    </div>
    
    <div class="form-group">
        <label for="smtp_from_email" data-i18n="settings_page.lbl_smtp_from_email">From Email Address</label>
        <input type="email" id="smtp_from_email" name="smtp_from_email"
               value="{{ config.smtp.from_email if config.smtp else 'noreply@example.com' }}" required>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Email address to send from</small>
    </div>
    
    <div class="form-group">
        <label for="smtp_from_name" data-i18n="settings_page.lbl_smtp_from_name">From Name</label>
        <input type="text" id="smtp_from_name" name="smtp_from_name"
               value="{{ config.smtp.from_name if config.smtp else 'AISBF' }}" required>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Display name for sent emails</small>
    </div>
    
    <div style="display: flex; gap: 10px; margin-top: 20px;">
        <input type="email" id="smtp_test_email" name="smtp_test_email" placeholder="Email address to send test to" style="flex: 1;">
        <button type="button" onclick="testSMTP()" class="btn btn-secondary">Send Test Email</button>
    </div>
    </div><!-- /tab-smtp -->

    <div class="settings-section" id="tab-batching">
    <div class="section-title"><i class="fas fa-layer-group"></i> <span data-i18n="settings_page.section_batching">Request Batching</span></div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="batching_enabled" {% if config.batching and config.batching.enabled %}checked{% endif %}>
            Enable Request Batching
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Batch multiple requests together for improved efficiency</small>
    </div>
    
    <div class="form-group">
        <label for="batching_window_ms" data-i18n="settings_page.lbl_batching_window">Batching Window (milliseconds)</label>
        <input type="number" id="batching_window_ms" name="batching_window_ms" value="{{ config.batching.window_ms if config.batching else 100 }}" min="1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Time window to collect requests for batching (default: 100ms)</small>
    </div>
    
    <div class="form-group">
        <label for="batching_max_batch_size" data-i18n="settings_page.lbl_max_batch_size">Max Batch Size</label>
        <input type="number" id="batching_max_batch_size" name="batching_max_batch_size" value="{{ config.batching.max_batch_size if config.batching else 8 }}" min="1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Maximum number of requests per batch (default: 8)</small>
    </div>
    
    <h4 style="margin: 20px 0 15px;">Provider-Specific Batching Settings</h4>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="batching_openai_enabled" {% if config.batching and config.batching.provider_settings and config.batching.provider_settings.openai and config.batching.provider_settings.openai.enabled %}checked{% endif %}>
            Enable OpenAI Batching
        </label>
    </div>
    
    <div class="form-group">
        <label for="batching_openai_max_batch_size" data-i18n="settings_page.lbl_openai_batch_size">OpenAI Max Batch Size</label>
        <input type="number" id="batching_openai_max_batch_size" name="batching_openai_max_batch_size" value="{{ config.batching.provider_settings.openai.max_batch_size if config.batching and config.batching.provider_settings and config.batching.provider_settings.openai else 10 }}" min="1">
    </div>
    
    <div class="form-group">
        <label>
            <input type="checkbox" name="batching_anthropic_enabled" {% if config.batching and config.batching.provider_settings and config.batching.provider_settings.anthropic and config.batching.provider_settings.anthropic.enabled %}checked{% endif %}>
            Enable Anthropic Batching
        </label>
    </div>
    
    <div class="form-group">
        <label for="batching_anthropic_max_batch_size" data-i18n="settings_page.lbl_anthropic_batch_size">Anthropic Max Batch Size</label>
        <input type="number" id="batching_anthropic_max_batch_size" name="batching_anthropic_max_batch_size" value="{{ config.batching.provider_settings.anthropic.max_batch_size if config.batching and config.batching.provider_settings and config.batching.provider_settings.anthropic else 5 }}" min="1">
    </div>
    </div><!-- /tab-batching -->

    <div class="settings-section" id="tab-ratelimit">

    <div class="section-title"><i class="fas fa-shield-alt"></i> Client Rate Limiting</div>
    <p style="color:var(--color-muted);margin-bottom:16px;font-size:.9em;">Protect the server against request flooding. Limits are applied per authenticated token (API/MCP) or per IP address (all other routes). Set a value to 0 to disable that specific threshold.</p>

    <div class="form-group">
        <label>
            <input type="checkbox" name="client_rl_enabled" {% if config.client_rate_limiting and config.client_rate_limiting.enabled %}checked{% endif %}>
            Enable Client Rate Limiting
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Rate-limit inbound clients before processing auth or routing</small>
    </div>

    <div style="display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-bottom:8px;">
        <div>
            <div style="font-weight:600;margin-bottom:12px;color:var(--color-primary);"><i class="fas fa-plug"></i> API &amp; MCP Calls</div>
            <div class="form-group">
                <label for="client_rl_api_rpm">Requests per Minute</label>
                <input type="number" id="client_rl_api_rpm" name="client_rl_api_rpm" min="0"
                    value="{{ config.client_rate_limiting.api.requests_per_minute if config.client_rate_limiting and config.client_rate_limiting.api else 60 }}">
                <small style="color:var(--color-subtle);display:block;margin-top:4px;">0 = unlimited</small>
            </div>
            <div class="form-group">
                <label for="client_rl_api_rph">Requests per Hour</label>
                <input type="number" id="client_rl_api_rph" name="client_rl_api_rph" min="0"
                    value="{{ config.client_rate_limiting.api.requests_per_hour if config.client_rate_limiting and config.client_rate_limiting.api else 1000 }}">
                <small style="color:var(--color-subtle);display:block;margin-top:4px;">0 = unlimited</small>
            </div>
        </div>
        <div>
            <div style="font-weight:600;margin-bottom:12px;color:var(--color-primary);"><i class="fas fa-globe"></i> General (Dashboard &amp; Other)</div>
            <div class="form-group">
                <label for="client_rl_general_rpm">Requests per Minute</label>
                <input type="number" id="client_rl_general_rpm" name="client_rl_general_rpm" min="0"
                    value="{{ config.client_rate_limiting.general.requests_per_minute if config.client_rate_limiting and config.client_rate_limiting.general else 120 }}">
                <small style="color:var(--color-subtle);display:block;margin-top:4px;">0 = unlimited</small>
            </div>
            <div class="form-group">
                <label for="client_rl_general_rph">Requests per Hour</label>
                <input type="number" id="client_rl_general_rph" name="client_rl_general_rph" min="0"
                    value="{{ config.client_rate_limiting.general.requests_per_hour if config.client_rate_limiting and config.client_rate_limiting.general else 3000 }}">
                <small style="color:var(--color-subtle);display:block;margin-top:4px;">0 = unlimited</small>
            </div>
        </div>
    </div>

    <hr style="border-color:var(--color-border);margin:24px 0;">
    <div class="section-title" style="margin-top:0;"><i class="fas fa-tachometer-alt"></i> Adaptive Rate Limiting</div>
    <p style="color:var(--color-muted);margin-bottom:16px;font-size:.9em;">Outbound adaptive rate limiting — automatically adjusts how fast requests are forwarded to upstream providers based on their responses.</p>

    <div class="form-group">
        <label>
            <input type="checkbox" name="adaptive_rate_limiting_enabled" {% if config.adaptive_rate_limiting and config.adaptive_rate_limiting.enabled %}checked{% endif %}>
            Enable Adaptive Rate Limiting
        </label>
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Automatically adjust rate limits based on provider responses</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_initial_rate_limit" data-i18n="settings_page.lbl_initial_rate_limit">Initial Rate Limit (requests/second)</label>
        <input type="number" id="adaptive_initial_rate_limit" name="adaptive_initial_rate_limit" value="{{ config.adaptive_rate_limiting.initial_rate_limit if config.adaptive_rate_limiting else 0 }}" min="0" step="0.1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Starting rate limit (0 = unlimited)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_learning_rate" data-i18n="settings_page.lbl_learning_rate">Learning Rate</label>
        <input type="number" id="adaptive_learning_rate" name="adaptive_learning_rate" value="{{ config.adaptive_rate_limiting.learning_rate if config.adaptive_rate_limiting else 0.1 }}" min="0" max="1" step="0.01">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">How quickly to adapt to rate limit changes (0-1, default: 0.1)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_headroom_percent" data-i18n="settings_page.lbl_headroom_percent">Headroom Percent</label>
        <input type="number" id="adaptive_headroom_percent" name="adaptive_headroom_percent" value="{{ config.adaptive_rate_limiting.headroom_percent if config.adaptive_rate_limiting else 10 }}" min="0" max="100">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Safety margin below detected limit (default: 10%)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_recovery_rate" data-i18n="settings_page.lbl_recovery_rate">Recovery Rate</label>
        <input type="number" id="adaptive_recovery_rate" name="adaptive_recovery_rate" value="{{ config.adaptive_rate_limiting.recovery_rate if config.adaptive_rate_limiting else 0.05 }}" min="0" max="1" step="0.01">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Rate at which limits recover after errors (default: 0.05)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_max_rate_limit" data-i18n="settings_page.lbl_max_rate_limit">Max Rate Limit (requests/second)</label>
        <input type="number" id="adaptive_max_rate_limit" name="adaptive_max_rate_limit" value="{{ config.adaptive_rate_limiting.max_rate_limit if config.adaptive_rate_limiting else 60 }}" min="0" step="0.1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Maximum allowed rate limit (default: 60)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_min_rate_limit" data-i18n="settings_page.lbl_min_rate_limit">Min Rate Limit (requests/second)</label>
        <input type="number" id="adaptive_min_rate_limit" name="adaptive_min_rate_limit" value="{{ config.adaptive_rate_limiting.min_rate_limit if config.adaptive_rate_limiting else 0.1 }}" min="0" step="0.1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Minimum allowed rate limit (default: 0.1)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_backoff_base" data-i18n="settings_page.lbl_backoff_base">Backoff Base</label>
        <input type="number" id="adaptive_backoff_base" name="adaptive_backoff_base" value="{{ config.adaptive_rate_limiting.backoff_base if config.adaptive_rate_limiting else 2 }}" min="1" step="0.1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Exponential backoff multiplier (default: 2)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_jitter_factor" data-i18n="settings_page.lbl_jitter_factor">Jitter Factor</label>
        <input type="number" id="adaptive_jitter_factor" name="adaptive_jitter_factor" value="{{ config.adaptive_rate_limiting.jitter_factor if config.adaptive_rate_limiting else 0.25 }}" min="0" max="1" step="0.01">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Random jitter to prevent thundering herd (0-1, default: 0.25)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_history_window" data-i18n="settings_page.lbl_history_window">History Window (seconds)</label>
        <input type="number" id="adaptive_history_window" name="adaptive_history_window" value="{{ config.adaptive_rate_limiting.history_window if config.adaptive_rate_limiting else 3600 }}" min="1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Time window for tracking rate limit history (default: 3600)</small>
    </div>
    
    <div class="form-group">
        <label for="adaptive_consecutive_successes" data-i18n="settings_page.lbl_consecutive_successes">Consecutive Successes for Recovery</label>
        <input type="number" id="adaptive_consecutive_successes" name="adaptive_consecutive_successes" value="{{ config.adaptive_rate_limiting.consecutive_successes_for_recovery if config.adaptive_rate_limiting else 10 }}" min="1">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Number of successful requests before increasing rate limit (default: 10)</small>
    </div>
    </div><!-- /tab-ratelimit -->

    <div class="settings-section" id="tab-admin">
    <div class="section-title"><i class="fas fa-shield-alt"></i> Admin Account &amp; Notifications</div>

    <div class="form-group">
        <label for="dashboard_username" data-i18n="settings_page.lbl_admin_username">Admin Username</label>
        <input type="text" id="dashboard_username" name="dashboard_username" value="{{ config.dashboard.username }}" required>
    </div>

    <div class="form-group">
        <label for="new_admin_password" data-i18n="settings_page.lbl_new_password">New Password</label>
        <input type="password" id="new_admin_password" name="new_admin_password" placeholder="Leave blank to keep current password">
    </div>

    <div class="form-group">
        <label for="confirm_admin_password" data-i18n="settings_page.lbl_confirm_password">Confirm New Password</label>
        <input type="password" id="confirm_admin_password" name="confirm_admin_password" placeholder="Confirm new password">
    </div>

    <div class="form-group">
        <label for="dashboard_email" data-i18n="settings_page.lbl_admin_email">Admin Email Address</label>
        <input type="email" id="dashboard_email" name="dashboard_email"
               value="{{ config.dashboard.email if config.dashboard and config.dashboard.email else '' }}"
               placeholder="admin@example.com">
        <small style="color: var(--color-subtle); display: block; margin-top: 5px;">Email address to receive admin notifications. Requires SMTP to be configured and enabled.</small>
    </div>

    <div class="section-title" style="margin-top: 24px;"><i class="fas fa-bell"></i> Admin Email Notifications</div>
    <small style="color: var(--color-subtle); display: block; margin-bottom: 16px;">Select which events trigger an email to the admin. SMTP must be enabled and an admin email must be set above.</small>

    {% set notif = config.dashboard.notifications if config.dashboard and config.dashboard.notifications else {} %}

    <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px;">
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_new_user_signup"
                   {% if notif.new_user_signup %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-user-plus" style="color:#4ade80;"></i> New user self-registered</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_payment_received"
                   {% if notif.payment_received %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-credit-card" style="color:#60a5fa;"></i> Payment received</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_tier_upgrade"
                   {% if notif.tier_upgrade %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-arrow-up" style="color:#f59e0b;"></i> Subscription upgrade</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_tier_downgrade"
                   {% if notif.tier_downgrade %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-arrow-down" style="color:#f87171;"></i> Subscription downgrade</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_subscription_expired"
                   {% if notif.subscription_expired %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-calendar-times" style="color:#f87171;"></i> Subscription expired / cancelled</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_subscription_renewed"
                   {% if notif.subscription_renewed %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-sync" style="color:#4ade80;"></i> Subscription renewed</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_wallet_topup"
                   {% if notif.wallet_topup %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-wallet" style="color:#a78bfa;"></i> Wallet top-up</span>
        </label>
        <label style="display:flex; align-items:center; gap:10px; cursor:pointer; background:#0f3460; padding:12px; border-radius:6px;">
            <input type="checkbox" name="admin_notify_user_deleted_account"
                   {% if notif.user_deleted_account %}checked{% endif %} style="width:auto;">
            <span><i class="fas fa-user-slash" style="color:#f87171;"></i> User deleted their account</span>
        </label>
    </div>
    </div><!-- /tab-admin -->

    <div style="display: flex; gap: 10px; margin-top: 30px; padding-top: 20px; border-top: 1px solid #0f3460;">
        <button type="submit" class="btn" data-i18n="settings_page.save_btn">Save Settings</button>
        <a href="{{ url_for(request, '/dashboard') }}" class="btn btn-secondary">Cancel</a>
        <button type="button" onclick="testSMTP()" class="btn btn-secondary" style="margin-left: auto;">Test SMTP</button>
    </div>
</form>

<script>
function switchTab(name) {
    document.querySelectorAll('.settings-tab').forEach(t => t.classList.remove('active'));
    document.querySelectorAll('.settings-section').forEach(s => s.classList.remove('active'));
    document.querySelector(`[onclick="switchTab('${name}')"]`).classList.add('active');
    document.getElementById('tab-' + name).classList.add('active');
    document.getElementById('active_tab_input').value = name;
}

// Validate admin password match before form submit
document.querySelector('form').addEventListener('submit', function(e) {
    const np = document.getElementById('new_admin_password').value;
    const cp = document.getElementById('confirm_admin_password').value;
    if (np && np !== cp) {
        e.preventDefault();
        switchTab('admin');
        showAlert('Admin passwords do not match. Please re-enter.', 'Password Mismatch', '⚠️', 'warn');
    }
});

async function testSMTP() {
    const host = document.getElementById('smtp_host').value;
    const port = document.getElementById('smtp_port').value;
    const username = document.getElementById('smtp_username').value;
    const fromEmail = document.getElementById('smtp_from_email').value;
    const testEmail = document.getElementById('smtp_test_email').value;
    
    if (!host || !port || !fromEmail) {
        showAlert('Please fill in SMTP host, port, and from email before testing', 'Missing Fields', '⚠️', 'warn');
        return;
    }
    
    if (!testEmail) {
        showAlert('Please enter a test recipient email address', 'Missing Fields', '⚠️', 'warn');
        return;
    }
    
    const ok = await showConfirm(`This will send a test email to ${testEmail}. Continue?`, 'Send Test Email');
    if (!ok) return;
    
    try {
        const response = await fetch('{{ url_for(request, "/dashboard/test-smtp") }}', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({
                host: host,
                port: parseInt(port),
                username: username,
                password: document.getElementById('smtp_password').value,
                use_tls: document.querySelector('input[name="smtp_use_tls"]').checked,
                use_ssl: document.querySelector('input[name="smtp_use_ssl"]').checked,
                from_email: fromEmail,
                from_name: document.getElementById('smtp_from_name').value,
                test_recipient: testEmail
            })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showAlert('Test email sent successfully! Check your inbox.', 'Success', '✅', 'info');
        } else {
            showAlert('Failed to send test email: ' + (data.error || 'Unknown error'), 'Error', '❌', 'danger');
        }
    } catch (error) {
        showAlert('Error testing SMTP: ' + error.message, 'Error', '❌', 'danger');
    }
}
</script>

<script>
function toggleSSLFields() {
    const protocol = document.getElementById('protocol').value;
    const sslFields = document.getElementById('ssl-fields');
    
    if (protocol === 'https') {
        sslFields.style.display = 'block';
    } else {
        sslFields.style.display = 'none';
    }
}

function toggleTorFields() {
    const torEnabled = document.getElementById('tor_enabled').checked;
    const torFields = document.getElementById('tor-fields');

    if (torEnabled) {
        torFields.style.display = 'block';
    } else {
        torFields.style.display = 'none';
    }
}

function toggleDatabaseFields() {
    const dbType = document.getElementById('database_type').value;
    const sqliteFields = document.getElementById('sqlite-fields');
    const mysqlFields = document.getElementById('mysql-fields');

    if (dbType === 'sqlite') {
        sqliteFields.style.display = 'block';
        mysqlFields.style.display = 'none';
    } else if (dbType === 'mysql') {
        sqliteFields.style.display = 'none';
        mysqlFields.style.display = 'block';
    }
}

function toggleCacheFields() {
    const cacheType = document.getElementById('cache_type').value;
    const redisFields = document.getElementById('redis-cache-fields');
    const sqliteFields = document.getElementById('sqlite-cache-fields');
    const mysqlCacheFields = document.getElementById('mysql-cache-fields');

    // Hide all cache-specific fields first
    redisFields.style.display = 'none';
    sqliteFields.style.display = 'none';
    mysqlCacheFields.style.display = 'none';

    // Show only the relevant fields
    if (cacheType === 'redis') {
        redisFields.style.display = 'block';
    } else if (cacheType === 'sqlite') {
        sqliteFields.style.display = 'block';
    } else if (cacheType === 'mysql') {
        mysqlCacheFields.style.display = 'block';
    }
}

function toggleResponseCacheFields() {
    const backend = document.getElementById('response_cache_backend').value;
    const redisFields = document.getElementById('response-cache-redis-fields');
    const sqliteFields = document.getElementById('response-cache-sqlite-fields');
    const mysqlFields = document.getElementById('response-cache-mysql-fields');
    
    // Hide all fields first
    redisFields.style.display = 'none';
    sqliteFields.style.display = 'none';
    mysqlFields.style.display = 'none';
    
    // Show only the relevant fields
    if (backend === 'redis') {
        redisFields.style.display = 'block';
    } else if (backend === 'sqlite') {
        sqliteFields.style.display = 'block';
    } else if (backend === 'mysql') {
        mysqlFields.style.display = 'block';
    }
}

function createPersistentService() {
    const dirInput = document.getElementById('tor_hidden_service_dir');
    const defaultDir = '/home/{{ os.environ.get("USER", "yourusername") }}/.aisbf/tor_hidden_service';
    
    if (dirInput.value && dirInput.value.trim() !== '') {
        showConfirm('This will replace the current directory path. Continue?', 'Replace Path').then(ok => {
            if (!ok) return;
            dirInput.value = defaultDir;
            dirInput.focus();
            updateTorrcExample();
            dirInput.style.backgroundColor = '#1a4d2e';
            setTimeout(() => { dirInput.style.backgroundColor = ''; }, 500);
        });
        return;
    }
    
    dirInput.value = defaultDir;
    dirInput.focus();
    updateTorrcExample();
    dirInput.style.backgroundColor = '#1a4d2e';
    setTimeout(() => { dirInput.style.backgroundColor = ''; }, 500);
}

function toggleTorrcExample(type) {
    const ephemeralDiv = document.getElementById('torrc-ephemeral');
    const persistentDiv = document.getElementById('torrc-persistent');
    
    if (type === 'ephemeral') {
        ephemeralDiv.style.display = 'block';
        persistentDiv.style.display = 'none';
    } else {
        ephemeralDiv.style.display = 'none';
        persistentDiv.style.display = 'block';
        updateTorrcExample();
    }
}

function updateTorrcExample() {
    const hsDir = document.getElementById('tor_hidden_service_dir').value || '/home/yourusername/.aisbf/tor_hidden_service';
    const hsPort = document.getElementById('tor_hidden_service_port').value || '80';
    const localPort = document.getElementById('port').value || '{{ config.server.port if config.server else 17765 }}';
    
    // Expand ~ to actual home directory path for torrc display
    let expandedHsDir = hsDir;
    if (hsDir.startsWith('~')) {
        // Get home directory from server (we'll add an endpoint for this)
        // For now, show a placeholder that makes it clear it needs expansion
        expandedHsDir = hsDir.replace('~', '/home/yourusername');
    }
    
    const hsDirSpan = document.getElementById('torrc-hs-dir');
    const hsPortSpan = document.getElementById('torrc-hs-port');
    const localPortSpan = document.getElementById('torrc-local-port');
    
    if (hsDirSpan) hsDirSpan.textContent = expandedHsDir;
    if (hsPortSpan) hsPortSpan.textContent = hsPort;
    if (localPortSpan) localPortSpan.textContent = localPort;
}

async function checkTorStatus() {
    try {
        const response = await fetch('{{ url_for(request, "/dashboard/tor/status") }}');
        const status = await response.json();
        
        const statusText = document.getElementById('tor-status-text');
        const onionAddressDiv = document.getElementById('tor-onion-address');
        const onionValue = document.getElementById('tor-onion-value');
        
        if (status.enabled && status.connected && status.onion_address) {
            statusText.textContent = 'Active';
            statusText.style.color = '#4caf50';
            onionAddressDiv.style.display = 'block';
            onionValue.textContent = status.onion_address;
        } else if (status.enabled && !status.connected) {
            statusText.textContent = 'Enabled but not connected';
            statusText.style.color = '#ff9800';
            onionAddressDiv.style.display = 'none';
        } else {
            statusText.textContent = 'Disabled';
            statusText.style.color = '#666';
            onionAddressDiv.style.display = 'none';
        }
    } catch (error) {
        console.error('Error checking TOR status:', error);
        document.getElementById('tor-status-text').textContent = 'Error checking status';
        document.getElementById('tor-status-text').style.color = '#f44336';
    }
}

// Check TOR status on page load
document.addEventListener('DOMContentLoaded', function() {
    checkTorStatus();
    setInterval(checkTorStatus, 30000);
    refreshCacheStats();
    setInterval(refreshCacheStats, 10000);
    {% if warning == 'default_password' %}
    switchTab('admin');
    {% else %}
    const savedTab = document.getElementById('active_tab_input').value;
    if (savedTab && savedTab !== 'server') switchTab(savedTab);
    {% endif %}
});

async function refreshCacheStats() {
    try {
        const response = await fetch('{{ url_for(request, "/dashboard/response-cache/stats") }}');
        const data = await response.json();
        
        const statsText = document.getElementById('cache-stats-text');
        const statsDetails = document.getElementById('cache-stats-details');
        
        if (data.enabled) {
            statsText.textContent = 'Enabled';
            statsText.style.color = '#4caf50';
            statsDetails.style.display = 'block';
            
            document.getElementById('cache-hits').textContent = data.hits || 0;
            document.getElementById('cache-misses').textContent = data.misses || 0;
            document.getElementById('cache-hit-rate').textContent = (data.hit_rate || 0).toFixed(1) + '%';
            document.getElementById('cache-size').textContent = data.size || 0;
            document.getElementById('cache-evictions').textContent = data.evictions || 0;
            document.getElementById('cache-backend').textContent = data.backend || '-';
        } else {
            statsText.textContent = 'Disabled';
            statsText.style.color = '#666';
            statsDetails.style.display = 'none';
        }
    } catch (error) {
        console.error('Error fetching cache stats:', error);
        document.getElementById('cache-stats-text').textContent = 'Error loading stats';
        document.getElementById('cache-stats-text').style.color = '#f44336';
    }
}

async function clearModelCache(modelId, modelType, btn) {
    if (!modelId) {
        showAlert('Model ID is empty.', 'Error', '⚠️', 'warn');
        return;
    }
    const ok = await showDangerConfirm(
        `Delete local cache for <strong>${modelId}</strong>?<br><br>The model will be re-downloaded from HuggingFace on next use.`,
        'Clear Model Cache'
    );
    if (!ok) return;

    const orig = btn.innerHTML;
    btn.disabled = true;
    btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Clearing…';

    try {
        const response = await fetch('{{ url_for(request, "/dashboard/local-models/clear-cache") }}', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({model_id: modelId, model_type: modelType})
        });
        const data = await response.json();
        if (data.success) {
            showAlert(`Cache cleared for <strong>${modelId}</strong>. It will be re-downloaded on next use.`, 'Done', '✅', 'info');
        } else {
            const errs = (data.errors || []).join('<br>');
            showAlert('Cache clear finished with errors:<br>' + errs, 'Warning', '⚠️', 'warn');
        }
    } catch (err) {
        showAlert('Error: ' + err.message, 'Error', '❌', 'danger');
    } finally {
        btn.disabled = false;
        btn.innerHTML = orig;
    }
}

async function clearAllModelCaches(btn) {
    const ok = await showDangerConfirm(
        'Delete the local cache for <strong>all</strong> configured models?<br><br>All models will be re-downloaded from HuggingFace on next use.',
        'Clear All Model Caches'
    );
    if (!ok) return;

    const orig = btn.innerHTML;
    btn.disabled = true;
    btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Clearing…';

    try {
        const response = await fetch('{{ url_for(request, "/dashboard/local-models/clear-cache") }}', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({})
        });
        const data = await response.json();
        if (data.success) {
            const count = (data.cleared || []).length;
            showAlert(`Cleared ${count} model cache(s). They will be re-downloaded on next use.`, 'Done', '✅', 'info');
        } else {
            const errs = (data.errors || []).join('<br>');
            showAlert('Cache clear finished with errors:<br>' + errs, 'Warning', '⚠️', 'warn');
        }
    } catch (err) {
        showAlert('Error: ' + err.message, 'Error', '❌', 'danger');
    } finally {
        btn.disabled = false;
        btn.innerHTML = orig;
    }
}

async function clearResponseCache() {
    const ok = await showDangerConfirm('Are you sure you want to clear the response cache? This will remove all cached responses.', 'Clear Cache');
    if (!ok) return;
    
    try {
        const response = await fetch('{{ url_for(request, "/dashboard/response-cache/clear") }}', {
            method: 'POST'
        });
        const data = await response.json();
        
        if (data.success) {
            showAlert('Response cache cleared successfully', 'Done', '✅', 'info');
            refreshCacheStats();
        } else {
            showAlert('Failed to clear cache: ' + (data.error || 'Unknown error'), 'Error', '❌', 'danger');
        }
    } catch (error) {
        showAlert('Error clearing cache: ' + error.message, 'Error', '❌', 'danger');
    }
}
</script>
{% endblock %}
