<?php
/**
 * 对接节点管理 - 对接方后台
 */
$title = '对接节点管理';
include __DIR__ . '/head.php';

$biz = isset($_GET['biz']) ? trim($_GET['biz']) : 'all';
if(!in_array($biz, ['all','cloud','dg'], true)) $biz = 'all';
?>
<style>
.status-toggle { cursor: pointer; }
.status-toggle:hover { opacity: 0.8; }
</style>

<div class="p-4 md:p-6 space-y-4 md:space-y-6">
    <!-- 说明区域 -->
    <div class="bg-blue-50 border border-blue-200 rounded-xl p-4">
        <p class="text-sm text-blue-700">
            <i class="fas fa-info-circle mr-2"></i>
            <b>说明：</b>对接节点用于连接其他站点的登录节点。添加被对接方提供的凭证后，可同步获取节点信息。
            <br><span class="text-blue-600">框架类型和登录协议同步后不可修改，登录API地址不保存（实时获取）。全站/分类授权会自动同步分类。</span>
        </p>
    </div>

    <!-- 对接节点列表 -->
    <div class="bg-white rounded-xl shadow-sm border border-gray-200">
        <div class="p-4 md:p-6 border-b border-gray-200">
            <h2 class="text-lg font-semibold text-gray-800">对接节点列表</h2>
        </div>
        <div class="p-4 md:p-6">
            <!-- 操作按钮区 -->
            <div class="mb-4 flex flex-wrap items-center gap-3">
                <button onclick="showAddModal()" class="px-6 py-2 bg-green-600 hover:bg-green-700 text-white font-medium rounded-lg transition">
                    <i class="fas fa-plus mr-2"></i>添加对接凭证
                </button>
                <button onclick="syncAllNodes()" class="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition">
                    <i class="fas fa-sync mr-2"></i>同步所有对接节点
                </button>
            </div>

            <!-- 批量设置本地分类 -->
            <div class="mb-4 flex flex-wrap items-center gap-3">
                <div class="flex items-center gap-2">
                    <span class="text-xs text-gray-500">批量设置本地分类ID</span>
                    <input type="number" id="batch_local_class_id" min="0" value="0" class="w-28 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500" />
                    <button onclick="batchSetLocalClass()" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg transition text-sm">
                        批量设置
                    </button>
                </div>
                <span class="text-sm text-gray-600">已选 <span id="batch_selected_count" class="font-medium">0</span> 个节点</span>
                <span class="text-xs text-gray-400">请仅选择同一业务类型的节点；填 0 表示“自动同步分类”。</span>
            </div>
            
            <!-- 筛选区 -->
            <div class="mb-4 flex items-center gap-2">
                <span class="text-xs text-gray-500">业务</span>
                <select class="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent" onchange="location.href='node_link.php?biz='+this.value">
                    <option value="all" <?php echo $biz === 'all' ? 'selected' : '' ?>>全部</option>
                    <option value="cloud" <?php echo $biz === 'cloud' ? 'selected' : '' ?>>云端</option>
                    <option value="dg" <?php echo $biz === 'dg' ? 'selected' : '' ?>>代挂</option>
                </select>
            </div>
            
            <!-- 列表 -->
            <div class="overflow-x-auto">
                <table class="w-full min-w-[1100px]">
                    <thead class="bg-gray-50">
                        <tr>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap" style="width:60px;">选择</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap" style="width:60px;">排序</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">ID</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">节点名称</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">业务类型</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">框架类型</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">本地分类ID</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">接口密码</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">上限人数</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">在线人数</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">显示人数</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">接口状态</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">操作</th>
                        </tr>
                    </thead>
                    <tbody id="nodeList" class="divide-y divide-gray-200">
                        <tr><td colspan="13" class="px-4 py-8 text-center text-gray-400">加载中...</td></tr>
                    </tbody>
                </table>
            </div>
            
            <!-- 底部 -->
            <div class="mt-4 flex items-center justify-between">
                <p class="text-sm text-gray-600">共有 <span id="total" class="font-medium">0</span> 条对接节点</p>
                <button type="button" class="px-6 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 font-medium rounded-lg transition" onclick="if(document.referrer){history.back()}else{location.href='index.php'}">
                    <i class="fas fa-arrow-left mr-2"></i>返回
                </button>
            </div>
        </div>
    </div>
    
    <!-- 凭证列表区域 -->
    <div class="bg-white rounded-xl shadow-sm border border-gray-200">
        <div class="p-4 md:p-6 border-b border-gray-200 flex items-center justify-between">
            <h2 class="text-lg font-semibold text-gray-800">对接凭证列表</h2>
            <button onclick="syncAllExpire()" class="px-3 py-1.5 bg-orange-500 hover:bg-orange-600 text-white text-sm rounded-lg transition">
                <i class="fas fa-sync-alt mr-1"></i>一键同步授权
            </button>
        </div>
        <div class="p-4 md:p-6">
            <div class="overflow-x-auto">
                <table class="w-full min-w-[800px]">
                    <thead class="bg-gray-50">
                        <tr>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">凭证ID</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">API地址</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">节点名称</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">业务</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">到期时间</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">节点数</th>
                            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">操作</th>
                        </tr>
                    </thead>
                    <tbody id="credentialList" class="divide-y divide-gray-200">
                        <tr><td colspan="7" class="px-4 py-8 text-center text-gray-400">加载中...</td></tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

<!-- 添加凭证弹窗 -->
<div id="addModal" class="fixed inset-0 bg-black/50 hidden items-center justify-center z-50 p-4">
    <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
        <div class="p-4 border-b border-gray-200 flex items-center justify-between sticky top-0 bg-white">
            <h3 class="text-lg font-semibold">添加对接凭证</h3>
            <button type="button" class="text-gray-400 hover:text-gray-600" onclick="closeAddModal()">
                <i class="fas fa-times text-xl"></i>
            </button>
        </div>
        <form id="addForm" onsubmit="addCredential();return false;" class="p-4 space-y-4">
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">被对接方API地址 <span class="text-red-500">*</span></label>
                <input type="url" name="api_url" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="https://example.com/api/node.php">
            </div>
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">App ID <span class="text-red-500">*</span></label>
                <input type="text" name="app_id" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="被对接方提供的凭证ID">
            </div>
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">App Secret <span class="text-red-500">*</span></label>
                <input type="text" name="app_secret" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="被对接方提供的通信密钥">
            </div>
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">业务类型（拉取节点归属）</label>
                <select name="biz" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                    <option value="both">全部：按被对接站节点业务（云端/代挂）分别对应导入</option>
                    <option value="cloud">云端</option>
                    <option value="dg">代挂</option>
                </select>
            </div>
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">本地分类ID（需要自己填写）</label>
                <input type="number" name="local_class_id" id="add_local_class_id" min="0" value="0" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" />
                <p class="text-xs text-gray-400 mt-1">填 0 表示“自动同步分类”；填其他数字必须属于当前业务类型（云端/代挂）的分类ID。</p>
            </div>
            <div class="flex items-center gap-2">
                <input type="checkbox" name="auto_sync" id="auto_sync" value="1" checked>
                <label for="auto_sync" class="text-sm text-gray-700">添加后自动拉取节点</label>
            </div>
            <div class="flex justify-end gap-3 pt-4">
                <button type="button" onclick="closeAddModal()" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg">取消</button>
                <button type="submit" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg">添加</button>
            </div>
        </form>
    </div>
</div>

<!-- 编辑节点弹窗 -->
<div id="editModal" class="fixed inset-0 bg-black/50 hidden items-center justify-center z-50 p-4">
    <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
        <div class="p-4 border-b border-gray-200 flex items-center justify-between sticky top-0 bg-white">
            <h3 class="text-lg font-semibold">编辑对接节点</h3>
            <button type="button" class="text-gray-400 hover:text-gray-600" onclick="closeEditModal()">
                <i class="fas fa-times text-xl"></i>
            </button>
        </div>
        <form id="editForm" onsubmit="saveNode();return false;" class="p-4 space-y-6">
            <input type="hidden" name="id" id="edit_id">
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">节点名称</label>
                <div class="md:col-span-3">
                    <input type="text" name="custom_name" id="edit_name" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="使用被对接方节点名称">
                    <p class="mt-1 text-xs text-gray-400">留空则使用被对接方节点名称</p>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">框架类型</label>
                <div class="md:col-span-3">
                    <div class="p-2 bg-gray-50 rounded-lg">
                        <span id="edit_type" class="text-sm text-gray-700">-</span>
                        <span class="text-xs text-gray-400 ml-2">(同步获取，不可修改)</span>
                    </div>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">本地分类</label>
                <div class="md:col-span-3">
                    <input type="number" name="local_class_id" id="edit_class" min="0" value="0" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" />
                    <p class="mt-1 text-xs text-gray-400">请手填本地分类ID（必须属于该节点业务类型的分类ID）</p>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">显示人数</label>
                <div class="md:col-span-3">
                    <select name="show_online_census" id="edit_show_online_census" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="1">开启</option>
                        <option value="0">关闭</option>
                    </select>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">节点异常提示</label>
                <div class="md:col-span-3">
                    <select name="api_error_check" id="edit_api_error_check" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="1">开启</option>
                        <option value="0">关闭</option>
                    </select>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">上限人数</label>
                <div class="md:col-span-3">
                    <input type="number" name="max" id="edit_max" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" value="0">
                    <p class="mt-1 text-xs text-gray-400">0表示不限制</p>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">接口密码</label>
                <div class="md:col-span-3">
                    <input type="text" name="apipwd" id="edit_apipwd" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="0=免费，空=收费，其他=密码">
                    <p class="mt-1 text-xs text-gray-400">对接方自行设置，不同步</p>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-start">
                <label class="text-sm font-medium text-gray-700 pt-2">接口公告</label>
                <div class="md:col-span-3">
                    <textarea name="msg" id="edit_msg" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="留空使用被对接方公告"></textarea>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">公告提示位置</label>
                <div class="md:col-span-3">
                    <select name="msg_type" id="edit_msg_type" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="0">默认_公告栏</option>
                        <option value="1">弹窗提示</option>
                        <option value="5">弹窗提示_5秒后可关闭</option>
                        <option value="10">弹窗提示_10秒后可关闭</option>
                    </select>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
                <label class="text-sm font-medium text-gray-700">状态</label>
                <div class="md:col-span-3">
                    <select name="status" id="edit_status" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="1">启用</option>
                        <option value="0">禁用</option>
                    </select>
                </div>
            </div>
            
            <div class="flex justify-end gap-3 pt-4">
                <button type="button" onclick="closeEditModal()" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg">取消</button>
                <button type="submit" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg">保存</button>
            </div>
        </form>
    </div>
</div>

<script>
var currentBiz = '<?php echo $biz ?>';
// 本页面对本地分类不做下拉拉取，local_class_id 需要管理员手填（并由后端校验 cloud/dg 业务类型）

$(document).ready(function() {
    loadCredentialList();
    loadNodeList();
    $(document).on('click', '.js-cred-sync-expire', function() {
        var tr = $(this).closest('tr');
        syncExpire(tr.attr('data-cred-app-id'), tr.attr('data-cred-biz'), tr.attr('data-cred-api-url'));
    });
    $(document).on('click', '.js-cred-pull', function() {
        var tr = $(this).closest('tr');
        pullNodes(tr.attr('data-cred-app-id'), tr.attr('data-cred-biz'), tr.attr('data-cred-api-url'));
    });
    $(document).on('click', '.js-cred-delete', function() {
        var tr = $(this).closest('tr');
        deleteCredential(tr.attr('data-cred-app-id'), tr.attr('data-cred-biz'), tr.attr('data-cred-api-url'));
    });
});

function loadCredentialList() {
    $.get('ajax.php?act=node_link_credential_list&biz=' + currentBiz, function(res) {
        if (res.code == 0) {
            renderCredentialList(res.data);
        } else {
            $('#credentialList').html('<tr><td colspan="6" class="px-4 py-8 text-center text-gray-400">暂无数据</td></tr>');
        }
    }, 'json');
}

function renderCredentialList(data) {
    if (!data || data.length == 0) {
        $('#credentialList').html('<tr><td colspan="7" class="px-4 py-8 text-center text-gray-400">暂无数据，请添加对接凭证</td></tr>');
        return;
    }
    
    var bizLabels = {'cloud': '云端', 'dg': '代挂', 'all': '旧·全部(请删后重拉)', 'both': '—'};
    var html = '';
    
    for (var i = 0; i < data.length; i++) {
        var item = data[i];
        var expireLabel = item.expire_time ? (new Date(item.expire_time) < new Date() ? '<span class="text-red-600">已过期</span>' : item.expire_time) : '<span class="text-gray-400">永久</span>';
        var nodeNames = item.node_names || '-';
        // 如果节点名称太长，截断显示
        if (nodeNames && nodeNames.length > 50) {
            nodeNames = nodeNames.substring(0, 50) + '...';
        }
        var esc = function(s) {
            return String(s == null ? '' : s).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;');
        };
        html += '<tr data-cred-app-id="' + esc(item.app_id) + '" data-cred-api-url="' + esc(item.api_url) + '" data-cred-biz="' + esc(item.biz) + '">' +
            '<td class="px-4 py-3 text-sm font-mono">' + item.app_id + '</td>' +
            '<td class="px-4 py-3 text-sm truncate max-w-[200px]" title="' + esc(item.api_url) + '">' + item.api_url + '</td>' +
            '<td class="px-4 py-3 text-sm truncate max-w-[150px]" title="' + esc(item.node_names || '') + '">' + nodeNames + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (bizLabels[item.biz] || item.biz) + '</td>' +
            '<td class="px-4 py-3 text-sm">' + expireLabel + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.node_count || 0) + '</td>' +
            '<td class="px-4 py-3 text-sm">' +
                '<button type="button" class="js-cred-sync-expire text-orange-600 hover:text-orange-800 mr-2"><i class="fas fa-clock"></i>同步授权</button>' +
                '<button type="button" class="js-cred-pull text-green-600 hover:text-green-800 mr-2"><i class="fas fa-download"></i>拉取</button>' +
                '<button type="button" class="js-cred-delete text-red-600 hover:text-red-800"><i class="fas fa-trash"></i>删除</button>' +
            '</td>' +
        '</tr>';
    }
    
    $('#credentialList').html(html);
}

function loadNodeList() {
    $.get('ajax.php?act=node_link_list&biz=' + currentBiz, function(res) {
        if (res.code == 0) {
            renderNodeList(res.data);
        } else {
            selectedNodeBizMap = {};
            $('#batch_selected_count').text('0');
            $('#nodeList').html('<tr><td colspan="13" class="px-4 py-8 text-center text-gray-400">暂无对接节点</td></tr>');
        }
    }, 'json');
}

function renderNodeList(data) {
    var bizLabels = {'cloud': '云端', 'dg': '代挂', 'all': '旧·全部(请删后重拉)', 'both': '—'};
    if (!data || data.length == 0) {
        selectedNodeBizMap = {};
        $('#batch_selected_count').text('0');
        $('#nodeList').html('<tr><td colspan="13" class="px-4 py-8 text-center text-gray-400">暂无对接节点，请先添加凭证并拉取节点</td></tr>');
        $('#total').text('0');
        return;
    }

    var html = '';
    var totalCount = data.length;

    for (var i = 0; i < data.length; i++) {
        var item = data[i];
        var statusHtml = item.status == 1
            ? '<span class="status-toggle px-2 py-1 text-xs rounded-full bg-green-100 text-green-700" onclick="toggleStatus(' + item.id + ', 0)">启用</span>'
            : '<span class="status-toggle px-2 py-1 text-xs rounded-full bg-red-100 text-red-700" onclick="toggleStatus(' + item.id + ', 1)">禁用</span>';
        var bizLabel = bizLabels[item.biz] || (item.biz || '-');

        html += '<tr>' +
            '<td class="px-4 py-3 text-sm">' +
                '<input type="checkbox" class="js-node-select" data-id="' + item.id + '" data-biz="' + (item.biz || '') + '" />' +
            '</td>' +
            '<td class="px-4 py-3 text-sm text-gray-500 whitespace-nowrap"><div class="flex items-center gap-1"><a class="text-blue-600 hover:text-blue-800 cursor-pointer" onclick="nodeLinkSort(' + item.id + ',' + item.sort + ')"><i class="fa fa-sort"></i></a><span>' + item.sort + '</span></div></td>' +
            '<td class="px-4 py-3 text-sm">' + item.id + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.custom_name || item.remote_class_name || '未命名') + '</td>' +
            '<td class="px-4 py-3 text-sm">' + bizLabel + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.sync_type || '-') + '</td>' +
            '<td class="px-4 py-3 text-sm">' + ((item.local_class_id && String(item.local_class_id) !== '0') ? item.local_class_id : '未分类') + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.apipwd === '0' ? '免费' : (item.apipwd ? '密码验证' : '收费')) + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.max || 0) + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.online_count || 0) + '</td>' +
            '<td class="px-4 py-3 text-sm">' + (item.show_online_census == 1 ? '开启' : '关闭') + '</td>' +
            '<td class="px-4 py-3 text-sm">' + statusHtml + '</td>' +
            '<td class="px-4 py-3 text-sm">' +
                '<button onclick="syncNode(' + item.id + ')" class="text-green-600 hover:text-green-800 mr-2"><i class="fas fa-sync"></i>同步</button>' +
                '<button onclick="editNode(' + item.id + ')" class="text-blue-600 hover:text-blue-800 mr-2"><i class="fas fa-edit"></i>编辑</button>' +
                '<button onclick="deleteNode(' + item.id + ')" class="text-red-600 hover:text-red-800"><i class="fas fa-trash"></i>删除</button>' +
            '</td>' +
        '</tr>';
    }

    $('#nodeList').html(html);
    selectedNodeBizMap = {};
    $('#batch_selected_count').text('0');
    $('#total').text(totalCount);
}

// ---------------- 批量分类设置 ----------------
var selectedNodeBizMap = {}; // { [id:string]: biz }

function syncBatchSelectedCount() {
    $('#batch_selected_count').text(String(Object.keys(selectedNodeBizMap).length));
}

$(document).on('change', '.js-node-select', function() {
    var id = String($(this).data('id'));
    var biz = $(this).data('biz') || 'cloud';
    if (this.checked) {
        selectedNodeBizMap[id] = biz;
    } else {
        delete selectedNodeBizMap[id];
    }
    syncBatchSelectedCount();
});

function batchSetLocalClass() {
    var ids = Object.keys(selectedNodeBizMap);
    if (ids.length === 0) {
        showToast('请先选择节点', 'warning');
        return;
    }

    var bizSet = new Set(Object.values(selectedNodeBizMap));
    if (bizSet.size > 1) {
        showToast('请仅选择同一业务类型的节点（云端/代挂）', 'warning');
        return;
    }

    var localClassIdRaw = $('#batch_local_class_id').val();
    var localClassId = parseInt(localClassIdRaw, 10);
    if (isNaN(localClassId) || localClassId < 0) {
        showToast('本地分类ID不合法', 'error');
        return;
    }

    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_batch_set_local_class',
        type: 'POST',
        data: { ids: ids.join(','), local_class_id: localClassId },
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast(res.msg || '批量设置成功', 'success');
                selectedNodeBizMap = {};
                $('#batch_selected_count').text('0');
                loadNodeList();
            } else {
                showToast(res.msg || '操作失败', 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function nodeLinkSort(id, sort) {
    var text = prompt('排序操作\n当前序号：' + sort + '\n序号越小越靠前\n请输入新序号：');
    if(text !== null) {
        showToast('正在操作中...', 'info');
        $.post('ajax.php?act=node_link_sort', {id:id,sort:text}, function(d) {
            if(d.code == 0){
                showToast(d.msg, 'success');
                loadNodeList();
            }else{
                showToast(d.msg, 'error');
            }
        },'json');
    }
}

function toggleStatus(id, newStatus) {
    $.ajax({
        url: 'ajax.php?act=node_link_toggle_status',
        type: 'POST',
        data: { id: id, status: newStatus },
        dataType: 'json',
        success: function(res) {
            if (res.code == 0) {
                showToast(res.msg, 'success');
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            showToast('请求失败', 'error');
        }
    });
}

function showAddModal() {
    $('#addModal').removeClass('hidden').addClass('flex');
}

function closeAddModal() {
    $('#addModal').removeClass('flex').addClass('hidden');
    $('#addForm')[0].reset();
}

function addCredential() {
    showLoading();
    var formData = $('#addForm').serialize();
    // 先获取本地分类ID，避免弹窗关闭后表单重置
    var selectedLocalClassId = $('#add_local_class_id').val();
    $.ajax({
        url: 'ajax.php?act=node_link_add_credential',
        type: 'POST',
        data: formData,
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast(res.msg, 'success');
                if ($('#auto_sync').is(':checked') && res.data) {
                    // 传递完整的凭证信息和本地分类ID去拉取节点
                    var credData = res.data;
                    credData.local_class_id = selectedLocalClassId;
                    closeAddModal();
                    pullNodesWithCred(credData);
                } else {
                    closeAddModal();
                    loadCredentialList();
                }
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function pullNodesWithCred(credData) {
    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_pull',
        type: 'POST',
        data: credData,
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast('成功拉取 ' + (res.data && res.data.count != null ? res.data.count : 0) + ' 个节点', 'success');
                loadCredentialList();
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function pullNodes(appId, biz, apiUrl) {
    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_pull',
        type: 'POST',
        data: { app_id: appId, biz: biz || '', api_url: apiUrl || '' },
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast('成功拉取 ' + res.data.count + ' 个节点', 'success');
                loadCredentialList();
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function syncExpire(appId, biz, apiUrl) {
    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_sync_expire',
        type: 'POST',
        data: { app_id: appId, biz: biz || '', api_url: apiUrl || '' },
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast('同步授权时长成功', 'success');
                loadCredentialList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function syncAllExpire() {
    if (!confirm('确定要同步所有凭证的授权时长吗？')) return;
    
    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_sync_expire',
        type: 'POST',
        data: { app_id: '' },
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast('成功同步 ' + res.data.count + ' 个节点的授权时长', 'success');
                loadCredentialList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function deleteCredential(appId, biz, apiUrl) {
    if (!confirm('确定要删除此凭证吗？关联的对接节点也将被删除。')) return;
    
    $.ajax({
        url: 'ajax.php?act=node_link_delete_credential',
        type: 'POST',
        data: { app_id: appId, biz: biz || '', api_url: apiUrl || '' },
        dataType: 'json',
        success: function(res) {
            if (res.code == 0) {
                showToast(res.msg, 'success');
                loadCredentialList();
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            showToast('请求失败', 'error');
        }
    });
}

function editNode(id) {
    $.get('ajax.php?act=node_link_get&id=' + id, function(res) {
        if (res.code == 0) {
            var item = res.data;
            $('#edit_id').val(item.id);
            $('#edit_type').text(item.sync_type || '未同步');
            $('#edit_name').val(item.custom_name || '');
            $('#edit_class').val(item.local_class_id || 0);
            $('#edit_show_online_census').val(item.show_online_census || 1);
            $('#edit_api_error_check').val(item.api_error_check || 1);
            $('#edit_max').val(item.max || 0);
            $('#edit_apipwd').val(item.apipwd || '');
            $('#edit_msg').val(item.msg || '');
            $('#edit_msg_type').val(item.msg_type || 0);
            $('#edit_status').val(item.status);
            $('#editModal').removeClass('hidden').addClass('flex');
        } else {
            showToast(res.msg, 'error');
        }
    }, 'json');
}

function closeEditModal() {
    $('#editModal').removeClass('flex').addClass('hidden');
}

function saveNode() {
    $.ajax({
        url: 'ajax.php?act=node_link_save',
        type: 'POST',
        data: $('#editForm').serialize(),
        dataType: 'json',
        success: function(res) {
            if (res.code == 0) {
                showToast(res.msg, 'success');
                closeEditModal();
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            showToast('请求失败', 'error');
        }
    });
}

function syncNode(id) {
    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_sync',
        type: 'POST',
        data: { id: id },
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast(res.msg, 'success');
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function syncAllNodes() {
    if (!confirm('确定要同步所有对接节点吗？')) return;
    
    showLoading();
    $.ajax({
        url: 'ajax.php?act=node_link_sync_all',
        type: 'POST',
        dataType: 'json',
        success: function(res) {
            hideLoading();
            if (res.code == 0) {
                showToast('成功同步 ' + res.data.count + ' 个节点', 'success');
                loadNodeList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            hideLoading();
            showToast('请求失败', 'error');
        }
    });
}

function deleteNode(id) {
    if (!confirm('确定要删除此对接节点吗？')) return;
    
    $.ajax({
        url: 'ajax.php?act=node_link_delete',
        type: 'POST',
        data: { id: id },
        dataType: 'json',
        success: function(res) {
            if (res.code == 0) {
                showToast(res.msg, 'success');
                loadNodeList();
                loadCredentialList();
            } else {
                showToast(res.msg, 'error');
            }
        },
        error: function() {
            showToast('请求失败', 'error');
        }
    });
}
</script>

<?php include 'foot.php'; ?>
