<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 配置 - Ops-Assistant</title>
<style>
:root{
  --bg:#f5f7fb;--text:#222;--card:#fff;--border:#e5e7eb;--muted:#6b7280;
  --accent:#ee5a24;--accent-hover:#d63031;--header-bg:linear-gradient(135deg,#ff6b6b,#ee5a24);
}
[data-theme="dark"]{
  --bg:#0f172a;--text:#e5e7eb;--card:#111827;--border:#1f2937;--muted:#9ca3af;
  --accent:#f97316;--accent-hover:#ea580c;--header-bg:linear-gradient(135deg,#7c2d12,#ea580c);
}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:var(--bg);color:var(--text);min-height:100vh}
.header{background:var(--header-bg);color:#fff;padding:18px 20px;position:sticky;top:0;z-index:100;box-shadow:0 2px 10px rgba(0,0,0,.15);display:flex;justify-content:space-between;align-items:center;gap:10px}
.header .right{display:flex;align-items:center;gap:8px}
.header a,.header button{color:#fff;text-decoration:none;background:rgba(255,255,255,.2);padding:0 10px;border-radius:8px;font-size:13px;border:none;cursor:pointer;line-height:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;}
.header button{width:28px;padding:0;transition:transform .2s ease}
.header button.spin{transform:rotate(180deg)}
.header button svg{width:16px;height:16px;stroke:#fff;fill:none;stroke-width:2}
.wrap{max-width:980px;margin:0 auto;padding:14px}
.card{background:var(--card);border-radius:6px;padding:14px;border:1px solid var(--border);box-shadow:none;margin-bottom:10px}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:10px 0}
.row label{width:180px;color:var(--muted);font-size:13px}
.row input{flex:1;min-width:240px;padding:8px;border:1px solid var(--border);border-radius:6px;font-size:13px;background:var(--card);color:var(--text)}
.btns{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
button{border:none;border-radius:6px;padding:8px 12px;cursor:pointer;color:#fff;background:var(--accent);font-size:13px}
button.secondary{background:#6b7280}
small{color:var(--muted)}
.theme-hidden{display:none !important;}
</style>
</head>
<body>
<div class="header">
  <div>🤖 AI 配置 · {{.version}}</div>
  <div class="right">
    <button id="themeToggle" class="theme-hidden" title="切换主题" aria-label="切换主题">
      <svg id="themeIcon" viewBox="0 0 24 24" aria-hidden="true">
        <circle cx="12" cy="12" r="5"></circle>
        <line x1="12" y1="2" x2="12" y2="4"></line>
        <line x1="12" y1="20" x2="12" y2="22"></line>
        <line x1="2" y1="12" x2="4" y2="12"></line>
        <line x1="20" y1="12" x2="22" y2="12"></line>
        <line x1="4.2" y1="4.2" x2="5.8" y2="5.8"></line>
        <line x1="18.2" y1="18.2" x2="19.8" y2="19.8"></line>
        <line x1="18.2" y1="5.8" x2="19.8" y2="4.2"></line>
        <line x1="4.2" y1="19.8" x2="5.8" y2="18.2"></line>
      </svg>
    </button>
    <a href="/">返回首页</a>
    <a href="/logout">退出</a>
  </div>
</div>
<div class="wrap">
  <div class="card">
    <h3>AI 模型配置</h3>
    <div class="row"><label>启用 AI 翻译</label><input id="enabled" type="checkbox"></div>
    <div class="row"><label>Base URL</label><input id="base_url" placeholder="https://api.xxx/v1"></div>
    <div class="row"><label>API Key</label><input id="api_key" type="password" placeholder="sk-..." autocomplete="new-password"></div>
    <div class="row"><label>Model</label><input id="model" placeholder="gemini-3-flash-preview"></div>
    <div class="row"><label>Timeout (秒)</label><input id="timeout" placeholder="15"></div>
    <small>用于将“非命令文本”翻译为标准命令（仅翻译，不自动执行）。</small>
    <div class="btns">
      <button onclick="save()">保存</button>
      <button class="secondary" onclick="load()">刷新</button>
    </div>
    <small id="msg"></small>
  </div>
</div>
<script>
async function api(url,opt={}){
  const r=await fetch(url,opt);
  const out=await r.json().catch(()=>({}));
  if(!r.ok) throw new Error(out.message||('HTTP '+r.status));
  return out?.data||{};
}
function esc(s){return String(s||'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));}
async function load(){
  try{
    const d=await api('/api/v1/admin/ai/settings');
    const s=d.settings||{};
    document.getElementById('enabled').checked = (String(s.ai_enabled||'').toLowerCase()==='true');
    document.getElementById('base_url').value = s.ai_base_url || '';
    document.getElementById('api_key').value = s.ai_api_key || '';
    document.getElementById('model').value = s.ai_model || '';
    document.getElementById('timeout').value = s.ai_timeout_seconds || '15';
    document.getElementById('msg').textContent='已加载';
  }catch(e){document.getElementById('msg').textContent='加载失败：'+esc(e.message||e);}  
}
async function save(){
  const payload={
    enabled: document.getElementById('enabled').checked,
    base_url: document.getElementById('base_url').value.trim(),
    api_key: document.getElementById('api_key').value.trim(),
    model: document.getElementById('model').value.trim(),
    timeout_seconds: parseInt(document.getElementById('timeout').value||'15',10)
  };
  try{
    await api('/api/v1/admin/ai/settings',{method:'PATCH',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
    document.getElementById('msg').textContent='已保存';
  }catch(e){document.getElementById('msg').textContent='保存失败：'+esc(e.message||e);}  
}
function setThemeIcon(theme){
  const icon=document.getElementById('themeIcon');
  if(!icon) return;
  if(theme==='dark'){
    icon.innerHTML = '<path d="M21 12.8A8.5 8.5 0 1 1 11.2 3.1 7 7 0 0 0 21 12.8z"></path>';
  }else{
    icon.innerHTML = '<circle cx="12" cy="12" r="5"></circle>'+
      '<line x1="12" y1="2" x2="12" y2="4"></line>'+
      '<line x1="12" y1="20" x2="12" y2="22"></line>'+
      '<line x1="2" y1="12" x2="4" y2="12"></line>'+
      '<line x1="20" y1="12" x2="22" y2="12"></line>'+
      '<line x1="4.2" y1="4.2" x2="5.8" y2="5.8"></line>'+
      '<line x1="18.2" y1="18.2" x2="19.8" y2="19.8"></line>'+
      '<line x1="18.2" y1="5.8" x2="19.8" y2="4.2"></line>'+
      '<line x1="4.2" y1="19.8" x2="5.8" y2="18.2"></line>';
  }
}
function applyTheme(theme){
  if(theme==='dark'){document.documentElement.setAttribute('data-theme','dark');}
  else{document.documentElement.removeAttribute('data-theme');}
  localStorage.setItem('theme',theme);
  setThemeIcon(theme);
}
function toggleTheme(){
  const cur=localStorage.getItem('theme')||'dark';
  const next = cur==='light'?'dark':'light';
  const btn=document.getElementById('themeToggle');
  if(btn){btn.classList.add('spin'); setTimeout(()=>btn.classList.remove('spin'),200);} 
  applyTheme(next);
}
(function(){
  const saved=localStorage.getItem('theme')||'dark';
  applyTheme(saved);
  const btn=document.getElementById('themeToggle');
  if(btn){btn.addEventListener('click',toggleTheme)}
  load();
})();
</script>
</body>
</html>
