// SCADA 데모 — 컴포넌트 드래그 좌표 인스펙터 (개발용)
// 사용법: Shift+D 로 드래그 모드 토글. 컴포넌트 잡고 옮기면 새 좌표가 화면 + 콘솔 + 클립보드.
// 좌표 자동 적용은 안 함 — 사용자가 보고 코드(topology.js)에 반영.

(function () {
  let DRAG_MODE = false;
  let dragging = null;
  let svg = null;

  window.addEventListener('keydown', (e) => {
    // e.code 는 키보드 레이아웃/한영 입력기와 무관하게 동작
    if (e.shiftKey && e.code === 'KeyD') {
      e.preventDefault();
      DRAG_MODE = !DRAG_MODE;
      updateUI();
      console.log('[DRAG] mode:', DRAG_MODE ? 'ON' : 'OFF');
    }
    if (e.code === 'Escape' && dragging) {
      dragging.el.setAttribute('transform', dragging.origTransform);
      dragging.el.style.opacity = '';
      dragging = null;
    }
  }, true);

  function updateUI() {
    let ind = document.getElementById('drag-mode-indicator');
    if (DRAG_MODE) {
      if (!ind) {
        ind = document.createElement('div');
        ind.id = 'drag-mode-indicator';
        ind.style.cssText = `position:fixed;top:10px;left:50%;transform:translateX(-50%);
          background:#d63031;color:#fff;padding:6px 16px;border-radius:4px;
          font:700 13px/1.2 system-ui;z-index:9999;box-shadow:0 2px 8px rgba(0,0,0,0.4);`;
        ind.textContent = 'DRAG MODE — 컴포넌트 잡고 옮기기 (Shift+D 끄기 / Esc 취소)';
        document.body.appendChild(ind);
      }
      svg.style.cursor = 'grab';
      drawPipeHandles();
    } else {
      if (ind) ind.remove();
      svg.style.cursor = '';
      removePipeHandles();
    }
  }

  // 파이프 핸들 (via 점 + 절대 to 끝점)
  function drawPipeHandles() {
    if (!window.INVYONE_TOPO) return;
    removePipeHandles();
    const sceneContent = document.getElementById('scene-content');
    if (!sceneContent) return;
    const NS = 'http://www.w3.org/2000/svg';
    const layer = document.createElementNS(NS, 'g');
    layer.setAttribute('id', 'pipe-handles-layer');

    let ports;
    try { ports = window.INVYONE_TOPO.computePorts(); } catch { ports = {}; }

    (window.INVYONE_TOPO.PIPES || []).forEach(pipe => {
      // 1) 절대 to 끝점
      if (pipe.to && typeof pipe.to === 'object' && typeof pipe.to.x === 'number' && typeof pipe.to.y === 'number') {
        layer.appendChild(makeHandle(pipe.to.x, pipe.to.y, '#ff8a3a', { pipeId: pipe.id, kind: 'to-abs' }));
      }
      // 2) via 점들 — via 가 있으면 path 의 corner 가 via 좌표에 정확히 떨어짐
      if (Array.isArray(pipe.via)) {
        pipe.via.forEach((v, i) => {
          // via.x 만 있으면 핸들 위치는 (v.x, 시작점 y 또는 다음 corner y) 추정
          // via.y 만 있으면 핸들 위치는 (시작점 x, v.y) 추정
          const fromXY = portXY(pipe.from, ports);
          const toXY = (typeof pipe.to === 'string') ? portXY(pipe.to, ports) :
                       (pipe.to && typeof pipe.to.x === 'number') ? { x: pipe.to.x, y: pipe.to.y } : null;
          let hx, hy;
          if (typeof v.x === 'number' && typeof v.y === 'number') {
            hx = v.x; hy = v.y;
          } else if (typeof v.x === 'number') {
            hx = v.x;
            hy = fromXY ? fromXY.y : (toXY ? toXY.y : 0);
          } else if (typeof v.y === 'number') {
            hy = v.y;
            hx = fromXY ? fromXY.x : (toXY ? toXY.x : 0);
          }
          if (hx == null || hy == null) return;
          layer.appendChild(makeHandle(hx, hy, '#5af9ff', { pipeId: pipe.id, kind: 'via', viaIdx: i }));
        });
      }
    });

    sceneContent.appendChild(layer);
  }

  function makeHandle(x, y, color, data) {
    const NS = 'http://www.w3.org/2000/svg';
    const c = document.createElementNS(NS, 'circle');
    c.setAttribute('cx', x);
    c.setAttribute('cy', y);
    c.setAttribute('r', 7);
    c.setAttribute('fill', color);
    c.setAttribute('stroke', '#fff');
    c.setAttribute('stroke-width', 2);
    c.setAttribute('class', 'pipe-handle');
    c.style.cursor = 'grab';
    c.style.opacity = '0.85';
    Object.entries(data).forEach(([k, v]) => c.dataset[k] = v);
    return c;
  }

  function removePipeHandles() {
    const old = document.getElementById('pipe-handles-layer');
    if (old) old.remove();
  }

  function portXY(ref, ports) {
    if (!ref || typeof ref !== 'string') return null;
    const [compId, portName] = ref.split('.');
    return ports[compId] && ports[compId][portName] ? ports[compId][portName] : null;
  }

  function toSvg(clientX, clientY) {
    const pt = svg.createSVGPoint();
    pt.x = clientX;
    pt.y = clientY;
    return pt.matrixTransform(svg.getScreenCTM().inverse());
  }

  function parseTranslate(transform) {
    const m = (transform || '').match(/translate\(([^)]+)\)/);
    if (!m) return { x: 0, y: 0 };
    const parts = m[1].split(/[ ,]+/).map(Number);
    return { x: parts[0] || 0, y: parts[1] || 0 };
  }

  function onMouseDown(e) {
    if (!DRAG_MODE) return;
    if (!svg.contains(e.target)) return;

    // 1) 파이프 핸들 우선 처리
    if (e.target.classList && e.target.classList.contains('pipe-handle')) {
      e.preventDefault();
      e.stopPropagation();
      const sp = toSvg(e.clientX, e.clientY);
      dragging = {
        isHandle: true,
        el: e.target,
        pipeId: e.target.dataset.pipeId,
        kind: e.target.dataset.kind,
        viaIdx: e.target.dataset.viaIdx ? parseInt(e.target.dataset.viaIdx, 10) : null,
        startMouseX: sp.x,
        startMouseY: sp.y,
        origCx: parseFloat(e.target.getAttribute('cx')),
        origCy: parseFloat(e.target.getAttribute('cy')),
      };
      e.target.style.cursor = 'grabbing';
      return;
    }

    const compEl = e.target.closest('.comp');
    if (!compEl) {
      console.log('[DRAG] mousedown target:', e.target.tagName, e.target.getAttribute && e.target.getAttribute('class'), '— .comp 못 찾음');
      return;
    }
    console.log('[DRAG] grabbed:', compEl.getAttribute('data-comp-id'));
    e.preventDefault();
    e.stopPropagation();

    const sp = toSvg(e.clientX, e.clientY);
    const tr = compEl.getAttribute('transform') || '';
    const orig = parseTranslate(tr);

    dragging = {
      el: compEl,
      compId: compEl.getAttribute('data-comp-id'),
      compType: compEl.getAttribute('data-comp-type'),
      origTransform: tr,
      origX: orig.x,
      origY: orig.y,
      startMouseX: sp.x,
      startMouseY: sp.y,
    };
    compEl.style.opacity = '0.65';
  }

  function onMouseMove(e) {
    if (!dragging) return;
    e.preventDefault();
    const sp = toSvg(e.clientX, e.clientY);
    const dx = sp.x - dragging.startMouseX;
    const dy = sp.y - dragging.startMouseY;
    if (dragging.isHandle) {
      const newCx = dragging.origCx + dx;
      const newCy = dragging.origCy + dy;
      dragging.el.setAttribute('cx', newCx.toFixed(1));
      dragging.el.setAttribute('cy', newCy.toFixed(1));
      return;
    }
    const newX = dragging.origX + dx;
    const newY = dragging.origY + dy;
    const newT = dragging.origTransform.replace(
      /translate\([^)]+\)/,
      `translate(${newX.toFixed(1)} ${newY.toFixed(1)})`
    );
    dragging.el.setAttribute('transform', newT);
  }

  function onMouseUp(e) {
    if (!dragging) return;
    e.preventDefault();
    const sp = toSvg(e.clientX, e.clientY);
    const dx = sp.x - dragging.startMouseX;
    const dy = sp.y - dragging.startMouseY;

    if (dragging.isHandle) {
      const newX = dragging.origCx + dx;
      const newY = dragging.origCy + dy;
      const moved = (Math.abs(dx) > 0.5 || Math.abs(dy) > 0.5);
      if (moved) applyHandleToTopology(dragging.pipeId, dragging.kind, dragging.viaIdx, newX, newY);
      showHandleResult(dragging.pipeId, dragging.kind, dragging.viaIdx, newX, newY);
      dragging.el.style.cursor = 'grab';
      dragging = null;
      if (moved) {
        rebuildScene();
        drawPipeHandles();
      }
      return;
    }

    showResult(dragging.compId, dragging.compType, dx, dy, dragging.origX, dragging.origY);
    if (Math.abs(dx) > 0.5 || Math.abs(dy) > 0.5) {
      const applied = applyToTopology(dragging.compId, dx, dy);
      if (applied) {
        rebuildScene();
        drawPipeHandles();
      }
    }

    dragging.el.style.opacity = '';
    dragging = null;
  }

  function applyHandleToTopology(pipeId, kind, viaIdx, newX, newY) {
    const PIPES = (window.INVYONE_TOPO && window.INVYONE_TOPO.PIPES) || [];
    const pipe = PIPES.find(p => p.id === pipeId);
    if (!pipe) return;
    if (kind === 'to-abs' && pipe.to && typeof pipe.to === 'object') {
      pipe.to.x = Math.round(newX);
      pipe.to.y = Math.round(newY);
    } else if (kind === 'via' && Array.isArray(pipe.via) && pipe.via[viaIdx]) {
      const v = pipe.via[viaIdx];
      if (typeof v.x === 'number') v.x = Math.round(newX);
      if (typeof v.y === 'number') v.y = Math.round(newY);
    }
  }

  function showHandleResult(pipeId, kind, viaIdx, x, y) {
    let msg;
    if (kind === 'to-abs') {
      msg = `▶ ${pipeId} (pipe to)\n새 끝점: { x: ${Math.round(x)}, y: ${Math.round(y)} }`;
    } else {
      const v = window.INVYONE_TOPO.PIPES.find(p => p.id === pipeId).via[viaIdx];
      const parts = [];
      if (typeof v.x === 'number') parts.push(`x: ${Math.round(x)}`);
      if (typeof v.y === 'number') parts.push(`y: ${Math.round(y)}`);
      msg = `▶ ${pipeId} (pipe via[${viaIdx}])\n새 좌표: { ${parts.join(', ')} }`;
    }
    console.log('%c[DRAG]\n' + msg, 'color:#ff8a3a;font-weight:700;');
    appendToPanel(msg, '#ff8a3a');
  }

  // 결과 누적 패널 — 모든 변경 사항이 한 곳에 쌓임
  const HISTORY = [];
  function appendToPanel(msg, color) {
    HISTORY.push({ time: new Date().toLocaleTimeString('ko-KR'), msg, color });
    let panel = document.getElementById('drag-result-panel');
    if (!panel) {
      panel = document.createElement('div');
      panel.id = 'drag-result-panel';
      panel.style.cssText = `position:fixed;top:60px;right:10px;background:#11102a;
        color:#fff;padding:0;border-radius:4px;border:1px solid #5af9ff;
        font:700 11px/1.5 monospace;z-index:9999;width:380px;max-height:80vh;
        display:flex;flex-direction:column;box-shadow:0 2px 10px rgba(0,0,0,0.5);`;
      const header = document.createElement('div');
      header.style.cssText = `padding:8px 12px;background:#1a1936;border-bottom:1px solid #5af9ff;
        display:flex;justify-content:space-between;align-items:center;flex-shrink:0;`;
      header.innerHTML = `<span style="color:#5af9ff;">📋 변경 기록 (<span id="drag-history-count">0</span>)</span>
        <span><button id="drag-copy-all" style="background:#5af9ff;color:#11102a;border:0;padding:3px 8px;border-radius:3px;cursor:pointer;font-weight:700;font-size:10px;margin-right:4px;">전체 복사</button>
        <button id="drag-clear" style="background:#444;color:#fff;border:0;padding:3px 8px;border-radius:3px;cursor:pointer;font-size:10px;margin-right:4px;">지우기</button>
        <button id="drag-close" style="background:#d63031;color:#fff;border:0;padding:3px 8px;border-radius:3px;cursor:pointer;font-size:10px;">닫기</button></span>`;
      const body = document.createElement('div');
      body.id = 'drag-history-body';
      body.style.cssText = `padding:8px 12px;overflow-y:auto;flex:1;white-space:pre-wrap;`;
      panel.appendChild(header);
      panel.appendChild(body);
      document.body.appendChild(panel);
      document.getElementById('drag-copy-all').addEventListener('click', () => {
        const all = HISTORY.map(h => h.msg).join('\n\n');
        if (navigator.clipboard) navigator.clipboard.writeText(all).then(() => {
          const btn = document.getElementById('drag-copy-all');
          const orig = btn.textContent;
          btn.textContent = '복사됨!';
          setTimeout(() => { btn.textContent = orig; }, 1200);
        });
      });
      document.getElementById('drag-clear').addEventListener('click', () => {
        HISTORY.length = 0;
        renderHistory();
      });
      document.getElementById('drag-close').addEventListener('click', () => panel.remove());
    }
    renderHistory();
    if (navigator.clipboard) navigator.clipboard.writeText(msg).catch(() => {});
  }

  function renderHistory() {
    const body = document.getElementById('drag-history-body');
    const count = document.getElementById('drag-history-count');
    if (!body) return;
    count.textContent = HISTORY.length;
    body.innerHTML = HISTORY.map((h, i) => {
      return `<div style="margin-bottom:10px;padding:6px 8px;background:#0a0a1a;border-left:3px solid ${h.color};border-radius:3px;">
        <div style="color:#888;font-size:10px;margin-bottom:3px;">#${i + 1} · ${h.time}</div>
        <div style="color:${h.color};">${h.msg.replace(/</g, '&lt;')}</div>
      </div>`;
    }).join('');
    body.scrollTop = body.scrollHeight;
  }

  function applyToTopology(compId, dx, dy) {
    const meta = findCompMeta(compId);
    if (!meta) return false;
    const c = meta.comp;
    if (c.anchor && c.anchor.absolute) {
      c.anchor.absolute.x = (c.anchor.absolute.x || 0) + dx;
      c.anchor.absolute.y = (c.anchor.absolute.y || 0) + dy;
      return true;
    }
    if (c.anchor && !c.anchor.absolute) {
      c.anchor.dx = (c.anchor.dx ?? 0) + dx;
      c.anchor.dy = (c.anchor.dy ?? 0) + dy;
      return true;
    }
    if (typeof c.x === 'number' && typeof c.y === 'number') {
      c.x += dx;
      c.y += dy;
      return true;
    }
    return false;
  }

  function rebuildScene() {
    const sceneEl = document.getElementById('scene-content');
    if (!sceneEl || !window.INVYONE_TOPO) return;
    // anchor 기반 컴포넌트의 _resolved 캐시 리셋 (dx/dy/at 등 변경 사항 재계산되도록)
    const T = window.INVYONE_TOPO;
    ['TANKS','PUMPS','VALVES','FILTERS','MODULES','GAUGES','SENSORS','LEDS'].forEach(b => {
      (T[b] || []).forEach(c => {
        if (c.anchor) {
          c._resolved = false;
          if (!c.anchor.absolute) { c.x = undefined; c.y = undefined; }
        }
      });
    });
    sceneEl.innerHTML = window.INVYONE_TOPO.buildScene();
    if (window.INVYONE_ENGINE && typeof window.INVYONE_ENGINE.init === 'function') {
      try { window.INVYONE_ENGINE.init(); } catch (err) { console.warn('[DRAG] engine.init re-call failed:', err); }
    }
  }

  function findCompMeta(compId) {
    if (!window.INVYONE_TOPO) return null;
    const T = window.INVYONE_TOPO;
    const buckets = ['TANKS', 'PUMPS', 'GAUGES', 'SENSORS', 'FILTERS', 'MODULES', 'LEDS', 'VALVES', 'TILES', 'PANELS'];
    for (const b of buckets) {
      const arr = T[b] || [];
      const c = arr.find((x) => x.id === compId);
      if (c) return { bucket: b, comp: c };
    }
    return null;
  }

  function showResult(compId, compType, dx, dy, origX, origY) {
    const meta = findCompMeta(compId);
    const isAnchor = !!(meta && meta.comp && meta.comp.anchor && !meta.comp.anchor.absolute);

    // 게이지는 transform 안에 (x-20, y-20) 적용돼 있으니 anchor 절대 좌표는 +20 보정
    const isGauge = compType === 'gauge';
    const baseX = isGauge ? origX + 20 : origX;
    const baseY = isGauge ? origY + 20 : origY;
    const newAnchorX = baseX + dx;
    const newAnchorY = baseY + dy;

    const dxStr = (dx >= 0 ? '+' : '') + dx.toFixed(1);
    const dyStr = (dy >= 0 ? '+' : '') + dy.toFixed(1);

    let lines = [`▶ ${compId} (${compType || '-'})`, `이동량: dx=${dxStr}, dy=${dyStr}`];

    if (isAnchor) {
      const a = meta.comp.anchor;
      const oldDx = a.dx ?? 0;
      const oldDy = a.dy ?? 0;
      lines.push(`anchor 기반 → 기존 dx:${oldDx}, dy:${oldDy}`);
      lines.push(`수정 후: dx:${(oldDx + dx).toFixed(1)}, dy:${(oldDy + dy).toFixed(1)}`);
    } else {
      lines.push(`절대 좌표 → 새 위치: x=${newAnchorX.toFixed(0)}, y=${newAnchorY.toFixed(0)}`);
    }

    const msg = lines.join('\n');
    console.log('%c[DRAG]\n' + msg, 'color:#5af9ff;font-weight:700;');
    appendToPanel(msg, '#5af9ff');
  }

  function init() {
    svg = document.getElementById('scene');
    if (!svg) {
      setTimeout(init, 100);
      return;
    }
    window.addEventListener('mousedown', onMouseDown, true);
    window.addEventListener('mousemove', onMouseMove, true);
    window.addEventListener('mouseup', onMouseUp, true);
    console.log('%c[DEV] Drag mode 사용 가능: Shift+D 로 토글', 'color:#5af9ff;font-weight:700;');
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
