/* ─────────────────────────────────────────────────────────────
   02  서버 접속 테스트
───────────────────────────────────────────────────────────── */
function getServerCfg(p) {
  return {
    serverHostName: document.getElementById(`${p}-server`).value.trim(),
    port:           parseInt(document.getElementById(`${p}-port`).value) || 4840,
    clientHostName: document.getElementById(`${p}-client`).value.trim(),
    userName:       document.getElementById(`${p}-user`).value.trim(),
    password:       document.getElementById(`${p}-pass`).value
  };
}

async function connTest() {
  setGlobal('busy', '접속 중');
  try {
    const d = await api('POST', '/api/connection/test', getServerCfg('x'));
    log('conn-log', [
      { c: d.success ? 'ok' : 'err', t: (d.success ? '✅ ' : '❌ ') + d.message },
      ...(d.sessionId ? [{ c: 'inf', t: '   SessionID : ' + d.sessionId }] : []),
      ...(d.policyUri ? [{ c: 'inf', t: '   Policy    : ' + d.policyUri.split('/').pop() }] : [])
    ]);
    setGlobal(d.success ? 'ok' : 'err', d.success ? '연결 성공' : '연결 실패');
  } catch (e) {
    log('conn-log', [{ c: 'err', t: '❌ ' + e.message }]);
    setGlobal('err', '오류');
  }
}

async function connRead() {
  const nodeId = document.getElementById('x-node').value.trim();
  if (!nodeId) return;
  setGlobal('busy', '태그 읽기');
  try {
    const d = await api('POST', '/api/connection/read', {
      serverConfig: getServerCfg('x'), nodeId
    });
    const box = document.getElementById('tag-box');
    box.classList.remove('hidden');
    if (d.success) {
      box.innerHTML = `
        <div class="ll ok">✅ 읽기 성공</div>
        <div class="ll"><span class="mut">NodeID  : </span><span style="color:var(--t0)">${esc(d.nodeId)}</span></div>
        <div class="ll"><span class="mut">Value   : </span><span class="val">${esc(d.value ?? 'null')}</span></div>
        <div class="ll"><span class="mut">Status  : </span><span class="ok">${esc(d.statusCode)}</span></div>
        <div class="ll"><span class="mut">Time    : </span><span class="inf">${d.timestamp ? new Date(d.timestamp).toLocaleString('ko-KR') : '-'}</span></div>
      `;
      setGlobal('ok', '읽기 완료');
    } else {
      box.innerHTML = `<div class="ll err">❌ ${esc(d.error || '읽기 실패')}</div>`;
      setGlobal('err', '읽기 실패');
    }
  } catch (e) {
    setGlobal('err', '오류');
  }
}

async function llmLoadConfig() {
  const statusEl = document.getElementById('llm-status');
  const input = document.getElementById('llm-model');
  statusEl.innerHTML = '<span class="placeholder">불러오는 중...</span>';
  try {
    const d = await api('GET', '/api/llm/config');
    if (d.success) {
      input.value = d.vllmModel || '';
      statusEl.innerHTML = `<span style="color:var(--color-success)">✓ 현재 모델: ${esc(d.vllmModel)}</span>`;
    } else {
      statusEl.innerHTML = `<span style="color:var(--color-danger)">✗ ${esc(d.error || '조회 실패')}</span>`;
    }
  } catch (e) {
    statusEl.innerHTML = `<span style="color:var(--color-danger)">✗ ${esc(e.message)}</span>`;
  }
}

async function llmSaveModelConfig() {
  const statusEl = document.getElementById('llm-status');
  const model = document.getElementById('llm-model').value.trim();
  if (!model) {
    statusEl.innerHTML = '<span style="color:var(--color-danger)">모델명을 입력하세요</span>';
    return;
  }
  statusEl.innerHTML = '<span class="placeholder">저장 중...</span>';
  try {
    const d = await api('POST', '/api/llm/config', { vllm_model: model });
    if (d.success) {
      statusEl.innerHTML = `<span style="color:var(--color-success)">✓ 모델 변경 완료: ${esc(d.vllmModel)} (다음 LLM 요청 시 반영)</span>`;
    } else {
      statusEl.innerHTML = `<span style="color:var(--color-danger)">✗ ${esc(d.error || '저장 실패')}</span>`;
    }
  } catch (e) {
    statusEl.innerHTML = `<span style="color:var(--color-danger)">✗ ${esc(e.message)}</span>`;
  }
}

async function connBrowse() {
  const wrap = document.getElementById('browse-wrap');
  const logEl = document.getElementById('conn-log');
  setGlobal('busy', '노드 탐색');

  // 로그 초기화
  logEl.classList.remove('hidden');
  logEl.innerHTML = '<div class="ll inf">[진행] 노드 탐색 시작...</div>';

  try {
    logEl.innerHTML += '<div class="ll inf">[진행] 서버: ' + getServerCfg('x').serverHostName + ':' + getServerCfg('x').port + '</div>';

    const d = await api('POST', '/api/connection/browse', {
      serverConfig: getServerCfg('x'), startNodeId: null
    });
    
    logEl.innerHTML += '<div class="ll inf">[진행] 응답 수신: success=' + d.success + ', nodes=' + (d.nodes ? d.nodes.length : 0) + '</div>';
    
    if (d.success && d.nodes?.length) {
      wrap.classList.remove('hidden');
      logEl.innerHTML += '<div class="ll ok">✅ [성공] 탐색 성공: ' + d.nodes.length + '개 노드</div>';
      
      // 노드 이름 확인 로그
      const emptyNames = d.nodes.filter(n => !n.displayName || n.displayName.trim() === '');
      if (emptyNames.length > 0) {
        logEl.innerHTML += '<div class="ll err">⚠️ 노드 이름이 비어진 항목: ' + emptyNames.length + '개 (NodeId만 복사됨)</div>';
      }
      
      // 노드 목록 생성 (displayName이 없으면 NodeId를 노출 이름으로 사용)
      const nodeListHtml = d.nodes.map(n => {
        const displayName = n.displayName || '<span style="color:var(--red)">이름 없음</span>';
        const nodeId = n.nodeId;
        // 중복된 NodeId 건너뛰기
        const nodeHtml = `
          <div class="bnode" onclick="document.getElementById('x-node').value='${esc(nodeId)}'">
            <span>${n.nodeClass === 'Object' ? '📂' : '📌'}</span>
            <span style="color:var(--t0)">${esc(displayName)}</span>
            <span class="bclass" style="font-size:11px;margin-left:8px;border:1px solid var(--t3);padding:1px 4px;border-radius:3px">[${n.nodeClass}]</span>
            <span class="bnid" style="font-size:10px;display:block;margin-top:2px;color:var(--t3);font-family:var(--fm)">📄 ${esc(nodeId)}</span>
          </div>
        `;
        return nodeHtml;
      }).join('');
      
      wrap.innerHTML =
        `<div style="font-family:var(--fm);font-size:11px;color:var(--t2);margin-bottom:12px">🎉 탐색 성공: ${d.nodes.length}개 노드 발견</div>` +
        nodeListHtml;
      setGlobal('ok', '탐색 완료');
    } else {
      const errorMsg = d.error || '알 수 없는 에러';
      logEl.innerHTML += '<div class="ll err">❌ [실패] 탐색 실패: ' + errorMsg + '</div>';
      wrap.classList.remove('hidden');
      wrap.innerHTML = `<div style="color:var(--red,#e55);font-size:12px;padding:10px;border:1px solid var(--red,#e55);border-radius:4px">❌ ${errorMsg}</div>`;
      setGlobal('err', '탐색 실패');
    }
  } catch (e) {
    logEl.innerHTML += '<div class="ll err">❌ [오류] 요청 실패: ' + e.message + '</div>';
    wrap.classList.remove('hidden');
    wrap.innerHTML = `<div style="color:var(--red,#e55);font-size:12px;padding:10px;border:1px solid var(--red,#e55);border-radius:4px">❌ ${e.message}</div>`;
    setGlobal('err', '오류');
  }
}
