{% extends "base.html" %} {% block title %}Amrita Dashboard - {{ plugin_name }} 配置编辑{% endblock %} {% block topbar_title %}{{ plugin_name }} 配置编辑{% endblock %} {% block extra_head %}
<link
  href="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.css"
  rel="stylesheet"
/>
{% endblock %} {% block extra_css %}
<style>
  .config-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
  }

  .config-section {
    background: var(--card-bg);
    border-radius: 8px;
    margin-bottom: 20px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  }

  body.dark-mode .config-section {
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  }

  .config-header {
    border-bottom: 1px solid var(--border-color);
    padding: 15px;
    display: flex;
    align-items: center;
    cursor: pointer;
  }

  body.dark-mode .config-header {
    border-bottom: 1px solid var(--dark-border-color);
  }

  .config-header:hover {
    background-color: var(--hover-bg);
  }

  body.dark-mode .config-header:hover {
    background-color: var(--dark-hover-bg);
  }

  .config-title {
    font-size: 20px;
    font-weight: 600;
    color: var(--text-color);
    margin: 0;
    flex-grow: 1;
    display: flex;
    align-items: center;
    gap: 10px;
  }

  body.dark-mode .config-title {
    color: var(--dark-text-color);
  }

  .collapse-icon {
    display: inline-block;
    font-size: 12px;
    transition: transform 0.3s ease;
    width: 20px;
    text-align: center;
  }

  .config-section.collapsed .collapse-icon {
    transform: rotate(-90deg);
  }

  .config-actions-header {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-left: auto;
    white-space: nowrap;
  }

  .config-content {
    padding: 0 20px 20px 20px;
    display: block;
  }

  .config-section.collapsed .config-content {
    display: none;
  }

  .field-item {
    display: flex;
    flex-wrap: wrap;
    padding: 15px 0;
    border-bottom: 1px solid var(--border-color);
  }

  .field-item:last-child {
    border-bottom: none;
  }

  body.dark-mode .field-item {
    border-bottom: 1px solid var(--dark-border-color);
  }

  .field-label {
    flex: 0 0 250px;
    padding-right: 20px;
  }

  .field-name {
    font-weight: 600;
    color: var(--text-color);
    margin-bottom: 5px;
    word-break: break-all;
  }

  body.dark-mode .field-name {
    color: var(--dark-text-color);
  }

  .field-description {
    font-size: 14px;
    color: #666;
    margin-bottom: 8px;
  }

  body.dark-mode .field-description {
    color: #aaa;
  }

  .field-default {
    font-size: 12px;
    color: #888;
    font-style: italic;
    margin-bottom: 8px;
  }

  body.dark-mode .field-default {
    color: #999;
  }

  .field-value {
    flex: 1;
    min-width: 300px;
  }

  .field-input {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--input-bg);
    color: var(--text-color);
    font-family: monospace;
  }

  body.dark-mode .field-input {
    border: 1px solid var(--dark-border-color);
    background: var(--dark-input-bg);
    color: var(--dark-text-color);
  }

  .field-input-select {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--input-bg);
    color: var(--text-color);
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 1em;
    transition: all 0.3s ease;
  }

  .field-input-select:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
  }

  body.dark-mode .field-input-select {
    border: 1px solid var(--dark-border-color);
    background: var(--dark-input-bg);
    color: var(--dark-text-color);
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
  }

  .field-input-bool-label {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: normal;
    margin: 0;
    cursor: pointer;
    color: var(--text-color);
    transition: color 0.3s ease;
  }

  body.dark-mode .field-input-bool-label {
    color: var(--dark-text-color);
  }

  .field-input-bool-container {
    display: flex;
    align-items: center;
    height: 100%;
  }

  .bool-switch {
    position: relative;
    display: inline-block;
    width: 50px;
    height: 24px;
  }

  .bool-switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }

  .bool-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    transition: 0.4s;
    border-radius: 24px;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
  }

  .bool-slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.4s;
    border-radius: 50%;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  }

  .bool-switch input:checked + .bool-slider {
    background-color: var(--primary-color);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
  }

  .bool-switch input:checked + .bool-slider:before {
    transform: translateX(26px);
  }

  .bool-switch input:focus + .bool-slider {
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
  }

  .bool-switch:hover .bool-slider {
    background-color: #b3b3b3;
  }

  .bool-switch input:checked:hover + .bool-slider {
    background-color: #007bff;
  }

  .field-type {
    font-size: 12px;
    color: #888;
    margin-top: 5px;
  }

  body.dark-mode .field-type {
    color: #999;
  }

  .list-editor {
    width: 100%;
  }

  .list-items {
    margin-bottom: 10px;
  }

  .sortable-list {
    min-height: 20px;
  }

  .list-item {
    display: flex;
    align-items: center;
    margin-bottom: 5px;
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 4px;
    padding: 8px;
  }

  body.dark-mode .list-item {
    background: var(--dark-card-bg);
    border: 1px solid var(--dark-border-color);
  }

  .list-item.sortable-ghost {
    opacity: 0.4;
  }

  .list-item.sortable-chosen {
    background: var(--hover-bg);
  }

  body.dark-mode .list-item.sortable-chosen {
    background: var(--dark-hover-bg);
  }

  .list-item-input {
    flex: 1;
    padding: 6px 10px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--input-bg);
    color: var(--text-color);
    font-family: monospace;
    margin-right: 5px;
  }

  body.dark-mode .list-item-input {
    border: 1px solid var(--dark-border-color);
    background: var(--dark-input-bg);
    color: var(--dark-text-color);
  }

  .list-item-actions {
    display: flex;
    gap: 5px;
  }

  .drag-handle {
    padding: 6px 10px;
    cursor: grab;
    color: #666;
    display: flex;
    align-items: center;
    user-select: none;
  }

  .drag-handle:hover {
    color: #000;
  }

  body.dark-mode .drag-handle:hover {
    color: #fff;
  }

  .list-item-btn {
    padding: 6px 10px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--input-bg);
    color: var(--text-color);
    cursor: pointer;
    line-height: 1;
  }

  body.dark-mode .list-item-btn {
    border: 1px solid var(--dark-border-color);
    background: var(--dark-input-bg);
    color: var(--dark-text-color);
  }

  .list-add-btn {
    padding: 6px 10px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--input-bg);
    color: var(--text-color);
    cursor: pointer;
    font-size: 14px;
  }

  body.dark-mode .list-add-btn {
    border: 1px solid var(--dark-border-color);
    background: var(--dark-input-bg);
    color: var(--dark-text-color);
  }

  .config-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 10px;
    padding-top: 10px;
    margin-bottom: 20px;
    border-top: 1px solid var(--border-color);
  }

  body.dark-mode .config-actions {
    border-top: 1px solid var(--dark-border-color);
  }

  .btn {
    padding: 10px 20px;
    border-radius: 4px;
    border: none;
    cursor: pointer;
    font-size: 14px;
    transition: all 0.3s;
  }

  .btn-primary {
    background: var(--primary-color);
    color: white;
  }

  .btn-primary:hover {
    opacity: 0.9;
  }

  .btn-secondary {
    background: #6c757d;
    color: white;
  }

  .btn-secondary:hover {
    background: #5a6268;
  }

  .btn-success {
    background: #28a745;
    color: white;
  }

  .btn-warning {
    background: #ffc107;
    color: #212529;
  }

  .btn-danger {
    background: #dc3545;
    color: white;
  }

  .alert {
    padding: 15px;
    border-radius: 4px;
    margin-bottom: 20px;
  }

  .alert-success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
  }

  .alert-error {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid #f5c6cb;
  }

  .alert-warning {
    background: #fff3cd;
    color: #856404;
    border: 1px solid #ffeaa7;
  }

  .status-indicator {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 5px;
  }

  .status-modified {
    background-color: #ffc107;
  }

  .status-saved {
    background-color: #28a745;
  }

  .status-unmodified {
    background-color: #6c757d;
  }

  .nested-field {
    margin: 10px 0;
    border-left: 3px solid #007bff;
    background-color: var(--hover-bg);
    border-radius: 4px;
    padding: 0 10px 10px;
  }

  .nested-field-header {
    cursor: pointer;
    display: flex;
    align-items: center;
    padding: 10px;
    background-color: var(--card-bg);
    border-radius: 4px;
    margin-top: 10px;
    margin-left: -10px;
    margin-right: -10px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--border-color);
  }

  body.dark-mode .nested-field-header {
    background-color: var(--dark-card-bg);
  }

  .nested-field-header:hover {
    background-color: var(--hover-bg);
  }

  body.dark-mode .nested-field-header:hover {
    background-color: var(--dark-hover-bg);
  }

  .nested-field-header .collapse-icon {
    margin-right: 8px;
    transition: transform 0.3s ease;
  }

  .nested-field-header.collapsed .collapse-icon {
    transform: rotate(-90deg);
  }

  .nested-field-content {
    margin-top: 5px;
    padding-left: 25px;
    border-left: 1px dashed var(--border-color);
    padding-top: 10px;
    max-height: none;
    overflow: visible;
    transition: max-height 0.3s ease, padding 0.3s ease;
  }

  body.dark-mode .nested-field-content {
    border-left: 1px dashed var(--dark-border-color);
  }
  
  .nested-field-child {
    margin: 8px 0;
    padding: 8px 0;
  }
  
  .nested-field-child .field-label {
    padding-right: 20px;
  }
  
  .nested-field-child .field-value {
    min-width: 300px;
  }

  .nested-field.collapsed .nested-field-content {
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
    overflow: hidden;
  }

  .nested-field-child {
    margin: 8px 0;
  }

  @media (max-width: 768px) {
    .field-item {
      flex-direction: column;
    }

    .field-label {
      flex: 0 0 auto;
      margin-bottom: 10px;
      padding-right: 0;
    }

    .field-value {
      flex: 0 0 auto;
      min-width: auto;
      width: 100%;
    }

    .config-header {
      flex-direction: column;
      align-items: stretch;
      gap: 10px;
    }

    .config-title {
      flex-direction: column;
      align-items: flex-start;
      gap: 5px;
    }

    .config-actions-header {
      align-self: stretch;
      justify-content: flex-start;
    }
  }
</style>
{% endblock %} {% block content %}
<div class="config-container">
  <div style="margin-bottom: 20px;">
    <a href="/system/confedit" style="color: var(--primary-color); text-decoration: none; display: inline-flex; align-items: center;">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 5px;">
        <path d="M19 12H5M12 19l-7-7 7-7"></path>
      </svg>
      返回配置管理
    </a>
  </div>
  
  <div class="alert alert-success" id="success-alert" style="display: none">
    配置已成功保存！
  </div>

  <div class="alert alert-error" id="error-alert" style="display: none">
    保存配置时出错，请重试。
  </div>

  <div class="alert alert-warning" id="warning-alert" style="display: none">
    警告信息
  </div>

  <h2>{{ plugin_name }} 配置编辑</h2>
  <p>
    在此页面可以查看和修改 {{ plugin_name }} 插件的配置项。系统会自动检测配置变化并仅提交已修改的配置。<br />
    嵌套配置项将以 <code>parent.child</code> 的形式显示。
  </p>

  <div class="config-actions">
    <button class="btn btn-secondary" onclick="resetPluginConfig()">
      重置
    </button>
    <button class="btn btn-primary" onclick="savePluginConfig()">
      保存修改
    </button>
  </div>

  <div class="config-section" id="section-{{ plugin_name }}">
    <div class="config-header" onclick="toggleSection()">
      <h3 class="config-title">
        <span class="collapse-icon">▼</span>
        {{ plugin_name }} ({{ plugin_info.class_name }})
      </h3>
      <div class="config-actions-header">
        <span
          class="status-indicator status-unmodified"
          id="status-{{ plugin_name }}"
        ></span>
        <button
          class="btn btn-secondary"
          onclick="resetPluginConfig(event)"
        >
          重置
        </button>
        <button
          class="btn btn-primary"
          onclick="savePluginConfig(event)"
        >
          保存
        </button>
      </div>
    </div>
    <div class="config-content">
      {% if plugin_info.fields %}
        <!-- 预处理字段以分组嵌套字段 -->
        {% set grouped_fields = {} %}
        {% set standalone_fields = [] %}
        
        {% for field in plugin_info.fields %}
          {% if '.' in field.name %}
            {% set parent_name = field.name.split('.')[0] %}
            {% set child_name = field.name.split('.')[1:]|join('.') %}
            {% if parent_name not in grouped_fields %}
              {% set _ = grouped_fields.update({parent_name: []}) %}
            {% endif %}
            {% set _ = grouped_fields[parent_name].append({'field': field, 'child_name': child_name}) %}
          {% else %}
            {% set _ = standalone_fields.append(field) %}
          {% endif %}
        {% endfor %}
        
        <!-- 渲染独立字段 -->
        {% for field in standalone_fields %}
        <div
          class="field-item"
          data-field="{{ field.name }}"
          data-type="{{ field.type }}"
        >
          <div class="field-label">
            <div class="field-name">{{ field.name }}</div>
            <div class="field-description">
              {{ field.description or '无描述' }}
            </div>
            {% if field.default != None %}
            <div class="field-default">默认: {{ field.default }}</div>
            {% endif %}
            <div class="field-type">{{ field.type }}</div>
          </div>
          <div class="field-value">
            {% if field.type == 'bool' %}
            <div class="field-input-bool-container">
              <label class="field-input-bool-label">
                <div class="bool-switch">
                  <input type="checkbox" id="{{ field.name |
                  replace('.', '_DOT_') }}" name="{{ field.name
                  }}" data-original-value="{{ field.current_value | string }}"
                  onchange="markFieldAsModified()" {% if field.current_value == true %}checked{%
                  endif %}>
                  <span class="bool-slider"></span>
                </div>
                <span
                  id="{{ field.name | replace('.', '_DOT_') }}_text"
                >
                  {% if field.current_value == true %}True{% else %}False{% endif
                  %}
                </span>
              </label>
            </div>
            {% elif field.type == 'literal' %}
            <select
              class="field-input-select"
              id="{{ field.name | replace('.', '_DOT_') }}"
              name="{{ field.name }}"
              data-original-value="{{ field.current_value | string }}"
              onchange="markFieldAsModified()"
            >
              {% for value in field.literal_values %}
              <option value="{{ value }}"
                {% if field.current_value == value or (field.current_value == 'true' and value == true) or (field.current_value == 'false' and value == false) %}selected{% endif %}>
                {{ value }}
              </option>
              {% endfor %}
            </select>
            {% elif field.type == 'list' %}
            <div
              class="list-editor"
              id="{{ field.name | replace('.', '_DOT_') }}_editor"
            >
              <div
                class="list-items sortable-list"
                id="{{ field.name | replace('.', '_DOT_') }}_items"
              ></div>
              <button
                class="list-add-btn"
                type="button"
                onclick="addListItem('{{ field.name }}', event)"
              >
                + 添加项
              </button>
              <input
                type="hidden"
                id="{{ field.name | replace('.', '_DOT_') }}"
                name="{{ field.name }}"
                value="{{ field.current_value | string }}"
                data-original-value="{{ field.current_value | string }}"
              />
            </div>
            {% else %}
            <input
              type="text"
              class="field-input"
              id="{{ field.name | replace('.', '_DOT_') }}"
              name="{{ field.name }}"
              value="{{ field.current_value | string }}"
              placeholder="{{ field.default | string }}"
              data-original-value="{{ field.current_value | string }}"
              onchange="markFieldAsModified()"
            />
            {% endif %}
          </div>
        </div>
        {% endfor %}
        
        <!-- 渲染分组的嵌套字段 -->
        {% for parent_name, children in grouped_fields.items() %}
        <div class="field-item nested-field" data-parent="{{ parent_name }}">
          <div class="nested-field-header" onclick="toggleNestedField(this)">
            <span class="collapse-icon">▼</span>
            <strong>{{ parent_name }} 配置组</strong>
          </div>
          <div class="nested-field-content">
            {% for item in children %}
              {% set field = item['field'] %}
              {% set child_name = item['child_name'] %}
            <div
              class="field-item nested-field-child"
              data-field="{{ field.name }}"
              data-type="{{ field.type }}"
            >
              <div class="field-label">
                <div class="field-name">{{ child_name }}</div>
                <div class="field-description">
                  {{ field.description or '无描述' }}
                </div>
                {% if field.default != None %}
                <div class="field-default">默认: {{ field.default }}</div>
                {% endif %}
                <div class="field-type">{{ field.type }}</div>
              </div>
              <div class="field-value">
                {% if field.type == 'bool' %}
                <div class="field-input-bool-container">
                  <label class="field-input-bool-label">
                    <div class="bool-switch">
                      <input type="checkbox" id="{{ field.name |
                      replace('.', '_DOT_') }}" name="{{ field.name
                      }}" data-original-value="{{ field.current_value | string }}"
                      onchange="markFieldAsModified()" {% if field.current_value == true %}checked{%
                      endif %}>
                      <span class="bool-slider"></span>
                    </div>
                    <span
                      id="{{ field.name | replace('.', '_DOT_') }}_text"
                    >
                      {% if field.current_value == true %}True{% else %}False{% endif
                      %}
                    </span>
                  </label>
                </div>
                {% elif field.type == 'literal' %}
                <select
                  class="field-input-select"
                  id="{{ field.name | replace('.', '_DOT_') }}"
                  name="{{ field.name }}"
                  data-original-value="{{ field.current_value | string }}"
                  onchange="markFieldAsModified()"
                >
                  {% for value in field.literal_values %}
                  <option value="{{ value }}"
                    {% if field.current_value == value or (field.current_value == 'true' and value == true) or (field.current_value == 'false' and value == false) %}selected{% endif %}>
                    {{ value }}
                  </option>
                  {% endfor %}
                </select>
                {% elif field.type == 'list' %}
                <div
                  class="list-editor"
                  id="{{ field.name | replace('.', '_DOT_') }}_editor"
                >
                  <div
                    class="list-items sortable-list"
                    id="{{ field.name | replace('.', '_DOT_') }}_items"
                  ></div>
                  <button
                    class="list-add-btn"
                    type="button"
                    onclick="addListItem('{{ field.name }}', event)"
                  >
                    + 添加项
                  </button>
                  <input
                    type="hidden"
                    id="{{ field.name | replace('.', '_DOT_') }}"
                    name="{{ field.name }}"
                    value="{{ field.current_value | string }}"
                    data-original-value="{{ field.current_value | string }}"
                  />
                </div>
                {% else %}
                <input
                  type="text"
                  class="field-input"
                  id="{{ field.name | replace('.', '_DOT_') }}"
                  name="{{ field.name }}"
                  value="{{ field.current_value | string }}"
                  placeholder="{{ field.default | string }}"
                  data-original-value="{{ field.current_value | string }}"
                  onchange="markFieldAsModified()"
                />
                {% endif %}
              </div>
            </div>
            {% endfor %}
          </div>
        </div>
        {% endfor %}
      {% else %}
      <p>该插件暂无配置项。</p>
      {% endif %}
    </div>
  </div>

  <div class="config-actions">
    <button class="btn btn-secondary" onclick="resetPluginConfig()">
      重置
    </button>
    <button class="btn btn-primary" onclick="savePluginConfig()">
      保存修改
    </button>
  </div>
</div>
{% endblock %} {% block scripts %}
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
<script>
  const pluginHash = "{{ config_hash }}";
  let isModified = false;
  const sortableInstances = {};

  document.addEventListener('DOMContentLoaded', function() {
      initializeListFields();
      updatePluginStatus('unmodified');
      
      // 自动折叠所有嵌套字段
      const nestedFields = document.querySelectorAll('.field-item.nested-field');
      nestedFields.forEach(field => {
          field.classList.add('collapsed');
          
          // 查找对应的header并设置图标
          const header = field.querySelector('.nested-field-header');
          if (header) {
              const icon = header.querySelector('.collapse-icon');
              if (icon) {
                  icon.style.transform = 'rotate(-90deg)';
              }
          }
      });
  });

  function toggleSection() {
      const section = document.getElementById(`section-{{ plugin_name }}`);
      section.classList.toggle('collapsed');
  }

  function initializeListFields() {
      const listFields = document.querySelectorAll('[data-type="list"]');
      
      listFields.forEach(fieldItem => {
          const fieldName = fieldItem.dataset.field;
          const fieldId = `${fieldName.replace(/\./g, '_DOT_')}`;
          const hiddenInput = document.getElementById(fieldId);
          const itemsContainer = document.getElementById(`${fieldId}_items`);

          if (hiddenInput && itemsContainer) {
              try {
                  const currentValue = hiddenInput.value;
                  const listValue = currentValue ? JSON.parse(currentValue.replace(/'/g, '"')) : [];
                  renderListItems(fieldName, listValue, itemsContainer);
                  initSortableList(fieldName, itemsContainer);
              } catch (e) {
                  renderListItems(fieldName, [], itemsContainer);
                  initSortableList(fieldName, itemsContainer);
              }
          }
      });
  }

  function initSortableList(fieldName, container) {
      const fieldId = `${fieldName.replace(/\./g, '_DOT_')}`;

      if (sortableInstances[fieldId]) {
          sortableInstances[fieldId].destroy();
      }

      sortableInstances[fieldId] = new Sortable(container, {
          animation: 150,
          ghostClass: 'sortable-ghost',
          chosenClass: 'sortable-chosen',
          dragClass: 'sortable-drag',
          handle: '.drag-handle',
          onEnd: function() {
              updateListValue(fieldName);
              markFieldAsModified();
          }
      });
  }

  function renderListItems(fieldName, listValue, container) {
      const fieldId = `${fieldName.replace(/\./g, '_DOT_')}`;
      container.innerHTML = '';

      listValue.forEach((item, index) => {
          const listItem = document.createElement('div');
          listItem.className = 'list-item';
          listItem.innerHTML = `
              <div class="drag-handle">≡</div>
              <input type="text" class="list-item-input" value="${item}"
                     onchange="updateListValue('${fieldName}')">
              <div class="list-item-actions">
                  <button class="list-item-btn btn-danger" type="button" onclick="removeListItem('${fieldName}', ${index}, event)">×</button>
              </div>
          `;
          container.appendChild(listItem);
      });

      updateListValue(fieldName);
  }

  function addListItem(fieldName, event) {
      if (event) event.stopPropagation();

      const fieldId = `${fieldName.replace(/\./g, '_DOT_')}`;
      const itemsContainer = document.getElementById(`${fieldId}_items`);

      if (itemsContainer) {
          const listItem = document.createElement('div');
          listItem.className = 'list-item';
          listItem.innerHTML = `
              <div class="drag-handle">≡</div>
              <input type="text" class="list-item-input" value=""
                     onchange="updateListValue('${fieldName}')">
              <div class="list-item-actions">
                  <button class="list-item-btn btn-danger" type="button" onclick="removeListItem('${fieldName}', ${itemsContainer.children.length}, event)">×</button>
              </div>
          `;
          itemsContainer.appendChild(listItem);
          updateListValue(fieldName);
          markFieldAsModified();
      }
  }

  function removeListItem(fieldName, index, event) {
      if (event) event.stopPropagation();

      const fieldId = `${fieldName.replace(/\./g, '_DOT_')}`;
      const itemsContainer = document.getElementById(`${fieldId}_items`);

      if (itemsContainer && itemsContainer.children[index]) {
          itemsContainer.removeChild(itemsContainer.children[index]);
          updateListValue(fieldName);
          markFieldAsModified();
      }
  }

  function updateListValue(fieldName) {
      const fieldId = `${fieldName.replace(/\./g, '_DOT_')}`;
      const itemsContainer = document.getElementById(`${fieldId}_items`);
      const hiddenInput = document.getElementById(fieldId);

      if (itemsContainer && hiddenInput) {
          const values = [];
          const inputs = itemsContainer.querySelectorAll('.list-item-input');
          inputs.forEach(input => {
              if (input.value.trim() !== '') {
                  values.push(input.value);
              }
          });

          hiddenInput.value = JSON.stringify(values);
      }
  }

  function markFieldAsModified() {
      isModified = true;
      updatePluginStatus('modified');
  }

  function updatePluginStatus(status) {
      var indicator = document.getElementById(`status-{{ plugin_name }}`);
      if (indicator) {
          indicator.className = 'status-indicator';
          indicator.classList.add(`status-${status}`);
      }
  }

  function resetPluginConfig(event) {
      if (event) event.stopPropagation();

      const inputs = document.querySelectorAll(`.field-input, .field-input-select, .list-editor input[type="hidden"], .bool-switch input`);

      inputs.forEach(input => {
          const originalValue = input.getAttribute('data-original-value');
          if (input.tagName === 'INPUT' && input.type === 'hidden') {
              const fieldId = input.id;
              const fieldName = input.name;
              try {
                  const listValue = originalValue ? JSON.parse(originalValue.replace(/'/g, '"')) : [];
                  const itemsContainer = document.getElementById(`${fieldId}_items`);
                  if (itemsContainer) {
                      renderListItems(fieldName, listValue, itemsContainer);
                      initSortableList(fieldName, itemsContainer);
                  }
              } catch (e) {}
              input.value = originalValue;
          } else if (input.type === 'checkbox') {
              // Handle boolean switches
              const isChecked = (originalValue === 'True');
              input.checked = isChecked;
              // Update text label next to switch
              const textElement = document.getElementById(`${input.id}_text`);
              if (textElement) {
                  textElement.textContent = isChecked ? 'True' : 'False';
              }
          } else if (input.tagName === 'SELECT') {
              input.value = originalValue;
          } else {
              input.value = originalValue;
          }
      });

      isModified = false;
      updatePluginStatus('unmodified');
      showAlert('success', '配置已重置');
  }

  async function savePluginConfig(event) {
      if (event) event.stopPropagation();

      showLoading();

      try {
          const inputs = document.querySelectorAll('.field-input, .field-input-select, .list-editor input[type="hidden"], .bool-switch input');
          const configData = {};

          inputs.forEach(input => {
              const fieldName = input.name;
              if (input.type === 'checkbox') {
                  // Handle boolean switches
                  configData[fieldName] = input.checked.toString();
              } else {
                  configData[fieldName] = input.value;
              }
          });

          const response = await fetch(`/api/confedit/{{ plugin_name }}`, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                  config: configData,
                  hash: pluginHash
              })
          });

          const result = await response.json();

          if (result.code === 200) {
              inputs.forEach(input => {
                  if (input.type === 'checkbox') {
                      input.setAttribute('data-original-value', input.checked.toString());
                  } else {
                      input.setAttribute('data-original-value', input.value);
                  }
              });

              isModified = false;
              updatePluginStatus('saved');
              
              // 使用Swal.fire代替页面顶部提示
              Swal.fire({
                  title: '配置保存成功!',
                  text: '配置已成功保存，点击确定刷新页面。',
                  icon: 'success',
                  confirmButtonText: '确定',
                  willClose: () => {
                      // 刷新页面
                      window.location.reload();
                  }
              });
          } else if (result.code === 409) {
              window.location.reload();
          } else {
              // 错误情况仍使用Swal.fire
              Swal.fire({
                  title: '配置保存失败',
                  text: result.message,
                  icon: 'error',
                  confirmButtonText: '确定'
              });
          }
      } catch (error) {
          // 错误情况也使用Swal.fire
          Swal.fire({
              title: '保存配置时发生错误',
              text: error.message,
              icon: 'error',
              confirmButtonText: '确定'
          });
      } finally {
          hideLoading();
      }
  }

  function showAlert(type, message) {
      // 原来的showAlert函数已不再使用，但仍保留以备不时之需
      const successAlert = document.getElementById('success-alert');
      const errorAlert = document.getElementById('error-alert');
      const warningAlert = document.getElementById('warning-alert');

      successAlert.style.display = 'none';
      errorAlert.style.display = 'none';
      warningAlert.style.display = 'none';

      if (type === 'success') {
          successAlert.textContent = message;
          successAlert.style.display = 'block';
      } else if (type === 'error') {
          errorAlert.textContent = message;
          errorAlert.style.display = 'block';
      } else if (type === 'warning') {
          warningAlert.textContent = message;
          warningAlert.style.display = 'block';
      }

      setTimeout(() => {
          successAlert.style.display = 'none';
          errorAlert.style.display = 'none';
          warningAlert.style.display = 'none';
      }, 3000);
  }
  

  function toggleNestedField(element) {
      const parentDiv = element.parentElement;
      parentDiv.classList.toggle('collapsed');
      
      // 更新图标方向
      const icon = element.querySelector('.collapse-icon');
      if (parentDiv.classList.contains('collapsed')) {
          icon.style.transform = 'rotate(-90deg)';
      } else {
          icon.style.transform = 'rotate(0deg)';
      }
  }
  
</script>
{% endblock %}