{% extends "base.html" %}

{% block title %}配置管理{% endblock %}
{% block nav_config %}bg-zinc-100 font-semibold text-zinc-900{% endblock %}
{% block header %}配置管理{% endblock %}

{% block content %}
<div class="space-y-6 max-w-4xl mx-auto">

    <div id="loading-overlay" class="hidden fixed inset-0 bg-white/70 z-50 flex items-center justify-center">
        <svg class="animate-spin h-8 w-8 text-amber-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg>
    </div>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
            <span>日志配置</span>
        </h3>
        <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
            <div>
                <label for="log_level" class="block text-sm font-medium mb-1">日志级别</label>
                <select id="log_level" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
                    <option value="DEBUG">Debug</option>
                    <option value="INFO">Info</option>
                    <option value="SUCCESS">Success</option>
                    <option value="WARNING">Warning</option>
                    <option value="ERROR">Error</option>
                    <option value="CRITICAL">Critical</option>
                </select>
            </div>
        </div>
    </section>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /></svg>
            <span>Web 配置</span>
        </h3>
        <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
            <div>
                <label class="block text-sm font-medium mb-1">启用 Web 界面</label>
                <button id="web_enabled_switch" type="button"
                    class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none bg-zinc-200"
                    data-enabled="false">
                    <span class="sr-only">启用 Web 界面</span>
                    <span id="web_enabled_knob"
                        class="inline-block h-4 w-4 transform rounded-full bg-white transition-transform"></span>
                </button>
            </div>
            <div>
                <label for="web_host" class="block text-sm font-medium mb-1">Host</label>
                <input id="web_host" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500" placeholder="127.0.0.1">
            </div>
            <div>
                <label for="web_port" class="block text-sm font-medium mb-1">Port</label>
                <input id="web_port" type="number" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500" placeholder="8000">
            </div>
            <div>
                <label for="interval_hours" class="block text-sm font-medium mb-1">RSS 更新间隔 (小时)</label>
                <input id="interval_hours" type="number" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500" placeholder="6">
            </div>
        </div>
    </section>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
            <span>Aria2 配置</span>
        </h3>
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
            <div>
                <label for="aria2_rpc" class="block text-sm font-medium mb-1">RPC 地址</label>
                <input id="aria2_rpc" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500" placeholder="http://localhost:6800/jsonrpc">
            </div>
            <div>
                <label for="aria2_secret" class="block text-sm font-medium mb-1">RPC 密钥</label>
                <input id="aria2_secret" type="password" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
            </div>
            <div>
                <label for="aria2_dir" class="block text-sm font-medium mb-1">下载目录</label>
                <input id="aria2_dir" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
            </div>
        </div>
        <div class="mt-4">
            <button type="button" id="test_aria2" class="px-4 py-2 text-sm bg-white border border-zinc-200 rounded-md hover:bg-zinc-50">测试连接</button>
        </div>
    </section>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
             <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
            <span>qBittorrent 配置</span>
        </h3>
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
            <div>
                <label for="qb_host" class="block text-sm font-medium mb-1">Host</label>
                <input id="qb_host" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500" placeholder="http://localhost:8080">
            </div>
            <div>
                <label for="qb_username" class="block text-sm font-medium mb-1">用户名</label>
                <input id="qb_username" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
            </div>
            <div>
                <label for="qb_password" class="block text-sm font-medium mb-1">密码</label>
                <input id="qb_password" type="password" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
            </div>
        </div>
         <div class="mt-4">
            <button type="button" id="test_qb" class="px-4 py-2 text-sm bg-white border border-zinc-200 rounded-md hover:bg-zinc-50">测试连接</button>
        </div>
    </section>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
            <span>Transmission 配置</span>
        </h3>
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
            <div>
                <label for="trans_host" class="block text-sm font-medium mb-1">Host</label>
                <input id="trans_host" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500" placeholder="http://localhost:9091">
            </div>
            <div>
                <label for="trans_username" class="block text-sm font-medium mb-1">用户名</label>
                <input id="trans_username" type="text" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
            </div>
            <div>
                <label for="trans_password" class="block text-sm font-medium mb-1">密码</label>
                <input id="trans_password" type="password" class="w-full border border-zinc-200 rounded px-3 py-2 focus:ring-amber-500 focus:border-amber-500">
            </div>
        </div>
        <div class="mt-4">
            <button type="button" id="test_trans" class="px-4 py-2 text-sm bg-white border border-zinc-200 rounded-md hover:bg-zinc-50">测试连接</button>
        </div>
    </section>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" /></svg>
            <span>Webhook 配置</span>
        </h3>
        <div class="overflow-x-auto">
            <table class="w-full text-sm">
                <thead class="bg-zinc-50 text-left">
                    <tr>
                        <th class="px-3 py-2 font-medium text-zinc-600">名称</th>
                        <th class="px-3 py-2 font-medium text-zinc-600">Webhook URL</th>
                        <th class="px-3 py-2 font-medium text-zinc-600 w-40">启用</th>
                        <th class="px-3 py-2 font-medium text-zinc-600 w-20 text-center">操作</th>
                    </tr>
                </thead>
                <tbody id="webhooks-table" class="divide-y divide-zinc-200">
                </tbody>
            </table>
        </div>
        <button type="button" id="add-webhook" class="mt-4 inline-flex items-center gap-2 px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clip-rule="evenodd" /></svg>
            <span>添加 Webhook</span>
        </button>
    </section>

    <section class="bg-white p-6 rounded-lg shadow-sm border border-zinc-200">
        <h3 class="text-lg font-semibold mb-4 border-b border-zinc-200 pb-3 flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-zinc-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3h9M7 16h6M7 8h6v4H7V8z" /></svg>
            <span>RSS 源</span>
        </h3>
        <div class="overflow-x-auto">
            <table class="w-full text-sm">
                <thead class="bg-zinc-50 text-left">
                    <tr>
                        <th class="px-3 py-2 font-medium text-zinc-600">名称</th>
                        <th class="px-3 py-2 font-medium text-zinc-600">URL</th>
                        <th class="px-3 py-2 font-medium text-zinc-600 w-40">下载器</th>
                        <th class="px-3 py-2 font-medium text-zinc-600 w-20 text-center">操作</th>
                    </tr>
                </thead>
                <tbody id="feeds-table" class="divide-y divide-zinc-200">
                </tbody>
            </table>
        </div>
        <button type="button" id="add-feed" class="mt-4 inline-flex items-center gap-2 px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clip-rule="evenodd" /></svg>
            <span>添加 Feed</span>
        </button>
    </section>

    <div class="py-4">
        <button id="save-config" class="w-full md:w-auto inline-flex items-center justify-center gap-2 px-8 py-2.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors text-base font-semibold">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" /></svg>
            <span>保存配置</span>
        </button>
    </div>

    <div id="toast" class="hidden fixed top-15 left-1/2 -translate-x-1/2 text-white px-5 py-3 rounded-md shadow-lg text-sm font-medium">
        <span id="toast-message"></span>
    </div>
</div>
{% endblock %}

{% block scripts %}
<script>
document.addEventListener("DOMContentLoaded", () => {
    const webhooksTableBody = document.getElementById("webhooks-table");
    const feedsTable = document.getElementById("feeds-table");
    const loadingOverlay = document.getElementById("loading-overlay");

    // ===== Loading & Toast 工具函数 =====
    function showLoading() { loadingOverlay.classList.remove("hidden"); }
    function hideLoading() { loadingOverlay.classList.add("hidden"); }
    function showToast(text, type) {
        const msgBox = document.getElementById("toast");
        document.getElementById("toast-message").textContent = text;
        msgBox.classList.remove("bg-green-500", "bg-red-500", "bg-yellow-500", "bg-zinc-700");
        const typeClasses = {
            success: "bg-green-500",
            error: "bg-red-500",
            warning: "bg-yellow-500"
        };
        msgBox.classList.add(typeClasses[type] || "bg-zinc-700");
        msgBox.classList.remove("hidden");
        setTimeout(() => msgBox.classList.add("hidden"), 3000);
    }

    // ===== Switch Button 控制 =====
    const switchBtn = document.getElementById("web_enabled_switch");
    const knob = document.getElementById("web_enabled_knob");
    function setSwitchState(enabled) {
        switchBtn.dataset.enabled = enabled;
        if (enabled) {
            switchBtn.classList.remove("bg-zinc-200");
            switchBtn.classList.add("bg-amber-500");
            knob.classList.add("translate-x-5");
        } else {
            switchBtn.classList.remove("bg-amber-500");
            switchBtn.classList.add("bg-zinc-200");
            knob.classList.remove("translate-x-5");
        }
    }
    function getWebEnabled() { return switchBtn.dataset.enabled === "true"; }
    switchBtn.addEventListener("click", () => { setSwitchState(!getWebEnabled()); });

    // ===== 文本域工具函数 =====
    function arrToMultiline(arr) { return (arr || []).join("\n"); }
    function multilineToArr(text) { return (text || "").split("\n").map(s => s.trim()).filter(s => s.length > 0); }

    // ===== Webhook 表格渲染与交互 =====
    function renderWebhooks(webhooks) {
        webhooksTableBody.innerHTML = "";
        (webhooks || []).forEach((hook) => {
            const row = document.createElement("tr");
            row.className = "hover:bg-zinc-50";

            const isEnabled = hook.enabled;
            const switchBgClass = isEnabled ? 'bg-amber-500' : 'bg-zinc-200';
            const knobTranslateClass = isEnabled ? 'translate-x-5' : '';

            row.innerHTML = `
                <td class="px-3 py-2 align-middle">
                    <input data-field="name" value="${hook.name || ''}" class="w-full border border-zinc-200 rounded px-2 py-1 focus:ring-amber-500 focus:border-amber-500">
                </td>
                <td class="px-3 py-2 align-middle">
                    <input data-field="url" value="${hook.url || ''}" class="w-full border border-zinc-200 rounded px-2 py-1 focus:ring-amber-500 focus:border-amber-500">
                </td>
                <td class="px-3 py-2 align-middle">
                    <button type="button" data-field="enabled" data-enabled="${isEnabled}"
                        class="webhook-switch relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none ${switchBgClass}">
                        <span class="sr-only">启用 Webhook</span>
                        <span class="inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${knobTranslateClass}"></span>
                    </button>
                </td>
                <td class="px-3 py-2 text-center align-middle">
                    <button type="button" data-action="delete-webhook" class="text-red-500 hover:text-red-700 p-1" title="删除此 Webhook">
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" /></svg>
                    </button>
                </td>
            `;
            webhooksTableBody.appendChild(row);
        });
    }

    function collectWebhooks() {
        const hooks = [];
        webhooksTableBody.querySelectorAll("tr").forEach(row => {
            hooks.push({
                name: row.querySelector('[data-field="name"]').value.trim(),
                url: row.querySelector('[data-field="url"]').value.trim(),
                enabled: row.querySelector('[data-field="enabled"]').dataset.enabled === 'true'
            });
        });
        return hooks;
    }

    document.getElementById("add-webhook").addEventListener("click", () => {
        const currentHooks = collectWebhooks();
        renderWebhooks([...currentHooks, { name: "", url: "", enabled: true }]);
    });

    webhooksTableBody.addEventListener("click", e => {
        // 事件委托：处理开关按钮点击
        const switchButton = e.target.closest('.webhook-switch');
        if (switchButton) {
            const isEnabled = switchButton.dataset.enabled === 'true';
            const newEnabled = !isEnabled;
            const knob = switchButton.querySelector('span:last-child');

            switchButton.dataset.enabled = newEnabled;
            if (newEnabled) {
                switchButton.classList.remove('bg-zinc-200');
                switchButton.classList.add('bg-amber-500');
                knob.classList.add('translate-x-5');
            } else {
                switchButton.classList.remove('bg-amber-500');
                switchButton.classList.add('bg-zinc-200');
                knob.classList.remove('translate-x-5');
            }
        }

        // 事件委托：处理删除按钮点击
        const deleteButton = e.target.closest('button[data-action="delete-webhook"]');
        if (deleteButton) {
            deleteButton.closest("tr").remove();
        }
    });

    // ===== 渲染 Feeds =====
    function renderFeeds(feeds, downloaderStates) {
        feedsTable.innerHTML = "";
        (feeds || []).forEach((feed, index) => {
            const aria2Disabled = downloaderStates.aria2 ? "" : "disabled";
            const qbDisabled = downloaderStates.qbittorrent ? "" : "disabled";
            const transDisabled = downloaderStates.transmission ? "" : "disabled";

            const row1 = document.createElement("tr");
            row1.className = "hover:bg-zinc-50";
            row1.innerHTML = `
                <td class="px-3 py-2 align-top">
                    <input data-field="name" value="${feed.name || ''}" class="w-full border border-zinc-200 rounded px-2 py-1 focus:ring-amber-500 focus:border-amber-500">
                </td>
                <td class="px-3 py-2 align-top">
                    <input data-field="url" value="${feed.url || ''}" class="w-full border border-zinc-200 rounded px-2 py-1 focus:ring-amber-500 focus:border-amber-500">
                </td>
                <td class="px-3 py-2 align-top">
                    <select data-field="downloader" class="w-full border border-zinc-200 rounded px-2 py-2 focus:ring-amber-500 focus:border-amber-500">
                        <option value="aria2" ${feed.downloader === 'aria2' ? 'selected' : ''} ${aria2Disabled}>Aria2 ${aria2Disabled ? '(未配置)' : ''}</option>
                        <option value="qbittorrent" ${feed.downloader === 'qbittorrent' ? 'selected' : ''} ${qbDisabled}>qBittorrent ${qbDisabled ? '(未配置)' : ''}</option>
                        <option value="transmission" ${feed.downloader === 'transmission' ? 'selected' : ''} ${transDisabled}>Transmission ${transDisabled ? '(未配置)' : ''}</option>
                    </select>
                </td>
                <td class="px-3 py-2 text-center align-top">
                    <button type="button" class="text-red-500 hover:text-red-700 p-1" data-action="delete" title="删除此 Feed">
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" /></svg>
                    </button>
                </td>
            `;

            const row2 = document.createElement("tr");
            row2.className = index === feeds.length - 1 ? "" : "border-b-2 border-dashed border-zinc-100";
            row2.innerHTML = `
                <td colspan="4" class="p-3">
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label class="block text-xs text-zinc-500 mb-1">包含规则 (正则表达式, 每行一个)</label>
                            <textarea data-field="include" rows="3" class="w-full border border-zinc-200 rounded px-2 py-2 resize-y text-sm focus:ring-amber-500 focus:border-amber-500" placeholder="e.g., 1080p\n(chs|cht)">${arrToMultiline(feed.include)}</textarea>
                        </div>
                        <div>
                            <label class="block text-xs text-zinc-500 mb-1">排除规则 (正则表达式, 每行一个)</label>
                            <textarea data-field="exclude" rows="3" class="w-full border border-zinc-200 rounded px-2 py-2 resize-y text-sm focus:ring-amber-500 focus:border-amber-500" placeholder="e.g., 720p\n(eng|jpn)">${arrToMultiline(feed.exclude)}</textarea>
                        </div>
                    </div>
                </td>
            `;

            feedsTable.appendChild(row1);
            feedsTable.appendChild(row2);
        });
    }

    // ===== 添加 / 删除 Feed =====
    document.getElementById("add-feed").addEventListener("click", () => {
        const downloaderStates = {
            aria2: document.getElementById("aria2_rpc").value.trim() !== "",
            qbittorrent: document.getElementById("qb_host").value.trim() !== "",
            transmission: document.getElementById("trans_host").value.trim() !== ""
        };
        const currentFeeds = collectFeeds() || [];
        renderFeeds([...currentFeeds, {name:"", url:"", include:[], exclude:[], downloader:"aria2"}], downloaderStates);
    });

    feedsTable.addEventListener("click", e => {
        const button = e.target.closest('button');
        if (button && button.dataset.action === "delete") {
            const tr = button.closest("tr");
            const feedName = tr.querySelector('[data-field=name]').value || "这个未命名的";
            if (confirm(`确定要删除名为 "${feedName}" 的 RSS 源吗？`)) {
                const next = tr.nextElementSibling;
                tr.remove();
                if (next && next.querySelector("textarea")) { next.remove(); }
            }
        }
    });

    // ===== 收集 Feeds 数据 =====
    function collectFeeds() {
        const feeds = [];
        const names = new Set();
        let duplicateName = null;
        const rows = feedsTable.querySelectorAll("tr");
        for (let i = 0; i < rows.length; i += 2) {
            const row1 = rows[i];
            const row2 = rows[i + 1];
            if (!row1 || !row2) continue;
            const feed = {};
            row1.querySelectorAll("[data-field]").forEach(input => {
                feed[input.dataset.field] = input.value.trim();
            });
            row2.querySelectorAll("[data-field]").forEach(input => {
                const field = input.dataset.field;
                feed[field] = multilineToArr(input.value);
            });
            const nameKey = (feed.name || "").toLowerCase();
            if (nameKey && names.has(nameKey)) {
                duplicateName = feed.name;
            } else if (nameKey) {
                names.add(nameKey);
            }
            feeds.push(feed);
        }
        if (duplicateName) {
            showToast(`存在重复的 RSS 名称 "${duplicateName}"`, 'error');
            return null;
        }
        return feeds;
    }

    // ===== 保存配置 =====
    document.getElementById("save-config").addEventListener("click", () => {
        const allWebhooks = collectWebhooks();
        const validWebhooks = allWebhooks.filter(hook => hook.name && hook.url);

        const feeds = collectFeeds();
        if (feeds === null) return;
        showLoading();

        try {
            let portVal = parseInt(document.getElementById("web_port").value, 10);
            portVal = isNaN(portVal) ? 8000 : portVal;
            let intervalVal = parseInt(document.getElementById("interval_hours").value, 10);
            intervalVal = isNaN(intervalVal) ? 6 : intervalVal;
            const payload = {
                log: { level: document.getElementById("log_level").value },
                web: { enabled: getWebEnabled(), host: document.getElementById("web_host").value.trim(), port: portVal, interval_hours: intervalVal },
                aria2: { rpc: document.getElementById("aria2_rpc").value.trim() || null, secret: document.getElementById("aria2_secret").value.trim() || null, dir: document.getElementById("aria2_dir").value.trim() || null },
                qbittorrent: { host: document.getElementById("qb_host").value.trim() || null, username: document.getElementById("qb_username").value.trim() || null, password: document.getElementById("qb_password").value.trim() || null },
                transmission: { host: document.getElementById("trans_host").value.trim() || null, username: document.getElementById("trans_username").value.trim() || null, password: document.getElementById("trans_password").value.trim() || null },
                webhooks: validWebhooks,
                feeds
            };
            fetch("/config", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) })
            .then(res => res.json().then(data => ({ ok: res.ok, body: data })))
            .then(({ ok, body }) => {
                if (ok) { showToast("配置已保存成功！", "success"); }
                else { throw body; }
            })
            .catch(errorBody => {
                let errorMessage = "保存失败，请检查输入。";
                if (errorBody && errorBody.detail && Array.isArray(errorBody.detail)) {
                    const firstError = errorBody.detail[0];
                    const fieldPath = firstError.loc.slice(1).join(" -> ");
                    const message = firstError.msg;
                    errorMessage = `字段 '${fieldPath}' 出错: ${message}`;
                    console.error(firstError);
                } else if (errorBody && errorBody.message) {
                    errorMessage = errorBody.message;
                }
                showToast(errorMessage, "error");
            })
            .finally(() => { hideLoading(); });
        } catch (err) {
            showToast(err.message, "error");
            hideLoading();
        }
    });

    // ===== 测试连接功能 =====
    async function testConnection(type) {
        const url = `/test-downloader/${type}`;
        let payload;

        if (type === 'aria2') {
            payload = {
                rpc: document.getElementById("aria2_rpc").value.trim() || null,
                secret: document.getElementById("aria2_secret").value.trim() || null
            };
        } else if (type === 'qbittorrent') {
            payload = {
                host: document.getElementById("qb_host").value.trim() || null,
                username: document.getElementById("qb_username").value.trim() || null,
                password: document.getElementById("qb_password").value
            };
        } else if (type === 'transmission') {
            payload = {
                host: document.getElementById("trans_host").value.trim() || null,
                username: document.getElementById("trans_username").value.trim() || null,
                password: document.getElementById("trans_password").value
            };
        } else {
            showToast(`未知的下载器类型: ${type}`, 'error');
            return;
        }

        showLoading();
        try {
            const response = await fetch(url, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });
            const data = await response.json();
            if (response.ok) {
                showToast(`连接成功! 版本: ${data.version}`, "success");
            } else {
                throw new Error(data.detail || "连接失败");
            }
        } catch (err) {
            showToast(`连接失败: ${err.message}`, 'error');
        } finally {
            hideLoading();
        }
    }

    document.getElementById("test_aria2").addEventListener("click", () => testConnection('aria2'));
    document.getElementById("test_qb").addEventListener("click", () => testConnection('qbittorrent'));
    document.getElementById("test_trans").addEventListener("click", () => testConnection('transmission'));

    // ===== 页面加载时获取配置 =====
    showLoading();
    fetch("/config")
        .then(res => res.json())
        .then(cfg => {
            if (cfg.log && cfg.log.level) { document.getElementById("log_level").value = cfg.log.level; }
            setSwitchState(cfg.web.enabled);
            document.getElementById("web_host").value = cfg.web.host || "127.0.0.1";
            document.getElementById("web_port").value = cfg.web.port || 8000;
            document.getElementById("interval_hours").value = cfg.web.interval_hours || 6;
            document.getElementById("aria2_rpc").value = cfg.aria2?.rpc || "";
            document.getElementById("aria2_secret").value = cfg.aria2?.secret || "";
            document.getElementById("aria2_dir").value = cfg.aria2?.dir || "";
            document.getElementById("qb_host").value = cfg.qbittorrent?.host || "";
            document.getElementById("qb_username").value = cfg.qbittorrent?.username || "";
            document.getElementById("qb_password").value = cfg.qbittorrent?.password || "";
            document.getElementById("trans_host").value = cfg.transmission?.host || "";
            document.getElementById("trans_username").value = cfg.transmission?.username || "";
            document.getElementById("trans_password").value = cfg.transmission?.password || "";
            renderWebhooks(cfg.webhooks);

            const downloaderStates = {
                aria2: !!cfg.aria2?.rpc,
                qbittorrent: !!cfg.qbittorrent?.host,
                transmission: !!cfg.transmission?.host
            };
            renderFeeds(cfg.feeds || [], downloaderStates);
        })
        .catch(err => { showToast("加载配置失败: " + err.message, "error"); })
        .finally(() => { hideLoading(); });
});
</script>
{% endblock %}
