/* ─────────────────────────────────────────────────────────────
    03  데이터 크롤링
───────────────────────────────────────────────────────────── */
async function crawlStart() {
  const nodeIds = document.getElementById('w-nodes').value
    .trim().split('\n').map(s => s.trim()).filter(Boolean);
  if (!nodeIds.length) { alert('노드 ID를 입력하세요.'); return; }

  const cfg = {
    serverHostName: document.getElementById('w-server').value.trim(),
    port:           parseInt(document.getElementById('w-port').value) || 4840,
    clientHostName: document.getElementById('w-client').value.trim(),
    userName:       document.getElementById('w-user').value.trim(),
    password:       document.getElementById('w-pass').value
  };
  const intervalSeconds = parseInt(document.getElementById('w-interval').value) || 1;
  const durationSeconds = parseInt(document.getElementById('w-duration').value) || 30;

  const btn = document.getElementById('crawl-btn');
  btn.disabled = true;
  btn.textContent = '⏳ 수집 중...';

  const prog = document.getElementById('crawl-prog');
  prog.classList.remove('hidden');
  document.getElementById('crawl-bar').style.width = '0%';
  document.getElementById('crawl-ptxt').textContent = '서버 연결 중...';
  document.getElementById('crawl-cnt').textContent  = '0 건';
  setGlobal('busy', '크롤링 중');

  // 백엔드는 동기식이므로 프런트에서 타이머로 UI 진행 표시
  let fake = 0;
  const ticker = setInterval(() => {
    fake = Math.min(fake + (100 / durationSeconds) * .5, 94);
    document.getElementById('crawl-bar').style.width = fake + '%';
    document.getElementById('crawl-ptxt').textContent = `수집 중... ${Math.round(fake)}%`;
  }, 500);

  try {
    const d = await api('POST', '/api/crawl/start', {
      serverConfig: cfg, nodeIds, intervalSeconds, durationSeconds
    });
    clearInterval(ticker);
    document.getElementById('crawl-bar').style.width = '100%';
    document.getElementById('crawl-ptxt').textContent = '수집 완료';
    document.getElementById('crawl-cnt').textContent  = d.totalRecords + ' 건';

    log('crawl-log', [
      { c: 'ok',  t: `✅ 크롤링 완료 — ${d.totalRecords}개 레코드` },
      { c: 'inf', t: `   Session : ${d.sessionId}` },
      { c: 'inf', t: `   CSV     : ${d.csvPath}` },
      { c: 'mut', t: '--- 미리보기 ---' },
      ...(d.preview || []).map(r => ({
        c: 'val',
        t: `   [${new Date(r.collectedAt).toLocaleTimeString('ko-KR')}] ${r.nodeId} = ${r.value} (${r.statusCode})`
      }))
    ]);
    setGlobal('ok', '크롤링 완료');
  } catch (e) {
    clearInterval(ticker);
    log('crawl-log', [{ c: 'err', t: '❌ ' + e.message }]);
    setGlobal('err', '오류');
  } finally {
    btn.disabled = false;
    btn.innerHTML = '📡 크롤링 시작';
  }
}

/* ─────────────────────────────────────────────────────────────
    03-B  노드맵 수집
───────────────────────────────────────────────────────────── */
async function nodeMapCrawl() {
  const maxDepth = parseInt(document.getElementById('nm-depth').value) || 10;
  const cfg = {
    serverHostName: document.getElementById('w-server').value.trim(),
    port:           parseInt(document.getElementById('w-port').value) || 4840,
    clientHostName: document.getElementById('w-client').value.trim(),
    userName:       document.getElementById('w-user').value.trim(),
    password:       document.getElementById('w-pass').value
  };

  const btn = document.getElementById('nm-btn');
  btn.disabled = true;
  btn.textContent = '⏳ 탐색 중...';

  const prog = document.getElementById('nm-prog');
  prog.classList.remove('hidden');
  document.getElementById('nm-bar').style.width = '0%';
  document.getElementById('nm-ptxt').textContent = '서버 연결 중...';
  document.getElementById('nm-cnt').textContent  = '';
  setGlobal('busy', '노드맵 수집 중');

  // 완료 시점을 알 수 없으므로 완만하게 90%까지 증가
  let fake = 0;
  const ticker = setInterval(() => {
    if (fake < 90) {
      fake = Math.min(fake + 0.25, 90);
      document.getElementById('nm-bar').style.width = fake + '%';
      document.getElementById('nm-ptxt').textContent = `노드 탐색 중... ${Math.round(fake)}%`;
    }
  }, 500);

  try {
    const d = await api('POST', '/api/crawl/nodemap', { serverConfig: cfg, maxDepth });
    clearInterval(ticker);
    document.getElementById('nm-bar').style.width = '100%';
    document.getElementById('nm-ptxt').textContent = d.success ? '탐색 완료' : '탐색 실패';
    document.getElementById('nm-cnt').textContent  = d.success ? d.totalCount.toLocaleString() + '개 노드' : '';

    log('nm-log', d.success ? [
      { c: 'ok',  t: `✅ 노드맵 수집 완료 — ${d.totalCount.toLocaleString()}개 노드` },
      { c: 'inf', t: `   저장 경로  : ${d.csvPath}` },
      { c: 'mut', t: `   04 DB 저장 탭에서 raw_node_map 테이블에 적재할 수 있습니다.` }
    ] : [
      { c: 'err', t: `❌ ${d.error || '탐색 실패'}` }
    ]);
    setGlobal(d.success ? 'ok' : 'err', d.success ? `노드 ${d.totalCount}개` : '실패');
  } catch (e) {
    clearInterval(ticker);
    log('nm-log', [{ c: 'err', t: '❌ ' + e.message }]);
    setGlobal('err', '오류');
  } finally {
    btn.disabled = false;
    btn.textContent = '🗺 전체 노드맵 수집';
  }
}
