import { useMemo, useCallback } from 'react'
import { Routes, Route, Navigate, useNavigate } from 'react-router-dom'
import { Dashboard } from './pages/Dashboard/Dashboard'
import { Metrics } from './pages/Metrics/Metrics'
import { RouteDetail } from './pages/RouteDetail/RouteDetail'
import { ExchangeDetail } from './pages/ExchangeDetail/ExchangeDetail'
import { AgentHealth } from './pages/AgentHealth/AgentHealth'
import { Inventory } from './pages/Inventory/Inventory'
import { Admin } from './pages/Admin/Admin'
import { ApiDocs } from './pages/ApiDocs/ApiDocs'

import { CommandPalette } from './design-system/composites/CommandPalette/CommandPalette'
import type { SearchResult } from './design-system/composites/CommandPalette/types'
import { useCommandPalette } from './design-system/providers/CommandPaletteProvider'
import { useGlobalFilters } from './design-system/providers/GlobalFilterProvider'
import { buildSearchData } from './mocks/searchData'
import { exchanges } from './mocks/exchanges'
import { routes } from './mocks/routes'
import { agents } from './mocks/agents'
import { SIDEBAR_APPS } from './mocks/sidebar'

/** Compute which sidebar path to reveal for a given search result */
function computeSidebarRevealPath(result: SearchResult): string | undefined {
  if (!result.path) return undefined

  if (result.category === 'application') {
    // /apps/:id — already a sidebar node path
    return result.path
  }

  if (result.category === 'route') {
    // /routes/:id — already a sidebar node path
    return result.path
  }

  if (result.category === 'agent') {
    // /agents/:appId/:agentId — already a sidebar node path
    return result.path
  }

  if (result.category === 'exchange') {
    // /exchanges/:id — no sidebar entry; resolve to the parent route
    const exchange = exchanges.find((e) => e.id === result.id)
    if (exchange) {
      return `/routes/${exchange.route}`
    }
  }

  return result.path
}

export default function App() {
  const navigate = useNavigate()
  const { open: paletteOpen, setOpen } = useCommandPalette()
  const { isInTimeRange, statusFilters } = useGlobalFilters()

  const filteredSearchData = useMemo(() => {
    // Filter exchanges by time range and status
    let filteredExchanges = exchanges.filter((e) => isInTimeRange(e.timestamp))
    if (statusFilters.size > 0) {
      filteredExchanges = filteredExchanges.filter((e) => statusFilters.has(e.status))
    }
    return buildSearchData(filteredExchanges, routes, agents)
  }, [isInTimeRange, statusFilters])

  const handleSelect = useCallback(
    (result: SearchResult) => {
      if (result.path) {
        const sidebarReveal = computeSidebarRevealPath(result)
        navigate(result.path, { state: sidebarReveal ? { sidebarReveal } : undefined })
      }
      setOpen(false)
    },
    [navigate, setOpen],
  )

  return (
    <>
      <Routes>
        <Route path="/" element={<Navigate to="/apps" replace />} />
        <Route path="/apps" element={<Dashboard />} />
        <Route path="/apps/:id" element={<Dashboard />} />
        <Route path="/metrics" element={<Metrics />} />
        <Route path="/routes/:id" element={<RouteDetail />} />
        <Route path="/exchanges/:id" element={<ExchangeDetail />} />
        <Route path="/agents/*" element={<AgentHealth />} />
        <Route path="/admin" element={<Admin />} />
        <Route path="/api-docs" element={<ApiDocs />} />
        <Route path="/inventory" element={<Inventory />} />
      </Routes>
      <CommandPalette
        open={paletteOpen}
        onClose={() => setOpen(false)}
        onOpen={() => setOpen(true)}
        data={filteredSearchData}
        onSelect={handleSelect}
      />
    </>
  )
}
