import { createContext, useContext, useState, useEffect } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import PropTypes from 'prop-types'

const HistoryContext = createContext()

export const HistoryProvider = ({ children }) => {
  const [navigationHistory, setNavigationHistory] = useState([])
  const [currentPosition, setCurrentPosition] = useState(-1)
  const navigate = useNavigate()
  const location = useLocation()

  // Base route names
  const baseRouteNames = {
    '/production': 'Production',
    '/management': 'Management',
    '/dashboard/production/gcodefiles': 'GCode Files',
    '/dashboard/management/filaments': 'Filaments',
    '/dashboard/management/parts': 'Parts',
    '/dashboard/management/products': 'Products',
    '/dashboard/management/vendors': 'Vendors',
    '/dashboard/management/materials': 'Materials'
  }

  const getEntityDetails = (pathname, search) => {
    const searchParams = new URLSearchParams(search)

    // Handle different entity types
    if (pathname.includes('/gcodefiles/info')) {
      const gcodeFileId = searchParams.get('gcodeFileId')
      return {
        type: 'gcodefile',
        id: gcodeFileId,
        displayName: `GCode File Info${gcodeFileId ? ` (${gcodeFileId})` : ''}`
      }
    }
    if (pathname.includes('/filaments/info')) {
      const filamentId = searchParams.get('filamentId')
      return {
        type: 'filament',
        id: filamentId,
        displayName: `Filament Info${filamentId ? ` (${filamentId})` : ''}`
      }
    }
    if (pathname.includes('/parts/info')) {
      const partId = searchParams.get('partId')
      return {
        type: 'part',
        id: partId,
        displayName: `Part Info${partId ? ` (${partId})` : ''}`
      }
    }
    if (pathname.includes('/products/info')) {
      const productId = searchParams.get('productId')
      return {
        type: 'product',
        id: productId,
        displayName: `Product Info${productId ? ` (${productId})` : ''}`
      }
    }
    if (pathname.includes('/vendors/info')) {
      const vendorId = searchParams.get('vendorId')
      return {
        type: 'vendor',
        id: vendorId,
        displayName: `Vendor Info${vendorId ? ` (${vendorId})` : ''}`
      }
    }
    if (pathname.includes('/materials/info')) {
      const materialId = searchParams.get('materialId')
      return {
        type: 'material',
        id: materialId,
        displayName: `Material Info${materialId ? ` (${materialId})` : ''}`
      }
    }

    // For base routes, return the simple name
    const baseName = baseRouteNames[pathname]
    if (baseName) {
      return {
        type: 'base',
        displayName: baseName
      }
    }

    return null
  }

  // Track location changes
  useEffect(() => {
    const newPath = location.pathname
    const details = getEntityDetails(location.pathname, location.search)

    if (
      newPath === '/dashboard/production/gcodefiles' ||
      newPath === '/dashboard/management/filaments' ||
      newPath === '/dashboard/management/materials'
    ) {
      setNavigationHistory([
        {
          path: newPath + location.search,
          details,
          timestamp: new Date().toISOString()
        }
      ])
      setCurrentPosition(0)
    } else if (details) {
      setNavigationHistory((prev) => {
        const newHistory = prev.slice(0, currentPosition + 1)
        return [
          ...newHistory,
          {
            path: newPath + location.search,
            details,
            timestamp: new Date().toISOString()
          }
        ]
      })
      setCurrentPosition((prev) => prev + 1)
    }
  }, [location])

  const goBack = () => {
    if (currentPosition > 0) {
      setCurrentPosition((prev) => prev - 1)
      navigate(-1)
    }
  }

  const goForward = () => {
    if (currentPosition < navigationHistory.length - 1) {
      setCurrentPosition((prev) => prev + 1)
      navigate(1)
    }
  }

  const getBreadcrumbItems = () => {
    // If there's no history, return empty array
    if (navigationHistory.length === 0) return []

    // Get current location
    const currentItem = navigationHistory[currentPosition]
    if (!currentItem) return []

    const pathParts = currentItem.path.split('/')
    const breadcrumbs = []

    // Build up breadcrumbs including parent routes
    if (pathParts[1]) {
      // First level (e.g. /production or /management)
      const firstLevelPath = '/' + pathParts[1]
      breadcrumbs.push({
        path: firstLevelPath,
        title: baseRouteNames[firstLevelPath]
      })
    }

    if (pathParts[2]) {
      // Second level (e.g. /dashboard/production/gcodefiles)
      const secondLevelPath =
        '/' + pathParts[1] + '/' + pathParts[2].split('?')[0]
      breadcrumbs.push({
        path: currentItem.path,
        title:
          baseRouteNames[secondLevelPath] || currentItem.details.displayName
      })
    }

    // Add the entity detail level if it exists (e.g. specific gcodefile, filament, etc)
    if (currentItem.details.type !== 'base') {
      breadcrumbs.push({
        path: currentItem.path,
        title: currentItem.details.displayName
      })
    }

    return breadcrumbs
  }

  const canGoBack = currentPosition > 0
  const canGoForward = currentPosition < navigationHistory.length - 1

  return (
    <HistoryContext.Provider
      value={{
        navigationHistory,
        currentPosition,
        goBack,
        goForward,
        canGoBack,
        canGoForward,
        getBreadcrumbItems
      }}
    >
      {children}
    </HistoryContext.Provider>
  )
}

export const useHistory = () => {
  const context = useContext(HistoryContext)
  if (!context) {
    throw new Error('useHistory must be used within a HistoryProvider')
  }
  return context
}

HistoryProvider.propTypes = {
  children: PropTypes.node.isRequired
}

export default HistoryContext
