/**
 * Utility helper to make floating UI panels draggable and collapsible.
 */

let globalMaxZIndex = 30;

export interface PanelControlOptions {
  handleEl?: HTMLElement | null;
  collapseBtnEl?: HTMLElement | null;
  bodyEl?: HTMLElement | null;
  onCollapseToggle?: (isCollapsed: boolean) => void;
}

export function makePanelDraggableAndCollapsible(
  panelEl: HTMLElement,
  options?: PanelControlOptions
): { toggleCollapse: () => void; isCollapsed: () => boolean } {
  if (!panelEl) return { toggleCollapse: () => {}, isCollapsed: () => false };

  const handleEl = (options?.handleEl || panelEl.querySelector('.hdr') || panelEl) as HTMLElement;
  const collapseBtnEl = (options?.collapseBtnEl || panelEl.querySelector('.collapse-btn')) as HTMLElement | null;
  const bodyEl = (options?.bodyEl || panelEl.querySelector('#propBody') || panelEl.querySelector('#layerBody') || panelEl.children[1]) as HTMLElement | null;

  let isCollapsed = false;
  let isDragging = false;
  let startX = 0;
  let startY = 0;
  let initialLeft = 0;
  let initialTop = 0;

  // Set initial drag cursor
  if (handleEl) {
    handleEl.style.cursor = 'grab';
    handleEl.style.userSelect = 'none';
  }

  // Focus panel to top z-index when clicked anywhere
  panelEl.addEventListener('pointerdown', () => {
    globalMaxZIndex++;
    panelEl.style.zIndex = String(globalMaxZIndex);
  });

  // Dragging handler
  const onPointerDown = (e: PointerEvent) => {
    // Ignore clicks on buttons, inputs, or interactive controls inside the header
    const target = e.target as HTMLElement;
    if (target.closest('button, input, select, a, label, .hdr-actions')) {
      return;
    }

    isDragging = true;
    globalMaxZIndex++;
    panelEl.style.zIndex = String(globalMaxZIndex);
    if (handleEl) handleEl.style.cursor = 'grabbing';

    const rect = panelEl.getBoundingClientRect();
    startX = e.clientX;
    startY = e.clientY;
    initialLeft = rect.left;
    initialTop = rect.top;

    // Convert CSS right/bottom to explicit left/top positioning on first drag
    panelEl.style.left = `${initialLeft}px`;
    panelEl.style.top = `${initialTop}px`;
    panelEl.style.right = 'auto';
    panelEl.style.bottom = 'auto';

    document.addEventListener('pointermove', onPointerMove);
    document.addEventListener('pointerup', onPointerUp);
    e.preventDefault();
  };

  const onPointerMove = (e: PointerEvent) => {
    if (!isDragging) return;

    const dx = e.clientX - startX;
    const dy = e.clientY - startY;

    let newLeft = initialLeft + dx;
    let newTop = initialTop + dy;

    // Clamp within window boundaries so panel doesn't disappear off-screen
    const maxLeft = Math.max(10, window.innerWidth - panelEl.offsetWidth - 10);
    const maxTop = Math.max(10, window.innerHeight - panelEl.offsetHeight - 10);

    newLeft = Math.max(10, Math.min(newLeft, maxLeft));
    newTop = Math.max(10, Math.min(newTop, maxTop));

    panelEl.style.left = `${newLeft}px`;
    panelEl.style.top = `${newTop}px`;
  };

  const onPointerUp = () => {
    if (!isDragging) return;
    isDragging = false;
    if (handleEl) handleEl.style.cursor = 'grab';
    document.removeEventListener('pointermove', onPointerMove);
    document.removeEventListener('pointerup', onPointerUp);
  };

  if (handleEl) {
    handleEl.addEventListener('pointerdown', onPointerDown as EventListener);

    // Double-click on header to toggle collapse/expand
    handleEl.addEventListener('dblclick', (e) => {
      const target = e.target as HTMLElement;
      if (target.closest('button, input, select, a, label')) return;
      toggleCollapseState();
    });
  }

  let lastHeight = '';

  // Collapse / Expand toggle function
  const toggleCollapseState = () => {
    isCollapsed = !isCollapsed;
    panelEl.classList.toggle('collapsed', isCollapsed);

    if (isCollapsed) {
      lastHeight = panelEl.style.height || `${panelEl.offsetHeight}px`;
      panelEl.style.height = '42px';
      if (bodyEl) bodyEl.style.display = 'none';
    } else {
      panelEl.style.height = lastHeight || '480px';
      if (bodyEl) bodyEl.style.display = 'flex';
    }

    if (collapseBtnEl) {
      collapseBtnEl.textContent = isCollapsed ? '▸' : '▾';
      collapseBtnEl.setAttribute('title', isCollapsed ? '펼치기' : '접기');
    }

    if (options?.onCollapseToggle) {
      options.onCollapseToggle(isCollapsed);
    }
  };

  if (collapseBtnEl) {
    collapseBtnEl.addEventListener('click', (e) => {
      e.stopPropagation();
      toggleCollapseState();
    });
  }

  return {
    toggleCollapse: toggleCollapseState,
    isCollapsed: () => isCollapsed,
  };
}
