const SHOW_DELAY = 1000;
const HIDE_DELAY = 100;

const SVG_NS = 'http://www.w3.org/2000/svg';
const RADIUS = 20;
const CIRC   = 2 * Math.PI * RADIUS; // ~125.66

let _el         = null;
let _imgEl      = null;
let _showTimer  = null;
let _hideTimer  = null;
let _visible    = false;
let _loaderEl   = null;
let _activeCard = null;
let _enabled    = true;

export function init() {
  _el = document.createElement('div');
  _el.className = 'hover-preview';

  _imgEl = document.createElement('img');
  _el.appendChild(_imgEl);
  document.body.appendChild(_el);
}

export function setEnabled(v) {
  _enabled = v;
  if (!v) {
    clearTimeout(_showTimer); _showTimer = null;
    clearTimeout(_hideTimer); _hideTimer = null;
    _removeLoader();
    _activeCard = null;
    _visible = false;
    _el.style.display    = 'none';
    _el.style.visibility = 'hidden';
  }
}

export function setupCard(card) {
  card.addEventListener('mouseenter', _onEnter);
  card.addEventListener('mouseleave', _onLeave);
}

function _onEnter() {
  if (!_enabled) return;
  const card = this;
  _activeCard = card;

  // 팝업이 사라지려고 대기 중이면 취소
  if (_hideTimer) {
    clearTimeout(_hideTimer);
    _hideTimer = null;
  }

  if (_visible) {
    // 이미 팝업이 열려 있으면 즉시 내용 전환
    _switchTo(card);
    return;
  }

  // 팝업이 닫힌 상태 — 1초 대기 후 표시
  clearTimeout(_showTimer);
  _showLoader(card);
  _showTimer = setTimeout(async () => {
    _showTimer = null;
    _removeLoader();
    if (_activeCard !== card) return;

    const src = await _loadSrc(card);
    if (!src || _activeCard !== card) return;

    _imgEl.src = src;
    _visible = true;
    _show(card);
  }, SHOW_DELAY);
}

function _onLeave() {
  if (!_visible) {
    // 팝업 미표시 상태 — 로더·타이머만 정리
    clearTimeout(_showTimer);
    _showTimer = null;
    _removeLoader();
    return;
  }

  // 팝업 표시 중 — 0.1초 후 닫기 (다른 카드 진입 시 취소됨)
  _hideTimer = setTimeout(() => {
    _hideTimer = null;
    _visible = false;
    _el.style.display    = 'none';
    _el.style.visibility = 'hidden';
  }, HIDE_DELAY);
}

// ── 팝업 내용 전환 (이미 열린 상태에서 카드 변경) ──

async function _switchTo(card) {
  const src = await _loadSrc(card);
  if (!src || _activeCard !== card) return;

  _imgEl.src = src;
  _show(card);
}

// ── 이미지 소스 반환 (카드 썸네일 캐시 우선) ──

async function _loadSrc(card) {
  const thumb = card.querySelector('img.card-thumb');
  let src = thumb?.src || '';
  if (!src) {
    src = await window.api.readImage(card.dataset.filepath) || '';
    if (src && thumb) thumb.src = src;
  }
  return src;
}

// ── 원형 로딩바 ──────────────────────────────────

function _showLoader(card) {
  _removeLoader();

  const svg = document.createElementNS(SVG_NS, 'svg');
  svg.classList.add('card-hover-loader');
  svg.setAttribute('viewBox', '0 0 48 48');

  const bg = document.createElementNS(SVG_NS, 'circle');
  bg.classList.add('loader-bg');
  bg.setAttribute('cx', '24'); bg.setAttribute('cy', '24'); bg.setAttribute('r', '24');

  const track = document.createElementNS(SVG_NS, 'circle');
  track.classList.add('loader-track');
  track.setAttribute('cx', '24'); track.setAttribute('cy', '24'); track.setAttribute('r', String(RADIUS));

  const progress = document.createElementNS(SVG_NS, 'circle');
  progress.classList.add('loader-progress');
  progress.setAttribute('cx', '24'); progress.setAttribute('cy', '24'); progress.setAttribute('r', String(RADIUS));
  progress.style.strokeDasharray  = CIRC;
  progress.style.strokeDashoffset = CIRC;

  svg.appendChild(bg);
  svg.appendChild(track);
  svg.appendChild(progress);
  card.appendChild(svg);
  _loaderEl = svg;
}

function _removeLoader() {
  if (_loaderEl) {
    _loaderEl.remove();
    _loaderEl = null;
  }
}

// ── 이미지 팝업 위치 계산 및 표시 ────────────────

function _show(card) {
  _el.style.display    = 'block';
  _el.style.visibility = 'hidden';
  _el.style.left = '0px';
  _el.style.top  = '0px';

  requestAnimationFrame(() => {
    if (!_visible) return;

    const popup    = _el.getBoundingClientRect();
    const cardRect = card.getBoundingClientRect();
    const vw  = window.innerWidth;
    const vh  = window.innerHeight;
    const gap = 16;

    let left = cardRect.right + gap;
    if (left + popup.width > vw - 8) {
      left = cardRect.left - popup.width - gap;
    }
    left = Math.max(8, Math.min(left, vw - popup.width - 8));

    let top = cardRect.top + (cardRect.height - popup.height) / 2;
    top = Math.max(8, Math.min(top, vh - popup.height - 8));

    _el.style.left       = left + 'px';
    _el.style.top        = top  + 'px';
    _el.style.visibility = 'visible';
  });
}
