import { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
import type { ReactNode } from 'react';
import { useAuth } from './AuthContext';
import { settingsAPI } from '../api/client';

const EDGE_SWIPE_THRESHOLD = 50; // pixels from left edge to start swipe
const SWIPE_MIN_DISTANCE = 40; // minimum swipe distance to trigger

export type SidebarMode = 'collapsed' | 'expanded' | 'toggle' | 'dynamic';

interface SidebarContextType {
  isCollapsed: boolean;
  isMobileOpen: boolean;
  sidebarMode: SidebarMode;
  canToggle: boolean;
  toggleCollapse: () => void;
  toggleMobileMenu: () => void;
  closeMobileMenu: () => void;
  setSidebarMode: (mode: SidebarMode) => Promise<void>;
  isHovered: boolean;
  setIsHovered: (isHovered: boolean) => void;
  showLogo: boolean;
  setShowLogo: (show: boolean) => void;
}

const SidebarContext = createContext<SidebarContextType | undefined>(undefined);

export function SidebarProvider({ children }: { children: ReactNode }) {
  const { token } = useAuth();
  const [userCollapsed, setUserCollapsed] = useState(() => {
    const key = 'user_sidebar_collapsed';
    const saved = localStorage.getItem(key);
    if (saved === 'true') return true;
    if (saved === 'false') return false;

    // Backward-compatibility: migrate legacy key
    const legacy = localStorage.getItem('sidebarCollapsed');
    if (legacy === 'true' || legacy === 'false') {
      localStorage.setItem(key, legacy);
      localStorage.removeItem('sidebarCollapsed');
      return legacy === 'true';
    }

    return true;
  });
  const [isMobileOpen, setIsMobileOpen] = useState(false);
  const [sidebarMode, setSidebarModeState] = useState<SidebarMode>('toggle');
  const [isHovered, setIsHovered] = useState(false);
  const [showLogo, setShowLogo] = useState(false);

  // Load sidebar mode from backend
	  useEffect(() => {
	    const loadSidebarMode = async () => {
	      try {
	        if (!token) {
	          setSidebarModeState('toggle');
	          setShowLogo(false);
	          return;
	        }

	        const data = await settingsAPI.getUi();
	        const parseBool = (val: any, defaultVal: boolean): boolean => {
	          if (val === undefined || val === null) return defaultVal;
	          if (val === true || val === 'true' || val === 'True' || val === 1 || val === '1') return true;
	          if (val === false || val === 'false' || val === 'False' || val === 0 || val === '0') return false;
	          return defaultVal;
	        };

	        if (data.sidebar_mode && ['collapsed', 'expanded', 'toggle', 'dynamic'].includes(data.sidebar_mode as string)) {
	          setSidebarModeState(data.sidebar_mode as SidebarMode);
	        }
	        if (data.show_logo !== undefined) {
	          setShowLogo(parseBool(data.show_logo, false));
	        }
	      } catch (error) {
	        console.error('Failed to load sidebar mode:', error);
	      }
	    };
	    loadSidebarMode();
	  }, [token]);

  // Compute isCollapsed based on mode
  const isCollapsed = sidebarMode === 'collapsed' ? true :
    sidebarMode === 'dynamic' ? true :
      sidebarMode === 'expanded' ? false :
        userCollapsed;

  // Can only toggle if mode is 'toggle'
  const canToggle = sidebarMode === 'toggle';

  // Sync collapsed state to document root for CSS selectors
  useEffect(() => {
    const root = document.documentElement;
    root.setAttribute('data-sidebar-collapsed', String(isCollapsed));
  }, [isCollapsed]);

  const toggleCollapse = () => {
    if (canToggle) {
      setUserCollapsed((prev) => {
        const next = !prev;
        localStorage.setItem('user_sidebar_collapsed', String(next));
        return next;
      });
    }
  };

  const toggleMobileMenu = () => {
    setIsMobileOpen((prev) => !prev);
  };

  const closeMobileMenu = () => {
    setIsMobileOpen(false);
  };

  const openMobileMenu = useCallback(() => {
    setIsMobileOpen(true);
  }, []);

  // Edge swipe detection for mobile
  const swipeRef = useRef({
    startX: 0,
    startY: 0,
    isEdgeSwipe: false,
    isMobile: false,
  });

  useEffect(() => {
    const updateMobile = () => {
      swipeRef.current.isMobile = window.innerWidth <= 768;
    };
    updateMobile();
    window.addEventListener('resize', updateMobile, { passive: true });

    const handleTouchStart = (e: TouchEvent) => {
      if (!swipeRef.current.isMobile) return;
      const touch = e.touches[0];
      if (!touch) return;

      if (touch.clientX <= EDGE_SWIPE_THRESHOLD) {
        swipeRef.current.startX = touch.clientX;
        swipeRef.current.startY = touch.clientY;
        swipeRef.current.isEdgeSwipe = true;
      } else {
        swipeRef.current.isEdgeSwipe = false;
      }
    };

    const handleTouchMove = (e: TouchEvent) => {
      if (!swipeRef.current.isEdgeSwipe) return;
      const touch = e.touches[0];
      if (!touch) return;

      const dx = touch.clientX - swipeRef.current.startX;
      const dy = Math.abs(touch.clientY - swipeRef.current.startY);

      if (dx > SWIPE_MIN_DISTANCE && dx > dy * 2) {
        openMobileMenu();
        swipeRef.current.isEdgeSwipe = false;
      }
    };

    const handleTouchEnd = () => {
      swipeRef.current.isEdgeSwipe = false;
    };

    document.addEventListener('touchstart', handleTouchStart, { passive: true });
    document.addEventListener('touchmove', handleTouchMove, { passive: true });
    document.addEventListener('touchend', handleTouchEnd, { passive: true });

    return () => {
      window.removeEventListener('resize', updateMobile);
      document.removeEventListener('touchstart', handleTouchStart);
      document.removeEventListener('touchmove', handleTouchMove);
      document.removeEventListener('touchend', handleTouchEnd);
    };
  }, [openMobileMenu]);

	  const setSidebarMode = useCallback(async (mode: SidebarMode) => {
	    try {
	      if (!token) return;
	      await settingsAPI.updateSetting('sidebar_mode', mode);
	      setSidebarModeState(mode);
	    } catch (error) {
	      console.error('Failed to save sidebar mode:', error);
	    }
	  }, [token]);

  return (
    <SidebarContext.Provider
      value={{
        isCollapsed,
        isMobileOpen,
        sidebarMode,
        canToggle,
        toggleCollapse,
        toggleMobileMenu,
        closeMobileMenu,
        setSidebarMode,
        isHovered,
        setIsHovered: (value: boolean) => setIsHovered(value),
        showLogo,
        setShowLogo,
      }}
    >
      {children}
    </SidebarContext.Provider>
  );
}

export function useSidebar() {
  const context = useContext(SidebarContext);
  if (context === undefined) {
    throw new Error('useSidebar must be used within a SidebarProvider');
  }
  return context;
}
