import { useEffect } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'

const PAGES = ['/write', '/history', '/settings']
const SWIPE_THRESHOLD = 55   // minimum horizontal px to count as a swipe
const DESKTOP_BREAKPOINT = 860

/** Walk up the DOM and return true if any ancestor is horizontally scrollable */
function isInHScrollable(el: Element | null): boolean {
  while (el && el !== document.body) {
    const style = window.getComputedStyle(el)
    const ox = style.overflowX
    if ((ox === 'scroll' || ox === 'auto') && el.scrollWidth > el.clientWidth) {
      return true
    }
    el = el.parentElement
  }
  return false
}

/** Swipe left/right to navigate between the three main pages (mobile only) */
export function useSwipeNav() {
  const navigate = useNavigate()
  const location = useLocation()

  useEffect(() => {
    let startX = 0
    let startY = 0
    let startTarget: Element | null = null
    let cancelled = false

    const onTouchStart = (e: TouchEvent) => {
      startX = e.touches[0].clientX
      startY = e.touches[0].clientY
      startTarget = e.target as Element
      cancelled = false
    }

    const onTouchMove = (e: TouchEvent) => {
      // If vertical movement dominates early, cancel the swipe so we never
      // accidentally navigate while the user is scrolling.
      const dx = Math.abs(e.touches[0].clientX - startX)
      const dy = Math.abs(e.touches[0].clientY - startY)
      if (!cancelled && dy > dx && dy > 10) cancelled = true
    }

    const onTouchEnd = (e: TouchEvent) => {
      if (cancelled) return
      if (window.innerWidth >= DESKTOP_BREAKPOINT) return

      const dx = e.changedTouches[0].clientX - startX
      const dy = e.changedTouches[0].clientY - startY

      // Must be predominantly horizontal
      if (Math.abs(dx) <= Math.abs(dy)) return
      // Must clear the distance threshold
      if (Math.abs(dx) < SWIPE_THRESHOLD) return
      // Don't swipe-navigate when inside a horizontal scroll container
      if (isInHScrollable(startTarget)) return
      // Don't swipe-navigate when a modal/overlay is open
      if (document.querySelector('.confirm-modal-overlay, .cropper-overlay, .reminder-modal-overlay')) return

      const idx = PAGES.indexOf(location.pathname)
      if (idx === -1) return

      if (dx < 0 && idx < PAGES.length - 1) {
        navigate(PAGES[idx + 1])   // swipe left  → next page
      } else if (dx > 0 && idx > 0) {
        navigate(PAGES[idx - 1])   // swipe right → previous page
      }
    }

    document.addEventListener('touchstart', onTouchStart, { passive: true })
    document.addEventListener('touchmove',  onTouchMove,  { passive: true })
    document.addEventListener('touchend',   onTouchEnd,   { passive: true })

    return () => {
      document.removeEventListener('touchstart', onTouchStart)
      document.removeEventListener('touchmove',  onTouchMove)
      document.removeEventListener('touchend',   onTouchEnd)
    }
  }, [navigate, location.pathname])
}
