import { useState, useRef, useEffect, useCallback, useMemo } from 'react';

const EDGE_THRESHOLD = 20;
const SNAP_THRESHOLD = 0.4;
const VELOCITY_THRESHOLD = 0.5;

export function useSwipeNavigation({ enabled, canSwipeToChat }) {
  const [activeView, setActiveView] = useState('sidebar');
  const trayRef = useRef(null);

  // Refs so touch handlers always read current values
  const activeViewRef = useRef(activeView);
  const canSwipeToChatRef = useRef(canSwipeToChat);
  const screenWidthRef = useRef(window.innerWidth);

  useEffect(() => { activeViewRef.current = activeView; }, [activeView]);
  useEffect(() => { canSwipeToChatRef.current = canSwipeToChat; }, [canSwipeToChat]);

  // Track swiping state for pointer-events disabling
  const [isSwiping, setIsSwiping] = useState(false);

  // Programmatic navigation with smooth transition
  const goToChat = useCallback(() => {
    const tray = trayRef.current;
    if (tray) {
      tray.style.transition = 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
      tray.style.transform = `translateX(-${screenWidthRef.current}px)`;
    }
    setActiveView('chat');
  }, []);

  const goToSidebar = useCallback(() => {
    const tray = trayRef.current;
    if (tray) {
      tray.style.transition = 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
      tray.style.transform = 'translateX(0px)';
    }
    setActiveView('sidebar');
  }, []);

  useEffect(() => {
    if (!enabled) return;

    const handleResize = () => {
      const tray = trayRef.current;
      const panel = tray?.querySelector('.mobile-swipe-panel');
      screenWidthRef.current = panel?.offsetWidth || window.innerWidth;
    };
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, [enabled]);

  useEffect(() => {
    if (!enabled) return;
    const tray = trayRef.current;
    if (!tray) return;

    // Measure actual rendered panel width (CSS 100vw) instead of window.innerWidth
    const panel = tray.querySelector('.mobile-swipe-panel');
    if (panel) {
      screenWidthRef.current = panel.offsetWidth;
    }

    let tracking = false;
    let decided = false; // whether we've decided horizontal vs vertical
    let startX = 0;
    let startY = 0;
    let startTime = 0;
    let baseOffset = 0; // starting translateX when touch began
    let lastX = 0;
    let lastTime = 0;

    function getCurrentTranslateX() {
      const style = window.getComputedStyle(tray);
      const matrix = style.transform;
      if (!matrix || matrix === 'none') return 0;
      // matrix(a, b, c, d, tx, ty)
      const match = matrix.match(/matrix\(([^)]+)\)/);
      if (match) {
        const values = match[1].split(',').map(Number);
        return values[4] || 0;
      }
      return 0;
    }

    function onTouchStart(e) {
      if (e.touches.length !== 1) return;
      const touch = e.touches[0];
      const sw = screenWidthRef.current;
      const view = activeViewRef.current;

      // Edge detection: only start from edges
      const fromLeftEdge = touch.clientX <= EDGE_THRESHOLD;
      const fromRightEdge = touch.clientX >= sw - EDGE_THRESHOLD;

      if (view === 'chat' && fromLeftEdge) {
        // Potential swipe to sidebar
      } else if (view === 'sidebar' && fromRightEdge && canSwipeToChatRef.current) {
        // Potential swipe to chat
      } else {
        return; // Not an edge touch
      }

      // Capture current visual position (handles mid-animation interruption)
      tray.style.transition = 'none';
      baseOffset = getCurrentTranslateX();
      tray.style.transform = `translateX(${baseOffset}px)`;

      startX = touch.clientX;
      startY = touch.clientY;
      startTime = Date.now();
      lastX = touch.clientX;
      lastTime = startTime;
      tracking = false;
      decided = false;
    }

    function onTouchMove(e) {
      if (e.touches.length !== 1) return;
      if (decided && !tracking) return; // Decided vertical, ignore

      const touch = e.touches[0];
      const deltaX = touch.clientX - startX;
      const deltaY = touch.clientY - startY;

      // If we haven't decided intent yet
      if (!decided) {
        const absDx = Math.abs(deltaX);
        const absDy = Math.abs(deltaY);
        // Need some movement to decide
        if (absDx < 12 && absDy < 12) return;

        decided = true;
        if (absDx > absDy * 2) {
          tracking = true;
          setIsSwiping(true);
        } else {
          // Vertical — let it scroll
          return;
        }
      }

      if (!tracking) return;

      e.preventDefault();

      const sw = screenWidthRef.current;
      const view = activeViewRef.current;
      let newOffset = baseOffset + deltaX;

      // Clamp: tray can only be between -sw (chat) and 0 (sidebar)
      if (view === 'chat') {
        // On chat, base is -sw. Allow swiping right (toward 0) but not past
        newOffset = Math.max(-sw, Math.min(0, newOffset));
      } else {
        // On sidebar, base is 0. Allow swiping left (toward -sw) but not past
        newOffset = Math.max(-sw, Math.min(0, newOffset));
      }

      tray.style.transform = `translateX(${newOffset}px)`;
      lastX = touch.clientX;
      lastTime = Date.now();
    }

    function onTouchEnd(e) {
      if (!tracking) {
        decided = false;
        return;
      }

      tracking = false;
      decided = false;
      setIsSwiping(false);

      const sw = screenWidthRef.current;
      const view = activeViewRef.current;
      const currentOffset = getCurrentTranslateX();
      const elapsed = Date.now() - lastTime;
      const velocity = elapsed > 0 ? Math.abs(lastX - startX) / (Date.now() - startTime) : 0;

      let shouldTransition = false;

      if (view === 'chat') {
        // Swiping right to sidebar: progress is how far from -sw toward 0
        const progress = (currentOffset - (-sw)) / sw;
        shouldTransition = progress > SNAP_THRESHOLD || velocity > VELOCITY_THRESHOLD;
      } else {
        // Swiping left to chat: progress is how far from 0 toward -sw
        const progress = Math.abs(currentOffset) / sw;
        shouldTransition = progress > SNAP_THRESHOLD || velocity > VELOCITY_THRESHOLD;
      }

      tray.style.transition = 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)';

      if (shouldTransition) {
        if (view === 'chat') {
          tray.style.transform = 'translateX(0px)';
          setActiveView('sidebar');
        } else {
          tray.style.transform = `translateX(-${sw}px)`;
          setActiveView('chat');
        }
      } else {
        // Snap back
        if (view === 'chat') {
          tray.style.transform = `translateX(-${sw}px)`;
        } else {
          tray.style.transform = 'translateX(0px)';
        }
      }
    }

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

    return () => {
      tray.removeEventListener('touchstart', onTouchStart);
      tray.removeEventListener('touchmove', onTouchMove);
      tray.removeEventListener('touchend', onTouchEnd);
    };
  }, [enabled]);

  // Resting style: set initial position without transition on mount / view change
  const trayStyle = useMemo(() => {
    if (!enabled) return {};
    return {
      transform: activeView === 'chat' ? `translateX(-${screenWidthRef.current}px)` : 'translateX(0px)',
    };
  }, [enabled, activeView]);

  return { activeView, goToChat, goToSidebar, trayRef, trayStyle, isSwiping };
}
