<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ACP 身份管理</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        ::-webkit-scrollbar { width: 6px; height: 6px; }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 3px; }
        ::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.25); }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: linear-gradient(135deg, #f0f4ff 0%, #e8edf5 100%); min-height: 100vh; display: flex; justify-content: center; align-items: flex-start; padding: 40px 20px; }
        .container { background: white; padding: 0; border-radius: 16px; box-shadow: 0 8px 32px rgba(0,0,0,0.08); max-width: 560px; width: 100%; overflow: hidden; }
        .page-header { background: linear-gradient(135deg, #2563eb 0%, #1e40af 100%); padding: 28px 32px 22px; color: white; text-align: center; }
        .page-header h1 { font-size: 20px; font-weight: 600; margin-bottom: 12px; letter-spacing: 0.5px; }
        .nav-links { display: flex; justify-content: center; gap: 8px; }
        .nav-links a { color: rgba(255,255,255,0.85); text-decoration: none; font-size: 12px; padding: 4px 12px; border-radius: 20px; border: 1px solid rgba(255,255,255,0.25); transition: all 0.2s; }
        .nav-links a:hover { background: rgba(255,255,255,0.15); color: #fff; border-color: rgba(255,255,255,0.5); }
        .page-body { padding: 24px 32px 32px; }
        .hint { text-align: center; color: #9ca3af; font-size: 13px; margin-bottom: 20px; }
        .create-section { margin-bottom: 24px; display: flex; flex-direction: column; gap: 10px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; }
        .create-section .aid-input-row { display: flex; gap: 8px; align-items: center; }
        .create-section .aid-input-row input { flex: 1; padding: 10px 14px; border: 1px solid #e2e8f0; border-radius: 8px; font-size: 14px; min-width: 0; background: #fff; transition: border-color 0.2s, box-shadow 0.2s; }
        .create-section .aid-input-row input:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
        .create-section .aid-input-row .dot-separator { color: #9ca3af; font-size: 16px; flex-shrink: 0; }
        .create-section .aid-input-row select { padding: 10px 30px 10px 14px; border: 1px solid #e2e8f0; border-radius: 8px; font-size: 14px; background: #fff; flex-shrink: 0; cursor: pointer; appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23999%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"); background-repeat: no-repeat; background-position: right 10px top 50%; background-size: 10px auto; transition: border-color 0.2s, box-shadow 0.2s; }
        .create-section .aid-input-row select:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
        .create-section .extra-fields { display: flex; gap: 8px; }
        .create-section .extra-fields input { flex: 1; padding: 10px 14px; border: 1px solid #e2e8f0; border-radius: 8px; font-size: 14px; min-width: 0; background: #fff; transition: border-color 0.2s, box-shadow 0.2s; }
        .create-section .extra-fields input:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
        .btn { display: block; width: 100%; padding: 11px; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; }
        .btn:active { transform: scale(0.98); }
        .btn-primary { background: linear-gradient(135deg, #2563eb, #1d4ed8); color: white; }
        .btn-primary:hover { background: linear-gradient(135deg, #1d4ed8, #1e40af); box-shadow: 0 2px 8px rgba(37,99,235,0.3); }
        .btn-sm { display: inline-block; width: auto; padding: 6px 14px; font-size: 13px; border-radius: 6px; }
        .btn-success { background: #10b981; color: white; }
        .btn-success:hover { background: #059669; }
        .btn-danger { background: #ef4444; color: white; }
        .btn-danger:hover { background: #dc2626; }
        .btn-outline { background: white; color: #2563eb; border: 1px solid #2563eb; }
        .btn-outline:hover { background: #eff6ff; }
        .btn:disabled { background: #d1d5db; cursor: not-allowed; border-color: #d1d5db; color: #fff; transform: none; }
        .aid-list { margin-bottom: 24px; }
        .aid-card { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 16px; margin-bottom: 10px; transition: all 0.2s; display: flex; align-items: stretch; gap: 12px; }
        .aid-card:hover { border-color: #93c5fd; box-shadow: 0 4px 12px rgba(37,99,235,0.08); transform: translateY(-1px); }
        .aid-card-left { flex: 1; min-width: 0; }
        .aid-card-right { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; justify-content: center; }
        .aid-card-header { margin-bottom: 10px; }
        .aid-name { font-family: 'SF Mono', 'Fira Code', monospace; font-size: 13px; color: #1f2937; word-break: break-all; }
        .copy-btn { background: none; border: none; color: #9ca3af; cursor: pointer; font-size: 12px; padding: 2px 6px; transition: color 0.2s; }
        .copy-btn:hover { color: #2563eb; }
        .aid-card-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
        .badge { display: inline-block; padding: 3px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; }
        .badge-success { background: #d1fae5; color: #065f46; }
        .badge-warning { background: #fef3c7; color: #92400e; }
        .badge-danger { background: #fee2e2; color: #991b1b; }
        .badge-info { background: #dbeafe; color: #1e40af; }
        .aid-card-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
        .status { position: fixed; top: 20px; left: 50%; transform: translate(-50%, -10px); padding: 12px 24px; border-radius: 10px; font-size: 14px; opacity: 0; visibility: hidden; z-index: 1000; box-shadow: 0 4px 16px rgba(0,0,0,0.1); transition: all 0.3s cubic-bezier(0.16,1,0.3,1); }
        .status.success { opacity: 1; visibility: visible; transform: translate(-50%, 0); background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
        .status.error { opacity: 1; visibility: visible; transform: translate(-50%, 0); background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
        @media (max-width: 480px) { body { padding: 16px 8px; } .page-header { padding: 22px 18px 18px; } .page-body { padding: 18px 16px 24px; } .create-section { padding: 14px; } }
    </style>
</head>
<body>
    <div class="container">
        <div class="page-header">
            <h1>ACP 身份管理</h1>
            <div class="nav-links">
                <a href="https://agentunion.net" target="_blank">AgentUnion排行榜</a>
                <a href="https://github.com/anthropics/agentcp" target="_blank">ACP 开源GitHub</a>
            </div>
        </div>
        <div class="page-body">
        <div class="hint" id="hint">最多注册 10 个 AID</div>
        <div class="create-section" id="createSection">
            <div class="aid-input-row">
                <input type="text" id="newAid" placeholder="输入名称">
                <span class="dot-separator">.</span>
                <select id="apSelect"></select>
            </div>
            <div class="extra-fields">
                <input type="text" id="aidNickname" placeholder="昵称（选填）">
                <input type="text" id="aidDescription" placeholder="描述（选填）" style="flex:2;">
            </div>
            <button class="btn btn-primary" onclick="createAid()">注册 AID</button>
        </div>
        <div class="aid-list" id="aidList"></div>
        <div class="status" id="status"></div>
        </div>
    </div>
    <script>
        var aidData = { aidList: [], aidStatus: [], apiUrl: '' };
        async function loadAidInfo() {
            try {
                var res = await fetch('/api/aid');
                var data = await res.json();
                aidData = data;
                updateApSelect();
                renderAidList();
            } catch (e) { console.error('加载失败', e); }
        }
        function updateApSelect() {
            var sel = document.getElementById('apSelect');
            if (sel && sel.options.length === 0) {
                ['agentcp.io', 'aid.show', 'agentid.pub'].forEach(function(op) {
                    var opt = document.createElement('option');
                    opt.value = op; opt.textContent = op;
                    if (op === 'agentcp.io') opt.selected = true;
                    sel.appendChild(opt);
                });
            }
        }
        function renderAidList() {
            var list = document.getElementById('aidList');
            var items = aidData.aidStatus || [];
            if (!items.length) { list.innerHTML = '<div style="text-align:center;color:#9ca3af;padding:20px;font-size:13px;">暂无 AID，请先注册</div>'; return; }
            var html = '';
            items.forEach(function(a) {
                var online = a.online;
                html += '<div class="aid-card">';
                html += '<div class="aid-card-left">';
                html += '<div class="aid-card-header"><span class="aid-name">' + escH(a.aid) + '</span> <button class="copy-btn" onclick="copyAid(\'' + escH(a.aid) + '\')">复制</button></div>';
                html += '<div class="aid-card-status">';
                if (a.certValid) html += '<span class="badge badge-success">证书有效</span>';
                else html += '<span class="badge badge-danger">证书无效</span>';
                if (online) html += '<span class="badge badge-info">在线</span>';
                else html += '<span class="badge badge-warning">离线</span>';
                html += '</div></div>';
                html += '<div class="aid-card-right"><div class="aid-card-actions">';
                if (online) {
                    html += '<button class="btn btn-sm btn-success" onclick="enterChat(\'' + escH(a.aid) + '\')">进入聊天</button>';
                    html += '<button class="btn btn-sm btn-danger" onclick="goOffline(\'' + escH(a.aid) + '\')">下线</button>';
                } else {
                    html += '<button class="btn btn-sm btn-outline" onclick="goOnline(\'' + escH(a.aid) + '\')">上线</button>';
                }
                html += '</div></div></div>';
            });
            list.innerHTML = html;
        }
        function escH(t) { var d = document.createElement('div'); d.textContent = t; return d.innerHTML; }
        function showStatus(msg, type) {
            var el = document.getElementById('status');
            el.textContent = msg; el.className = 'status ' + type;
            setTimeout(function() { el.className = 'status'; }, 3000);
        }
        function copyAid(aid) { navigator.clipboard.writeText(aid).then(function() { showStatus('已复制: ' + aid, 'success'); }); }
        async function createAid() {
            var name = document.getElementById('newAid').value.trim();
            if (!name) { showStatus('请输入名称', 'error'); return; }
            var ap = document.getElementById('apSelect').value;
            var nickname = document.getElementById('aidNickname').value.trim();
            var description = document.getElementById('aidDescription').value.trim();
            try {
                var r = await fetch('/api/aid/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prefix: name, ap: ap, nickname: nickname, description: description }) });
                var d = await r.json();
                if (d.success) { showStatus('注册成功: ' + d.aid, 'success'); document.getElementById('newAid').value = ''; loadAidInfo(); }
                else { showStatus(d.error || '注册失败', 'error'); }
            } catch (e) { showStatus('注册失败: ' + e.message, 'error'); }
        }
        async function goOnline(aid) {
            try {
                var r = await fetch('/api/ws/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ aid: aid }) });
                var d = await r.json();
                if (d.success) { showStatus(aid + ' 已上线', 'success'); loadAidInfo(); }
                else { showStatus(d.error || '上线失败', 'error'); }
            } catch (e) { showStatus('上线失败: ' + e.message, 'error'); }
        }
        async function goOffline(aid) {
            try {
                var r = await fetch('/api/aid/offline', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ aid: aid }) });
                var d = await r.json();
                if (d.success) { showStatus(aid + ' 已下线', 'success'); loadAidInfo(); }
                else { showStatus(d.error || '下线失败', 'error'); }
            } catch (e) { showStatus('下线失败: ' + e.message, 'error'); }
        }
        function enterChat(aid) { window.location.href = '/chat?aid=' + encodeURIComponent(aid); }
        loadAidInfo();
        setInterval(loadAidInfo, 5000);
    </script>
</body>
</html>
