{% extends "base.html" %} {% block title %}配置编辑器 - Gemini Balance{%
endblock %} {% block head_extra_styles %}
<style>
  /* config_editor.html specific styles */
  /* Animations (already in base.html, but keep fade-in class usage) */
  .fade-in {
    animation: fadeIn 0.3s ease forwards;
  }
  /* Modal specific styles (already in base.html) */
  .array-container {
    max-height: 300px;
    overflow-y: auto;
    padding: 1rem; /* p-4 consistency */
    margin-bottom: 0.5rem; /* mb-2 consistency */
    background-color: rgba(255, 255, 255, 0.05); /* theming */
    border: 1px solid rgba(120, 100, 200, 0.3); /* theming */
    color: #e2e8f0; /* theming */
    border-radius: 0.5rem; /* rounded-lg consistency */
  }
  #API_KEYS_container {
    /* Keep specific ID styling if needed */
    max-height: 300px;
    overflow-y: auto;
  }
  .config-section {
    display: none;
    /* theming: new background and border for sections */
    background-color: rgba(70, 50, 150, 0.5);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    border: 1px solid rgba(120, 100, 200, 0.2);
    border-radius: 0.75rem; /* rounded-xl */
    padding: 1.5rem; /* p-6 */
    margin-bottom: 1.5rem; /* mb-6 */
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
      0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-lg */
  }
  .config-section.active {
    display: block;
    animation: fadeIn 0.3s ease forwards; /* Use base animation */
  }
  .provider-config {
    display: none;
  }
  .provider-config.active {
    display: block;
  }
  /* Tailwind Toggle Switch Helper CSS */
  .toggle-checkbox:checked {
    @apply: right-0 border-violet-600; /* theming: changed from primary-600 */
    right: 0;
    border-color: #7c3aed; /* theming: violet-600 */
  }
  .toggle-checkbox:checked + .toggle-label {
    @apply: bg-violet-600; /* theming: changed from primary-600 */
    background-color: #7c3aed; /* theming: violet-600 */
  }
  .toggle-label {
    /* theming: style for unchecked state */
    background-color: rgba(120, 100, 200, 0.3);
  }
  /* 统一通知样式为黑色半透明，确保与 keys_status 一致 */
  .notification {
    background: rgba(0, 0, 0, 0.8) !important;
    color: #fff !important;
  }

  /* Theming for input fields */
  .form-input-themed {
    background-color: rgba(0, 0, 0, 0.3) !important;
    border: 1px solid rgba(120, 100, 200, 0.5) !important;
    color: #e2e8f0 !important;
  }
  .form-input-themed::placeholder {
    color: #a0aec0 !important; /* gray-400 */
  }
  .form-input-themed:focus {
    border-color: #a78bfa !important; /* violet-400 */
    box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.4) !important; /* ring-violet-400 */
  }

  /* Theming for select fields - 改进下拉框样式 */
  .form-select-themed {
    background-color: rgba(
      60,
      40,
      130,
      0.6
    ) !important; /* 更深的紫色背景，增加透明度 */
    border: 1px solid rgba(167, 139, 250, 0.7) !important; /* 更亮的紫色边框 */
    color: #ffffff !important; /* 更亮的文字颜色 */
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%23d8b4fe' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 8l4 4 4-4'/%3e%3c/svg%3e") !important; /* 更亮的紫色箭头 */
    appearance: none !important;
    padding: 0.6rem 2.5rem 0.6rem 0.8rem !important; /* 调整内边距 */
    background-repeat: no-repeat !important;
    background-position: right 0.6rem center !important;
    background-size: 1.5em 1.5em !important;
    border-radius: 0.5rem !important; /* 圆角 */
    font-weight: 500 !important; /* 半粗体 */
    height: auto !important; /* 自动高度 */
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) !important; /* 微小阴影 */
    cursor: pointer !important;
  }

  .form-select-themed:focus {
    border-color: #d8b4fe !important; /* violet-300 */
    box-shadow: 0 0 0 3px rgba(216, 180, 254, 0.4) !important; /* ring-violet-300 */
    outline: none !important;
  }

  .form-select-themed option {
    background-color: rgba(76, 29, 149, 0.95) !important; /* 暗紫色背景 */
    color: #ffffff !important;
    padding: 8px !important;
  }

  /* 不同级别的日志样式 */
  #LOG_LEVEL {
    font-weight: 600 !important;
  }

  #LOG_LEVEL option[value="DEBUG"] {
    background-color: rgba(79, 70, 229, 0.8) !important; /* indigo */
    color: white !important;
  }

  #LOG_LEVEL option[value="INFO"] {
    background-color: rgba(59, 130, 246, 0.8) !important; /* blue */
    color: white !important;
  }

  #LOG_LEVEL option[value="WARNING"] {
    background-color: rgba(245, 158, 11, 0.8) !important; /* amber */
    color: white !important;
  }

  #LOG_LEVEL option[value="ERROR"] {
    background-color: rgba(239, 68, 68, 0.8) !important; /* red */
    color: white !important;
  }

  #LOG_LEVEL option[value="CRITICAL"] {
    background-color: rgba(185, 28, 28, 0.8) !important; /* red-700 */
    color: white !important;
  }

  /* 思考模型预算映射样式 */
  .map-item {
    background-color: rgba(60, 40, 130, 0.2) !important;
    border-radius: 0.5rem !important;
    padding: 0.5rem !important;
    border: 1px solid rgba(167, 139, 250, 0.3) !important;
    transition: all 0.2s ease-in-out !important;
  }

  .map-item:hover {
    background-color: rgba(60, 40, 130, 0.3) !important;
    border-color: rgba(167, 139, 250, 0.5) !important;
  }

  .map-key-input {
    background-color: rgba(80, 60, 170, 0.4) !important;
    border: 1px solid rgba(167, 139, 250, 0.6) !important;
    color: #e2e8f0 !important;
    font-weight: 500 !important;
    border-radius: 0.375rem !important;
  }

  .map-value-input {
    background-color: rgba(60, 40, 130, 0.4) !important;
    border: 1px solid rgba(167, 139, 250, 0.6) !important;
    color: #ffffff !important;
    font-weight: 600 !important;
    border-radius: 0.375rem !important;
    box-shadow: none !important;
    transition: all 0.2s !important;
  }

  .map-value-input:focus {
    background-color: rgba(80, 60, 170, 0.6) !important;
    border-color: #d8b4fe !important; /* violet-300 */
    box-shadow: 0 0 0 3px rgba(216, 180, 254, 0.4) !important;
    outline: none !important;
  }

  /* 警告文字样式 */
  .warning-text {
    color: #f87171 !important; /* red-400 */
    font-weight: 600 !important;
    background-color: rgba(248, 113, 113, 0.15) !important;
    padding: 0.5rem 0.75rem !important;
    border-radius: 0.375rem !important;
    border-left: 3px solid #ef4444 !important; /* red-500 */
    display: flex !important;
    align-items: center !important;
    margin-top: 0.5rem !important;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) !important;
  }

  .warning-text i {
    margin-right: 0.5rem !important;
    color: #ef4444 !important; /* red-500 */
  }

  /* 令牌生成按钮样式 */
  .generate-btn {
    background-color: rgba(80, 60, 170, 0.3) !important;
    color: #d8b4fe !important; /* violet-300 */
    border: 1px solid rgba(167, 139, 250, 0.4) !important;
    border-left: none !important;
    transition: all 0.2s ease !important;
  }

  .generate-btn:hover {
    background-color: rgba(
      109,
      40,
      217,
      0.4
    ) !important; /* violet-700 半透明 */
    color: #ffffff !important;
    box-shadow: 0 0 8px rgba(167, 139, 250, 0.5) !important;
  }

  .generate-btn:focus {
    outline: none !important;
    box-shadow: 0 0 0 2px rgba(167, 139, 250, 0.5) !important;
  }

  /* 导航链接悬停样式 */
  .nav-link {
    transition: all 0.2s ease-in-out;
  }

  .nav-link:hover {
    background-color: rgba(120, 100, 200, 0.6) !important;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  }

  /* General label and small text theming */
  label {
    color: #e2e8f0 !important; /* Light gray/white for labels */
    font-weight: 500; /* semibold */
  }
  small {
    color: #cbd5e0 !important; /* Lighter gray for small text */
  }
</style>
{% endblock %} {% block content %}
<div class="container max-w-4xl mx-auto px-4">
  <div
    class="rounded-2xl shadow-xl p-6 md:p-8"
    style="
      background-color: rgba(80, 60, 160, 0.3);
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      border: 1px solid rgba(150, 130, 230, 0.3);
    "
  >
    <button
      class="absolute top-6 right-6 bg-white bg-opacity-20 hover:bg-opacity-30 rounded-full w-8 h-8 flex items-center justify-center text-violet-300 hover:text-violet-100 transition-all duration-300"
      onclick="refreshPage(this)"
    >
      <i class="fas fa-sync-alt"></i>
    </button>

    <h1
      class="text-3xl font-extrabold text-center text-transparent bg-clip-text bg-gradient-to-r from-violet-400 to-pink-400 mb-4"
    >
      <img
        src="/static/icons/logo.png"
        alt="Gemini Balance Logo"
        class="h-9 inline-block align-middle mr-2"
      />
      Gemini Balance - 配置编辑
    </h1>

    <!-- Navigation Tabs -->
    <div class="flex justify-center mb-8 overflow-x-auto pb-2 gap-2">
      <a
        href="/config"
        class="whitespace-nowrap flex items-center justify-center gap-2 px-6 py-3 font-medium rounded-lg bg-violet-600 text-white shadow-md"
      >
        <i class="fas fa-cog"></i> 配置编辑
      </a>
      <a
        href="/keys"
        class="nav-link whitespace-nowrap flex items-center justify-center gap-2 px-6 py-3 font-medium rounded-lg text-gray-200 hover:text-white transition-all duration-200"
        style="background-color: rgba(107, 70, 193, 0.4)"
      >
        <i class="fas fa-tachometer-alt"></i> 监控面板
      </a>
      <a
        href="/logs"
        class="nav-link whitespace-nowrap flex items-center justify-center gap-2 px-6 py-3 font-medium rounded-lg text-gray-200 hover:text-white transition-all duration-200"
        style="background-color: rgba(107, 70, 193, 0.4)"
      >
        <i class="fas fa-exclamation-triangle"></i> 错误日志
      </a>
    </div>

    <!-- Config Tabs -->
    <div class="flex justify-center mb-6 flex-wrap gap-2">
      <button
        class="tab-btn bg-violet-600 text-white px-5 py-2 rounded-full shadow-md font-medium text-sm"
        data-tab="api"
      >
        API配置
      </button>
      <button
        class="tab-btn bg-white bg-opacity-20 text-gray-200 px-5 py-2 rounded-full font-medium text-sm hover:bg-opacity-30 transition-all duration-200"
        data-tab="model"
      >
        模型配置
      </button>
      <button
        class="tab-btn bg-white bg-opacity-20 text-gray-200 px-5 py-2 rounded-full font-medium text-sm hover:bg-opacity-30 transition-all duration-200"
        data-tab="image"
      >
        图像生成
      </button>
      <button
        class="tab-btn bg-white bg-opacity-20 text-gray-200 px-5 py-2 rounded-full font-medium text-sm hover:bg-opacity-30 transition-all duration-200"
        data-tab="stream"
      >
        流式输出
      </button>
      <button
        class="tab-btn bg-white bg-opacity-20 text-gray-200 px-5 py-2 rounded-full font-medium text-sm hover:bg-opacity-30 transition-all duration-200"
        data-tab="scheduler"
      >
        定时任务
      </button>
      <button
        class="tab-btn bg-white bg-opacity-20 text-gray-200 px-5 py-2 rounded-full font-medium text-sm hover:bg-opacity-30 transition-all duration-200"
        data-tab="logging"
      >
        日志配置
      </button>
    </div>

    <!-- Save Status Banner (Removed - using notification component now) -->

    <!-- Configuration Form -->
    <form id="configForm" class="mt-6">
      <!-- API 相关配置 -->
      <div class="config-section active" id="api-section">
        <h2
          class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
        >
          <i class="fas fa-key text-violet-400"></i> API相关配置
        </h2>

        <!-- API密钥列表 -->
        <div class="mb-6">
          <label for="API_KEYS" class="block font-semibold mb-2 text-gray-700"
            >API密钥列表</label
          >
          <div class="mb-2">
            <input
              type="search"
              id="apiKeySearchInput"
              placeholder="搜索密钥..."
              class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
            />
          </div>
          <div class="array-container" id="API_KEYS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2">
            <button
              type="button"
              class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="bulkDeleteApiKeyBtn"
            >
              <i class="fas fa-trash-alt"></i> 删除密钥
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="addApiKeyBtn"
            >
              <i class="fas fa-plus"></i> 添加密钥
            </button>
          </div>
          <small class="text-gray-500 mt-1 block"
            >Gemini API密钥列表，每行一个</small
          >
        </div>

        <!-- 允许的令牌列表 -->
        <div class="mb-6">
          <label
            for="ALLOWED_TOKENS"
            class="block font-semibold mb-2 text-gray-700"
            >允许的令牌列表</label
          >
          <div class="array-container" id="ALLOWED_TOKENS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end">
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              onclick="addArrayItem('ALLOWED_TOKENS')"
            >
              <i class="fas fa-plus"></i> 添加令牌
            </button>
          </div>
          <small class="text-gray-500 mt-1 block">允许访问API的令牌列表</small>
        </div>

        <!-- 认证令牌 -->
        <div class="mb-6">
          <label for="AUTH_TOKEN" class="block font-semibold mb-2 text-gray-700"
            >认证令牌</label
          >
          <div class="flex items-center">
            <div
              class="flex items-center flex-grow border rounded-md focus-within:border-violet-400 focus-within:ring focus-within:ring-violet-400 focus-within:ring-opacity-50"
              style="border-color: rgba(120, 100, 200, 0.5)"
            >
              <input
                type="text"
                id="AUTH_TOKEN"
                name="AUTH_TOKEN"
                placeholder="默认使用ALLOWED_TOKENS中的第一个"
                class="array-input flex-grow px-3 py-2 border-none rounded-l-md focus:outline-none sensitive-input form-input-themed"
              />
              <button
                type="button"
                id="generateAuthTokenBtn"
                class="generate-btn px-2 py-2 text-gray-400 hover:text-violet-400 focus:outline-none rounded-r-md hover:bg-gray-600 transition-colors"
                title="生成随机令牌"
                style="background-color: rgba(120, 100, 200, 0.2)"
              >
                <i class="fas fa-dice"></i>
              </button>
            </div>
          </div>
          <small class="text-gray-500 mt-1 block">用于API认证的令牌</small>
        </div>

        <!-- API基础URL -->
        <div class="mb-6">
          <label for="BASE_URL" class="block font-semibold mb-2 text-gray-700"
            >API基础URL</label
          >
          <input
            type="text"
            id="BASE_URL"
            name="BASE_URL"
            placeholder="https://generativelanguage.googleapis.com/v1beta"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">Gemini API的基础URL</small>
        </div>
 
        <!-- Vertex API密钥列表 -->
        <div class="mb-6">
          <label for="VERTEX_API_KEYS" class="block font-semibold mb-2 text-gray-700"
            >Vertex API密钥列表</label
          >
          <div class="array-container" id="VERTEX_API_KEYS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2">
            <button
              type="button"
              class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="bulkDeleteVertexApiKeyBtn"
            >
              <i class="fas fa-trash-alt"></i> 删除Vertex密钥
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="addVertexApiKeyBtn"
            >
              <i class="fas fa-plus"></i> 添加Vertex密钥
            </button>
          </div>
          <small class="text-gray-500 mt-1 block"
            >Vertex AI Platform API密钥列表。点击按钮可批量添加或删除。</small
          >
        </div>
 
        <!-- Vertex Express API基础URL -->
        <div class="mb-6">
          <label for="VERTEX_EXPRESS_BASE_URL" class="block font-semibold mb-2 text-gray-700"
            >Vertex Express API基础URL</label
          >
          <input
            type="text"
            id="VERTEX_EXPRESS_BASE_URL"
            name="VERTEX_EXPRESS_BASE_URL"
            placeholder="https://aiplatform.googleapis.com/v1beta1/publishers/google/models"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">Vertex Express API的基础URL</small>
        </div>
 
        <!-- 最大失败次数 -->
        <div class="mb-6">
          <label
            for="MAX_FAILURES"
            class="block font-semibold mb-2 text-gray-700"
            >最大失败次数</label
          >
          <input
            type="number"
            id="MAX_FAILURES"
            name="MAX_FAILURES"
            min="1"
            max="100"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block"
            >API密钥失败后标记为无效的次数</small
          >
        </div>

        <!-- 请求超时时间 -->
        <div class="mb-6">
          <label for="TIME_OUT" class="block font-semibold mb-2 text-gray-700"
            >请求超时时间（秒）</label
          >
          <input
            type="number"
            id="TIME_OUT"
            name="TIME_OUT"
            min="1"
            max="600"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">API请求的超时时间</small>
        </div>

        <!-- 最大重试次数 -->
        <div class="mb-6">
          <label
            for="MAX_RETRIES"
            class="block font-semibold mb-2 text-gray-700"
            >最大重试次数</label
          >
          <input
            type="number"
            id="MAX_RETRIES"
            name="MAX_RETRIES"
            min="0"
            max="10"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block"
            >API请求失败后的最大重试次数</small
          >
        </div>
        <!-- 代理服务器列表 -->
        <div class="mb-6">
          <label for="PROXIES" class="block font-semibold mb-2 text-gray-700"
            >代理服务器列表</label
          >
          <div class="array-container" id="PROXIES_container">
            <!-- 代理项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2">
            <button
              type="button"
              class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="bulkDeleteProxyBtn"
            >
              <i class="fas fa-trash-alt"></i> 删除代理
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="addProxyBtn"
            >
              <i class="fas fa-plus"></i> 添加代理
            </button>
          </div>
          <small class="text-gray-500 mt-1 block"
            >代理服务器列表，支持 http 和 socks5 格式，例如:
            http://user:pass@host:port 或
            socks5://host:port。点击按钮可批量添加或删除。</small
          >
        </div>
      </div>

      <!-- 模型相关配置 -->
      <div class="config-section" id="model-section">
        <h2
          class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
        >
          <i class="fas fa-robot text-violet-400"></i> 模型相关配置
        </h2>

        <!-- 测试模型 -->
        <div class="mb-6">
          <label for="TEST_MODEL" class="block font-semibold mb-2 text-gray-700"
            >测试模型</label
          >
          <div class="flex items-center gap-2">
            <input
              type="text"
              id="TEST_MODEL"
              name="TEST_MODEL"
              placeholder="gemini-1.5-flash"
              class="flex-grow px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
            />
            <button
              type="button"
              title="选择模型"
              class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
              data-target-input-id="TEST_MODEL"
            >
              <i class="fas fa-list-ul"></i>
            </button>
          </div>
          <small class="text-gray-500 mt-1 block">用于测试API密钥的模型</small>
        </div>

        <!-- 图像模型列表 -->
        <div class="mb-6">
          <label
            for="IMAGE_MODELS"
            class="block font-semibold mb-2 text-gray-700"
            >图像模型列表</label
          >
          <div class="array-container" id="IMAGE_MODELS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2 mt-2">
            <button
              type="button"
              title="从列表选择模型添加到下方"
              class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
              data-target-array-key="IMAGE_MODELS"
            >
              <i class="fas fa-list-ul"></i>
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              onclick="addArrayItem('IMAGE_MODELS')"
            >
              <i class="fas fa-plus"></i> 添加模型
            </button>
          </div>
          <small class="text-gray-500 mt-1 block">支持图像处理的模型列表</small>
        </div>

        <!-- 搜索模型列表 -->
        <div class="mb-6">
          <label
            for="SEARCH_MODELS"
            class="block font-semibold mb-2 text-gray-700"
            >搜索模型列表</label
          >
          <div class="array-container" id="SEARCH_MODELS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2 mt-2">
            <button
              type="button"
              title="从列表选择模型添加到下方"
              class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
              data-target-array-key="SEARCH_MODELS"
            >
              <i class="fas fa-list-ul"></i>
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              onclick="addArrayItem('SEARCH_MODELS')"
            >
              <i class="fas fa-plus"></i> 添加模型
            </button>
          </div>
          <small class="text-gray-500 mt-1 block">支持搜索功能的模型列表</small>
        </div>

        <!-- 过滤模型列表 -->
        <div class="mb-6">
          <label
            for="FILTERED_MODELS"
            class="block font-semibold mb-2 text-gray-700"
            >过滤模型列表</label
          >
          <div class="array-container" id="FILTERED_MODELS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2 mt-2">
            <button
              type="button"
              title="从列表选择模型添加到下方"
              class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
              data-target-array-key="FILTERED_MODELS"
            >
              <i class="fas fa-list-ul"></i>
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              onclick="addArrayItem('FILTERED_MODELS')"
            >
              <i class="fas fa-plus"></i> 添加模型
            </button>
          </div>
          <small class="text-gray-500 mt-1 block">需要过滤的模型列表</small>
        </div>

        <!-- 启用代码执行工具 -->
        <div class="mb-6 flex items-center justify-between">
          <label
            for="TOOLS_CODE_EXECUTION_ENABLED"
            class="font-semibold text-gray-700"
            >启用代码执行工具</label
          >
          <div
            class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
          >
            <input
              type="checkbox"
              name="TOOLS_CODE_EXECUTION_ENABLED"
              id="TOOLS_CODE_EXECUTION_ENABLED"
              class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
            />
            <label
              for="TOOLS_CODE_EXECUTION_ENABLED"
              class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
            ></label>
          </div>
        </div>

        <!-- 显示搜索链接 -->
        <div class="mb-6 flex items-center justify-between">
          <label for="SHOW_SEARCH_LINK" class="font-semibold text-gray-700"
            >显示搜索链接</label
          >
          <div
            class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
          >
            <input
              type="checkbox"
              name="SHOW_SEARCH_LINK"
              id="SHOW_SEARCH_LINK"
              class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
            />
            <label
              for="SHOW_SEARCH_LINK"
              class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
            ></label>
          </div>
        </div>

        <!-- 显示思考过程 -->
        <div class="mb-6 flex items-center justify-between">
          <label for="SHOW_THINKING_PROCESS" class="font-semibold text-gray-700"
            >显示思考过程</label
          >
          <div
            class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
          >
            <input
              type="checkbox"
              name="SHOW_THINKING_PROCESS"
              id="SHOW_THINKING_PROCESS"
              class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
            />
            <label
              for="SHOW_THINKING_PROCESS"
              class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
            ></label>
          </div>
        </div>

        <!-- 思考模型列表 -->
        <div class="mb-6">
          <label
            for="THINKING_MODELS"
            class="block font-semibold mb-2 text-gray-700"
            >思考模型列表</label
          >
          <div class="array-container" id="THINKING_MODELS_container">
            <!-- 数组项将在这里动态添加 -->
          </div>
          <div class="flex justify-end gap-2 mt-2">
            <button
              type="button"
              title="从列表选择模型添加到下方"
              class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
              data-target-array-key="THINKING_MODELS"
            >
              <i class="fas fa-list-ul"></i>
            </button>
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              onclick="addArrayItem('THINKING_MODELS')"
            >
              <i class="fas fa-plus"></i> 添加模型
            </button>
          </div>
          <small class="text-gray-500 mt-1 block"
            >用于"思考过程"的模型列表</small
          >
        </div>

        <!-- 思考模型预算映射 -->
        <div class="mb-6">
          <label
            for="THINKING_BUDGET_MAP"
            class="block font-semibold mb-2 text-gray-700"
            >思考模型预算映射</label
          >
          <div
            class="bg-white rounded-lg border border-gray-200 p-4 mb-2 space-y-3"
            id="THINKING_BUDGET_MAP_container"
            style="
              background-color: rgba(255, 255, 255, 0.05);
              border: 1px solid rgba(120, 100, 200, 0.3);
              color: #e2e8f0;
            "
          >
            <!-- 键值对将在这里动态添加 -->
            <div class="text-gray-500 text-sm italic">
              请先在上方添加思考模型，然后在此处配置预算。
            </div>
          </div>
          <!-- 移除添加预算映射按钮 -->
          <!-- <div class="flex justify-end">
                            <button type="button" class="bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2" id="addBudgetMapItemBtn">
                                <i class="fas fa-plus"></i> 添加预算映射
                            </button>
                        </div> -->
          <small class="text-gray-500 mt-1 block"
            >为每个思考模型设置预算（整数，最大值
            24576），此项与上方模型列表自动关联。</small
          >
        </div>
        <!-- 安全设置 -->
        <div class="mb-6">
          <label
            for="SAFETY_SETTINGS"
            class="block font-semibold mb-2 text-gray-700"
            >安全设置 (Safety Settings)</label
          >
          <div
            class="bg-white rounded-lg border border-gray-200 p-4 mb-2 space-y-3"
            id="SAFETY_SETTINGS_container"
            style="
              background-color: rgba(255, 255, 255, 0.05);
              border: 1px solid rgba(120, 100, 200, 0.3);
              color: #e2e8f0;
            "
          >
            <!-- 安全设置项将在这里动态添加 -->
            <div class="text-gray-500 text-sm italic">
              定义模型的安全过滤阈值。
            </div>
          </div>
          <div class="flex justify-end">
            <button
              type="button"
              class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
              id="addSafetySettingBtn"
            >
              <i class="fas fa-plus"></i> 添加安全设置
            </button>
          </div>
          <small class="text-gray-500 mt-1 block"
            >配置模型的安全过滤级别，例如 HARM_CATEGORY_HARASSMENT:
            BLOCK_NONE。</small
          >
          <div class="warning-text">
            <i class="fas fa-exclamation-triangle"></i>
            <span
              >建议设置成OFF，其他值会影响输出速度，非必要不要随便改动。</span
            >
          </div>
        </div>
      </div>

      <!-- 图像生成相关配置 -->
      <div class="config-section" id="image-section">
        <h2
          class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
        >
          <i class="fas fa-image text-violet-400"></i> 图像生成配置
        </h2>

        <!-- 付费API密钥 -->
        <div class="mb-6">
          <label for="PAID_KEY" class="block font-semibold mb-2 text-gray-700"
            >付费API密钥</label
          >
          <input
            type="text"
            id="PAID_KEY"
            name="PAID_KEY"
            placeholder="AIzaSyxxxxxxxxxxxxxxxxxxx"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sensitive-input form-input-themed"
          />
          <small class="text-gray-500 mt-1 block"
            >用于图像生成的付费API密钥</small
          >
        </div>

        <!-- 图像生成模型 -->
        <div class="mb-6">
          <label
            for="CREATE_IMAGE_MODEL"
            class="block font-semibold mb-2 text-gray-700"
            >图像生成模型</label
          >
          <div class="flex items-center gap-2">
            <input
              type="text"
              id="CREATE_IMAGE_MODEL"
              name="CREATE_IMAGE_MODEL"
              placeholder="imagen-3.0-generate-002"
              class="flex-grow px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
            />
            <button
              type="button"
              title="选择模型"
              class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
              data-target-input-id="CREATE_IMAGE_MODEL"
            >
              <i class="fas fa-list-ul"></i>
            </button>
          </div>
          <small class="text-gray-500 mt-1 block">用于图像生成的模型</small>
        </div>

        <!-- 上传提供商 -->
        <div class="mb-6">
          <label
            for="UPLOAD_PROVIDER"
            class="block font-semibold mb-2 text-gray-700"
            >上传提供商</label
          >
          <select
            id="UPLOAD_PROVIDER"
            name="UPLOAD_PROVIDER"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-select-themed"
          >
            <option value="smms" selected>SM.MS</option>
            <option value="picgo">PicGo</option>
            <option value="cloudflare_imgbed">Cloudflare</option>
          </select>
          <small class="text-gray-500 mt-1 block">图片上传服务提供商</small>
        </div>

        <!-- SM.MS密钥 -->
        <div class="mb-6 provider-config active" data-provider="smms">
          <label
            for="SMMS_SECRET_TOKEN"
            class="block font-semibold mb-2 text-gray-700"
            >SM.MS密钥</label
          >
          <input
            type="text"
            id="SMMS_SECRET_TOKEN"
            name="SMMS_SECRET_TOKEN"
            placeholder="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sensitive-input form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">SM.MS图床的密钥</small>
        </div>

        <!-- PicGo API密钥 -->
        <div class="mb-6 provider-config" data-provider="picgo">
          <label
            for="PICGO_API_KEY"
            class="block font-semibold mb-2 text-gray-700"
            >PicGo API密钥</label
          >
          <input
            type="text"
            id="PICGO_API_KEY"
            name="PICGO_API_KEY"
            placeholder="xxxx"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sensitive-input form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">PicGo的API密钥</small>
        </div>

        <!-- Cloudflare图床URL -->
        <div class="mb-6 provider-config" data-provider="cloudflare_imgbed">
          <label
            for="CLOUDFLARE_IMGBED_URL"
            class="block font-semibold mb-2 text-gray-700"
            >Cloudflare图床URL</label
          >
          <input
            type="text"
            id="CLOUDFLARE_IMGBED_URL"
            name="CLOUDFLARE_IMGBED_URL"
            placeholder="https://xxxxxxx.pages.dev/upload"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">Cloudflare图床的URL</small>
        </div>

        <!-- Cloudflare认证码 -->
        <div class="mb-6 provider-config" data-provider="cloudflare_imgbed">
          <label
            for="CLOUDFLARE_IMGBED_AUTH_CODE"
            class="block font-semibold mb-2 text-gray-700"
            >Cloudflare认证码</label
          >
          <input
            type="text"
            id="CLOUDFLARE_IMGBED_AUTH_CODE"
            name="CLOUDFLARE_IMGBED_AUTH_CODE"
            placeholder="xxxxxxxxx"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sensitive-input form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">Cloudflare图床的认证码</small>
        </div>
      </div>

      <!-- 流式输出优化器配置 -->
      <div class="config-section" id="stream-section">
        <h2
          class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
        >
          <i class="fas fa-stream text-violet-400"></i> 流式输出优化器
        </h2>

        <!-- 启用流式输出优化 -->
        <div class="mb-6 flex items-center justify-between">
          <label
            for="STREAM_OPTIMIZER_ENABLED"
            class="font-semibold text-gray-700"
            >启用流式输出优化</label
          >
          <div
            class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
          >
            <input
              type="checkbox"
              name="STREAM_OPTIMIZER_ENABLED"
              id="STREAM_OPTIMIZER_ENABLED"
              class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
            />
            <label
              for="STREAM_OPTIMIZER_ENABLED"
              class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
            ></label>
          </div>
        </div>

        <!-- 最小延迟 -->
        <div class="mb-6">
          <label
            for="STREAM_MIN_DELAY"
            class="block font-semibold mb-2 text-gray-700"
            >最小延迟（秒）</label
          >
          <input
            type="number"
            id="STREAM_MIN_DELAY"
            name="STREAM_MIN_DELAY"
            min="0"
            max="1"
            step="0.001"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">流式输出的最小延迟时间</small>
        </div>

        <!-- 最大延迟 -->
        <div class="mb-6">
          <label
            for="STREAM_MAX_DELAY"
            class="block font-semibold mb-2 text-gray-700"
            >最大延迟（秒）</label
          >
          <input
            type="number"
            id="STREAM_MAX_DELAY"
            name="STREAM_MAX_DELAY"
            min="0"
            max="1"
            step="0.001"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">流式输出的最大延迟时间</small>
        </div>

        <!-- 短文本阈值 -->
        <div class="mb-6">
          <label
            for="STREAM_SHORT_TEXT_THRESHOLD"
            class="block font-semibold mb-2 text-gray-700"
            >短文本阈值</label
          >
          <input
            type="number"
            id="STREAM_SHORT_TEXT_THRESHOLD"
            name="STREAM_SHORT_TEXT_THRESHOLD"
            min="1"
            max="100"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">短文本的字符阈值</small>
        </div>

        <!-- 长文本阈值 -->
        <div class="mb-6">
          <label
            for="STREAM_LONG_TEXT_THRESHOLD"
            class="block font-semibold mb-2 text-gray-700"
            >长文本阈值</label
          >
          <input
            type="number"
            id="STREAM_LONG_TEXT_THRESHOLD"
            name="STREAM_LONG_TEXT_THRESHOLD"
            min="1"
            max="1000"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">长文本的字符阈值</small>
        </div>

        <!-- 分块大小 -->
        <div class="mb-6">
          <label
            for="STREAM_CHUNK_SIZE"
            class="block font-semibold mb-2 text-gray-700"
            >分块大小</label
          >
          <input
            type="number"
            id="STREAM_CHUNK_SIZE"
            name="STREAM_CHUNK_SIZE"
            min="1"
            max="100"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block">流式输出的分块大小</small>
        </div>

        <!-- Fake Streaming Configuration -->
        <h3
          class="text-lg font-semibold mb-4 pt-4 border-t border-violet-300 border-opacity-20 text-gray-200"
        >
          <i class="fas fa-ghost text-violet-400"></i> 假流式配置 (Fake
          Streaming)
        </h3>

        <!-- 启用假流式输出 -->
        <div class="mb-6 flex items-center justify-between">
          <label for="FAKE_STREAM_ENABLED" class="font-semibold text-gray-700"
            >启用假流式输出</label
          >
          <div
            class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
          >
            <input
              type="checkbox"
              name="FAKE_STREAM_ENABLED"
              id="FAKE_STREAM_ENABLED"
              class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
            />
            <label
              for="FAKE_STREAM_ENABLED"
              class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
            ></label>
          </div>
        </div>
        <small class="text-gray-500 mt-1 block mb-4"
          >当启用时，将调用非流式接口，并在等待响应期间发送空数据以维持连接。</small
        >

        <!-- 假流式发送空数据的间隔时间 -->
        <div class="mb-6">
          <label
            for="FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS"
            class="block font-semibold mb-2 text-gray-700"
            >假流式空数据发送间隔（秒）</label
          >
          <input
            type="number"
            id="FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS"
            name="FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS"
            min="1"
            max="60"
            step="1"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block"
            >在启用假流式输出时，向客户端发送空数据以维持连接状态的时间间隔（建议
            3-10 秒）。</small
          >
        </div>
      </div>

      <!-- 定时任务配置 -->
      <div class="config-section" id="scheduler-section">
        <h2
          class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
        >
          <i class="fas fa-clock text-violet-400"></i> 定时任务配置
        </h2>

        <!-- 检查间隔 -->
        <div class="mb-6">
          <label
            for="CHECK_INTERVAL_HOURS"
            class="block font-semibold mb-2 text-gray-700"
            >检查间隔（小时）</label
          >
          <input
            type="number"
            id="CHECK_INTERVAL_HOURS"
            name="CHECK_INTERVAL_HOURS"
            min="1"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block"
            >定时检查密钥状态的间隔时间（单位：小时）</small
          >
        </div>

        <!-- 时区 -->
        <div class="mb-6">
          <label for="TIMEZONE" class="block font-semibold mb-2 text-gray-700"
            >时区</label
          >
          <input
            type="text"
            id="TIMEZONE"
            name="TIMEZONE"
            placeholder="例如: Asia/Shanghai"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-input-themed"
          />
          <small class="text-gray-500 mt-1 block"
            >定时任务使用的时区，格式如 "Asia/Shanghai" 或 "UTC"</small
          >
        </div>
      </div>

      <!-- 日志配置 -->
      <div class="config-section" id="logging-section">
        <h2
          class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
        >
          <i class="fas fa-file-alt text-violet-400"></i> 日志配置
        </h2>

        <!-- 日志级别 -->
        <div class="mb-6">
          <label for="LOG_LEVEL" class="block font-semibold mb-2 text-gray-700"
            >日志级别</label
          >
          <select
            id="LOG_LEVEL"
            name="LOG_LEVEL"
            class="w-full px-4 py-3 rounded-lg form-select-themed"
          >
            <option value="DEBUG">DEBUG</option>
            <option value="INFO">INFO</option>
            <option value="WARNING">WARNING</option>
            <option value="ERROR">ERROR</option>
            <option value="CRITICAL">CRITICAL</option>
          </select>
          <small class="text-gray-500 mt-1 block"
            >设置应用程序的日志记录详细程度</small
          >
        </div>

        <!-- 自动删除错误日志 -->
        <div class="mb-6">
          <div class="flex items-center justify-between">
            <label
              for="AUTO_DELETE_ERROR_LOGS_ENABLED"
              class="font-semibold text-gray-700"
              >是否开启自动删除错误日志</label
            >
            <div
              class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
            >
              <input
                type="checkbox"
                name="AUTO_DELETE_ERROR_LOGS_ENABLED"
                id="AUTO_DELETE_ERROR_LOGS_ENABLED"
                class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
              />
              <label
                for="AUTO_DELETE_ERROR_LOGS_ENABLED"
                class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
              ></label>
            </div>
          </div>
          <small class="text-gray-500 mt-1 block"
            >开启后，将自动删除指定天数前的错误日志。</small
          >
        </div>

        <!-- 自动删除日志天数 -->
        <div class="mb-6">
          <label
            for="AUTO_DELETE_ERROR_LOGS_DAYS"
            class="block font-semibold mb-2 text-gray-700"
            >自动删除多少天前的错误日志</label
          >
          <select
            id="AUTO_DELETE_ERROR_LOGS_DAYS"
            name="AUTO_DELETE_ERROR_LOGS_DAYS"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-select-themed"
          >
            <option value="1">1 天</option>
            <option value="7">7 天</option>
            <option value="30">30 天</option>
          </select>
          <small class="text-gray-500 mt-1 block"
            >选择自动删除错误日志的天数。</small
          >
        </div>

        <!-- 自动删除请求日志 -->
        <div class="mb-6">
          <div class="flex items-center justify-between">
            <label
              for="AUTO_DELETE_REQUEST_LOGS_ENABLED"
              class="font-semibold text-gray-700"
              >是否开启自动删除请求日志</label
            >
            <div
              class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
            >
              <input
                type="checkbox"
                name="AUTO_DELETE_REQUEST_LOGS_ENABLED"
                id="AUTO_DELETE_REQUEST_LOGS_ENABLED"
                class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
              />
              <label
                for="AUTO_DELETE_REQUEST_LOGS_ENABLED"
                class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
              ></label>
            </div>
          </div>
          <small class="text-gray-500 mt-1 block"
            >开启后，将自动删除指定天数前的请求日志。</small
          >
        </div>

        <!-- 自动删除请求日志天数 -->
        <div class="mb-6">
          <label
            for="AUTO_DELETE_REQUEST_LOGS_DAYS"
            class="block font-semibold mb-2 text-gray-700"
            >自动删除多少天前的请求日志</label
          >
          <select
            id="AUTO_DELETE_REQUEST_LOGS_DAYS"
            name="AUTO_DELETE_REQUEST_LOGS_DAYS"
            class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 form-select-themed"
          >
            <option value="1">1 天</option>
            <option value="7">7 天</option>
            <option value="30">30 天</option>
          </select>
          <small class="text-gray-500 mt-1 block"
            >选择自动删除请求日志的天数。</small
          >
        </div>
      </div>

      <!-- Action Buttons -->
      <div class="flex flex-col md:flex-row justify-center gap-4 mt-8">
        <button
          type="button"
          id="saveBtn"
          class="bg-gradient-to-r from-violet-500 to-pink-500 text-white px-8 py-3 rounded-xl font-semibold transition-all duration-300 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center gap-2"
        >
          <i class="fas fa-save"></i> 保存配置
        </button>
        <button
          type="button"
          id="resetBtn"
          class="bg-gradient-to-r from-gray-600 to-gray-700 text-white px-8 py-3 rounded-xl font-semibold transition-all duration-300 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center gap-2"
          style="
            background-image: linear-gradient(
              to right,
              rgba(107, 70, 193, 0.7),
              rgba(120, 100, 200, 0.8)
            );
          "
        >
          <i class="fas fa-undo"></i> 重置配置
        </button>
      </div>
    </form>
  </div>
</div>

<!-- Scroll buttons are now in base.html -->
<div class="scroll-buttons">
  <button class="scroll-button" onclick="scrollToTop()" title="回到顶部">
    <i class="fas fa-chevron-up"></i>
  </button>
  <button class="scroll-button" onclick="scrollToBottom()" title="滚动到底部">
    <i class="fas fa-chevron-down"></i>
  </button>
</div>

<!-- Notification component is now in base.html -->
<div id="notification" class="notification"></div>
<!-- Footer is now in base.html -->

<!-- API Key Add Modal -->
<div id="apiKeyModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">批量添加 API 密钥</h2>
        <button
          id="closeApiKeyModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-4">
        每行粘贴一个或多个密钥，将自动提取有效密钥并去重。
      </p>
      <textarea
        id="apiKeyBulkInput"
        rows="10"
        placeholder="在此处粘贴 API 密钥..."
        class="w-full px-4 py-3 rounded-lg border font-mono text-sm form-input-themed"
      ></textarea>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="confirmAddApiKeyBtn"
          class="bg-violet-600 hover:bg-violet-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认添加
        </button>
        <button
          type="button"
          id="cancelAddApiKeyBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Bulk Delete API Key Modal -->
<div id="bulkDeleteApiKeyModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">批量删除 API 密钥</h2>
        <button
          id="closeBulkDeleteModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-4">
        每行粘贴一个或多个密钥，将自动提取有效密钥并从列表中删除。
      </p>
      <textarea
        id="bulkDeleteApiKeyInput"
        rows="10"
        placeholder="在此处粘贴要删除的 API 密钥..."
        class="w-full px-4 py-3 rounded-lg border font-mono text-sm form-input-themed focus:border-red-500 focus:ring-red-500"
      ></textarea>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="confirmBulkDeleteApiKeyBtn"
          class="bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认删除
        </button>
        <button
          type="button"
          id="cancelBulkDeleteApiKeyBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Proxy Add Modal -->
<div id="proxyModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">批量添加代理服务器</h2>
        <button
          id="closeProxyModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-4">
        每行粘贴一个或多个代理地址，将自动提取有效地址并去重。
      </p>
      <textarea
        id="proxyBulkInput"
        rows="10"
        placeholder="在此处粘贴代理地址 (例如 http://user:pass@host:port 或 socks5://host:port)..."
        class="w-full px-4 py-3 rounded-lg border font-mono text-sm form-input-themed"
      ></textarea>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="confirmAddProxyBtn"
          class="bg-violet-600 hover:bg-violet-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认添加
        </button>
        <button
          type="button"
          id="cancelAddProxyBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Bulk Delete Proxy Modal -->
<div id="bulkDeleteProxyModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">批量删除代理服务器</h2>
        <button
          id="closeBulkDeleteProxyModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-4">
        每行粘贴一个或多个代理地址，将自动提取有效地址并从列表中删除。
      </p>
      <textarea
        id="bulkDeleteProxyInput"
        rows="10"
        placeholder="在此处粘贴要删除的代理地址..."
        class="w-full px-4 py-3 rounded-lg border font-mono text-sm form-input-themed focus:border-red-500 focus:ring-red-500"
      ></textarea>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="confirmBulkDeleteProxyBtn"
          class="bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认删除
        </button>
        <button
          type="button"
          id="cancelBulkDeleteProxyBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Reset Confirmation Modal -->
<div id="resetConfirmModal" class="modal">
  <div
    class="w-full max-w-md mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">确认重置配置</h2>
        <button
          id="closeResetModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-6">
        确定要重置所有配置吗？<br />这将恢复到默认值，此操作不可撤销。
      </p>
      <div class="flex justify-end gap-3">
        <button
          type="button"
          id="confirmResetBtn"
          class="bg-red-500 hover:bg-red-600 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认重置
        </button>
        <button
          type="button"
          id="cancelResetBtn"
          class="bg-violet-600 hover:bg-violet-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>
 
<!-- Vertex API Key Add Modal -->
<div id="vertexApiKeyModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">批量添加 Vertex API 密钥</h2>
        <button
          id="closeVertexApiKeyModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-4">
        每行粘贴一个或多个密钥，将自动提取有效密钥 (格式: AQ.开头，共53位) 并去重。
      </p>
      <textarea
        id="vertexApiKeyBulkInput"
        rows="10"
        placeholder="在此处粘贴 Vertex API 密钥..."
        class="w-full px-4 py-3 rounded-lg border font-mono text-sm form-input-themed"
      ></textarea>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="confirmAddVertexApiKeyBtn"
          class="bg-violet-600 hover:bg-violet-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认添加
        </button>
        <button
          type="button"
          id="cancelAddVertexApiKeyBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>
 
<!-- Bulk Delete Vertex API Key Modal -->
<div id="bulkDeleteVertexApiKeyModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 class="text-xl font-bold text-gray-100">批量删除 Vertex API 密钥</h2>
        <button
          id="closeBulkDeleteVertexModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <p class="text-gray-300 mb-4">
        每行粘贴一个或多个密钥，将自动提取有效密钥并从列表中删除。
      </p>
      <textarea
        id="bulkDeleteVertexApiKeyInput"
        rows="10"
        placeholder="在此处粘贴要删除的 Vertex API 密钥..."
        class="w-full px-4 py-3 rounded-lg border font-mono text-sm form-input-themed focus:border-red-500 focus:ring-red-500"
      ></textarea>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="confirmBulkDeleteVertexApiKeyBtn"
          class="bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded-lg font-medium transition"
        >
          确认删除
        </button>
        <button
          type="button"
          id="cancelBulkDeleteVertexApiKeyBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          取消
        </button>
      </div>
    </div>
  </div>
</div>
 
<!-- Model Helper Modal -->
<div id="modelHelperModal" class="modal">
  <div
    class="w-full max-w-lg mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
    style="
      background-color: rgba(70, 50, 150, 0.95);
      color: #ffffff;
      border: 1px solid rgba(120, 100, 200, 0.4);
    "
  >
    <div class="p-6">
      <div class="flex justify-between items-center mb-4">
        <h2 id="modelHelperTitle" class="text-xl font-bold text-gray-100">
          选择模型
        </h2>
        <button
          id="closeModelHelperModalBtn"
          class="text-gray-300 hover:text-gray-100 text-xl"
        >
          &times;
        </button>
      </div>
      <input
        type="text"
        id="modelHelperSearchInput"
        placeholder="搜索模型..."
        class="w-full px-4 py-3 mb-4 rounded-lg border font-mono text-sm form-input-themed"
      />
      <div
        id="modelHelperListContainer"
        class="array-container"
        style="max-height: 300px; overflow-y: auto"
      >
        <!-- Model items will be populated here -->
        <p class="text-gray-400 text-sm italic">正在加载模型列表...</p>
      </div>
      <div class="flex justify-end gap-3 mt-6">
        <button
          type="button"
          id="cancelModelHelperBtn"
          class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
        >
          关闭
        </button>
      </div>
    </div>
  </div>
</div>

{% endblock %} {% block body_scripts %}
<script src="/static/js/config_editor.js"></script>
<!-- 增强下拉框样式和交互性 -->
<script>
  document.addEventListener("DOMContentLoaded", function () {
    // 增强所有下拉框的交互性
    const selects = document.querySelectorAll(".form-select-themed");

    selects.forEach((select) => {
      // 添加选择事件来应用选中效果
      select.addEventListener("change", function () {
        this.classList.add("selected");
        // 设置微小的动画效果
        this.style.transition = "all 0.2s ease";
        this.style.transform = "scale(1.02)";
        setTimeout(() => {
          this.style.transform = "scale(1)";
        }, 200);
      });

      // 添加焦点事件
      select.addEventListener("focus", function () {
        this.style.boxShadow = "0 0 0 3px rgba(216, 180, 254, 0.5)";
      });

      // 根据是否有选中值添加选中样式
      if (select.value && select.value !== "") {
        select.classList.add("selected");
      }
    });

    // 美化日志级别选择的显示
    const logLevelSelect = document.getElementById("LOG_LEVEL");
    if (logLevelSelect) {
      // 给不同日志级别添加不同的样式
      const updateLogLevelStyle = () => {
        const value = logLevelSelect.value;

        // 根据不同日志级别设置不同的样式
        switch (value) {
          case "DEBUG":
            logLevelSelect.style.borderColor = "rgba(129, 140, 248, 0.8)";
            logLevelSelect.style.color = "#c7d2fe"; // indigo-200
            break;
          case "INFO":
            logLevelSelect.style.borderColor = "rgba(96, 165, 250, 0.8)";
            logLevelSelect.style.color = "#bfdbfe"; // blue-200
            break;
          case "WARNING":
            logLevelSelect.style.borderColor = "rgba(251, 191, 36, 0.8)";
            logLevelSelect.style.color = "#fde68a"; // amber-200
            break;
          case "ERROR":
            logLevelSelect.style.borderColor = "rgba(239, 68, 68, 0.8)";
            logLevelSelect.style.color = "#fecaca"; // red-200
            break;
          case "CRITICAL":
            logLevelSelect.style.borderColor = "rgba(220, 38, 38, 0.8)";
            logLevelSelect.style.color = "#fca5a5"; // red-300
            break;
          default:
            logLevelSelect.style.borderColor = "rgba(167, 139, 250, 0.7)";
            logLevelSelect.style.color = "#ffffff";
        }
      };

      // 初始化和变更时更新样式
      updateLogLevelStyle();
      logLevelSelect.addEventListener("change", updateLogLevelStyle);
    }

    // 增强预算映射项交互
    const budgetInputs = document.querySelectorAll(".map-value-input");
    budgetInputs.forEach((input) => {
      // 添加焦点和悬停效果
      input.addEventListener("focus", function () {
        const parentItem = this.closest(".map-item");
        if (parentItem) {
          parentItem.style.backgroundColor = "rgba(60, 40, 130, 0.4)";
          parentItem.style.borderColor = "rgba(167, 139, 250, 0.7)";
        }
      });

      input.addEventListener("blur", function () {
        const parentItem = this.closest(".map-item");
        if (parentItem) {
          parentItem.style.backgroundColor = "";
          parentItem.style.borderColor = "";
        }
      });

      // 输入限制为正整数且不超过最大值
      input.addEventListener("input", function () {
        let val = this.value.replace(/[^0-9]/g, "");
        if (val !== "") {
          val = parseInt(val, 10);
          if (val > 24576) val = 24576;
        }
        this.value = val;

        // 添加微小动画反馈
        this.style.transform = "scale(1.05)";
        setTimeout(() => {
          this.style.transform = "scale(1)";
        }, 150);
      });
    });
  });
</script>
{% endblock %}
