# -*- coding: utf-8 -*-
"""后台前端接写接口
 · 读接口保持免登录（页面打开即可查、可预览，行为不变）
 · 写操作（新建/编辑/删除会议）改为调真接口，未登录时弹登录框
 · 写成功一律重新拉取 bootstrap，界面展示数据库真实结果（不做本地假修改）
"""
P = '/data/www/files/rmsys-app/backend/src/Rmsys.Api/wwwroot/admin.html'
s = open(P, encoding='utf-8').read()
n0 = len(s.encode())

# ---------- 1) 侧栏加「当前操作人」 ----------
old = '''      <span>干部科 · 管理后台</span>
    </div>
  </div>'''
new = '''      <span>干部科 · 管理后台</span>
    </div>
  </div>
  <div id="whoami">未登录（可查询，写操作需登录）</div>'''
assert s.count(old) == 1, '侧栏锚点异常'
s = s.replace(old, new, 1)

# ---------- 2) 注入登录态与写接口层 ----------
AUTH = r'''
/* ==========================================================================
   登录态与写接口
   读接口（bootstrap / 包校验 / 批注查询）免登录，页面照常打开即可查看。
   写操作需 JWT：未登录时弹登录框，成功后 token 存 sessionStorage。
   ========================================================================== */
var AUTH = {
  token: (function(){ try { return sessionStorage.getItem('rmsys_token') || ''; } catch(e){ return ''; } })(),
  user: null
};

function apiCall(path, method, body){
  var opt = { method: method || 'GET', headers: {} };
  if(body !== undefined){
    opt.headers['Content-Type'] = 'application/json';
    opt.body = JSON.stringify(body);
  }
  if(AUTH.token) opt.headers['Authorization'] = 'Bearer ' + AUTH.token;
  return fetch(path, opt).then(function(r){
    if(r.status === 401){
      AUTH.token = '';
      try { sessionStorage.removeItem('rmsys_token'); } catch(e){}
      paintUser();
      return { ok: false, __needLogin: true, message: '登录已失效，请重新登录' };
    }
    return r.json();
  });
}

function paintUser(){
  var el = document.getElementById('whoami');
  if(!el) return;
  el.innerHTML = AUTH.user
    ? ('操作人：<b style="color:#A8171C">' + esc(AUTH.user.name) + '</b> · ' + esc(AUTH.user.role))
    : '未登录（可查询，写操作需登录）';
}

function ensureAuth(){
  if(AUTH.token) return Promise.resolve(true);
  return loginModal();
}

function cancelLogin(){
  if(window.__loginResolve){ window.__loginResolve(false); window.__loginResolve = null; }
  closeModal();
}

function loginModal(){
  return new Promise(function(resolve){
    window.__loginResolve = resolve;
    var h = '<div class="modal-h"><h3>登录管理后台</h3><div class="spacer"></div>'
      + '<button class="x" onclick="cancelLogin()">&times;</button></div>'
      + '<div class="modal-b">'
      + '<div class="sec-note">新建、编辑、删除、批注、登记结果等写操作需登录，操作人将记入审计日志。<b>查询与预览无需登录。</b></div>'
      + '<div class="form-grid">'
      + '<div class="fld"><label>登录账号 <i>*</i></label><input type="text" id="lg_acc" value="admin">'
      + '<div class="hint">演示账号：admin / wangkc / lisp / bubz / audit01</div></div>'
      + '<div class="fld"><label>口令 <i>*</i></label><input type="password" id="lg_pwd" value="Rmsys@2026">'
      + '<div class="hint">演示口令统一 Rmsys@2026</div></div>'
      + '</div><div class="hint" id="lg_msg"></div></div>'
      + '<div class="modal-f"><button class="btn" onclick="cancelLogin()">取消</button>'
      + '<button class="btn pri" onclick="doLogin()">登录</button></div>';
    openModal(h, true);
  });
}

function doLogin(){
  var acc = (document.getElementById('lg_acc').value || '').trim();
  var pwd = document.getElementById('lg_pwd').value || '';
  var msg = document.getElementById('lg_msg');
  if(!acc || !pwd){ msg.innerHTML = '<span style="color:#A8171C">请填写账号与口令</span>'; return; }
  msg.innerHTML = '正在校验…';
  apiCall('/api/auth/login', 'POST', { account: acc, password: pwd, device: 'PC-WEB' })
    .then(function(d){
      if(!d || !d.ok){
        msg.innerHTML = '<span style="color:#A8171C">' + esc((d && d.message) || '登录失败') + '</span>';
        return;
      }
      AUTH.token = d.token;
      AUTH.user = d.user;
      try { sessionStorage.setItem('rmsys_token', d.token); } catch(e){}
      paintUser();
      closeModal();
      toast('已登录：' + d.user.name + '（' + d.user.role + '）', 'ok');
      if(window.__loginResolve){ window.__loginResolve(true); window.__loginResolve = null; }
    })
    .catch(function(e){ msg.innerHTML = '<span style="color:#A8171C">' + esc(e.message) + '</span>'; });
}

/* 记一次写操作并刷新界面（刷新后展示的是数据库真实结果） */
function afterWrite(d, okMsg, meetingId){
  if(d && d.__needLogin){ toast('登录已失效，请重新登录', 'wr'); ensureAuth(); return; }
  if(!d || !d.ok){ toast((d && d.message) || '操作失败', 'wr'); return; }
  closeModal();
  toast(okMsg, 'ok');
  if(meetingId) ROLE.meeting = meetingId;
  bootstrap(true, true);
}

'''

anchor = 'function bootstrap(keepView){'
assert s.count(anchor) == 1, 'bootstrap 锚点异常'
s = s.replace(anchor, AUTH.lstrip('\n') + anchor, 1)

# ---------- 3) bootstrap 支持静默刷新 ----------
old = "function bootstrap(keepView){\n  var url = API_BASE + '/api/admin/bootstrap?meetingId=' + (ROLE.meeting || 1);"
new = "function bootstrap(keepView, silent){\n  var url = API_BASE + '/api/admin/bootstrap?meetingId=' + (ROLE.meeting || 1);"
assert s.count(old) == 1, 'bootstrap 签名异常'
s = s.replace(old, new, 1)

old = "      toast('已连接数据库 · 上会 ' + CADRES.length + ' 人 / 会议 ' + MEETINGS.length + ' 场', 'ok');"
new = ("      if(!silent) toast('已连接数据库 · 上会 ' + CADRES.length + ' 人 / 会议 ' + MEETINGS.length + ' 场', 'ok');\n"
       "      paintUser();")
assert s.count(old) == 1, 'bootstrap toast 锚点异常'
s = s.replace(old, new, 1)

# ---------- 4) saveMeeting 改为调真接口 ----------
old_save = """function saveMeeting(id){
  var name=$('f_name').value.trim();
  if(!name){ toast('请填写会议名称','wr'); return; }
  var depts=[]; document.querySelectorAll('.f_dept').forEach(function(c){ if(c.checked) depts.push(c.value); });
  var t=typeOf($('f_type').value);
  if(t.depts && !depts.length){ toast('部务会至少选择一个处室','wr'); return; }
  var obj={no:$('f_no').value.trim(),type:$('f_type').value,name:name,time:$('f_time').value,
           place:$('f_place').value,host:$('f_host').value,secret:$('f_secret').value,
           level:$('f_level').value,status:$('f_status').value,depts:depts};
  if(id){ MEETINGS.forEach(function(m){ if(m.id===id){ for(var k in obj) m[k]=obj[k]; } }); toast('会议已保存'); }
  else { obj.id=Math.max.apply(null,MEETINGS.map(function(m){return m.id;}))+1; MEETINGS.unshift(obj); ROLE.meeting=obj.id; toast('会议创建成功','ok'); }
  closeModal(); render();
}"""

new_save = """var MEET_STATUS_CODE={'筹备中':'draft','材料已审核':'reviewing','已下发':'delivered',
                     '会议召开中':'ongoing','结果已登记':'registered','已归档':'archived'};
var MEET_STATUS_CN={'draft':'筹备中','reviewing':'材料已审核','delivered':'已下发',
                    'ongoing':'会议召开中','registered':'结果已登记','archived':'已归档'};

function saveMeeting(id){
  var name=$('f_name').value.trim();
  if(!name){ toast('请填写会议名称','wr'); return; }
  var depts=[]; document.querySelectorAll('.f_dept').forEach(function(c){ if(c.checked) depts.push(c.value); });
  var t=typeOf($('f_type').value);
  if(t.depts && !depts.length){ toast('部务会至少选择一个处室','wr'); return; }

  /* 表单值 → 接口字段（sessionNo 整型、heldAt ISO、pwdLevel 去掉括号说明、status 转编码） */
  var noStr=$('f_no').value.trim();
  var timeStr=$('f_time').value.trim();
  var payload={
    type: $('f_type').value,
    sessionNo: /^[0-9]+$/.test(noStr) ? parseInt(noStr,10) : null,
    name: name,
    heldAt: timeStr ? (timeStr.replace(' ','T').length===16 ? timeStr.replace(' ','T')+':00' : timeStr.replace(' ','T')) : null,
    place: $('f_place').value,
    host: $('f_host').value,
    secret: $('f_secret').value,
    pwdLevel: $('f_level').value.split('（')[0],
    status: MEET_STATUS_CODE[$('f_status').value] || 'draft'
  };

  ensureAuth().then(function(ok){
    if(!ok) return;
    var req = id ? apiCall('/api/admin/meetings/'+id, 'PUT', payload)
                 : apiCall('/api/admin/meetings', 'POST', payload);
    req.then(function(d){
      if(d && d.ok){
        afterWrite(d, id ? '会议已保存（已入库）' : '会议创建成功（已入库）', d.id || (id ? ROLE.meeting : null));
      } else {
        afterWrite(d, '', null);
      }
    });
  });
}"""

assert s.count(old_save) == 1, 'saveMeeting 锚点异常'
s = s.replace(old_save, new_save, 1)

# ---------- 5) doDelMeeting 改为调真接口（软删除） ----------
old_del = """function doDelMeeting(id){
  MEETINGS=MEETINGS.filter(function(m){ return m.id!==id; });
  if(ROLE.meeting===id && MEETINGS.length) ROLE.meeting=MEETINGS[0].id;
  closeModal(); render(); toast('已删除（可在回收站恢复，操作已留痕）');
}"""

new_del = """function doDelMeeting(id){
  ensureAuth().then(function(ok){
    if(!ok) return;
    apiCall('/api/admin/meetings/'+id, 'DELETE').then(function(d){
      if(d && d.ok){
        if(ROLE.meeting===id){
          var rest=MEETINGS.filter(function(m){ return m.id!==id; });
          if(rest.length) ROLE.meeting=rest[0].id;
        }
        afterWrite(d, '已删除（可在回收站恢复，操作已留痕）', null);
      } else {
        afterWrite(d, '', null);
      }
    });
  });
}"""

assert s.count(old_del) == 1, 'doDelMeeting 锚点异常'
s = s.replace(old_del, new_del, 1)

open(P, 'w', encoding='utf-8').write(s)
print('admin.html %d -> %d bytes' % (n0, len(s.encode())))
