import { useSegments } from 'expo-router'
import { useMemo } from 'react'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useTheme, View, XStack } from 'tamagui'
import { useA11yFlags, useKeyboardVisible } from './hooks'
import { placeIntents, type SearchIntent } from './intents'
import { ICON_SIZE, ICON_SIZE_BOLD, MenuBarFloating, MenuSurfacePill } from './MenuBar'
import { useActiveMenuEntry } from './MenuStore'
import { RenderAct, RenderCommit } from './render/renderAct'
import { RenderBack } from './render/renderBack'
import { RenderFilter } from './render/renderFilter'
import { RenderMenu } from './render/renderMenu'
import { RenderNav } from './render/renderNav'
import { RenderSearchField, RenderSearchToggle } from './render/renderSearch'
import { RenderTitle } from './render/renderTitle'

// MenuBarToolbar — root-level fallback for non-tab routes (post/[id],
// settings/**, chats/conversation/**, ...). Inside the tabs navigator the
// unified bar takes over and this component short-circuits to null.

export function MenuBarToolbar() {
  const entry = useActiveMenuEntry()
  const insets = useSafeAreaInsets()
  const theme = useTheme()
  const keyboardVisible = useKeyboardVisible()
  const segments = useSegments()
  const a11y = useA11yFlags()

  const placed = useMemo(() => (entry ? placeIntents(entry.spec.intents) : null), [entry])

  // Inside the tabs navigator, MenuBarUnified owns the bar. This one only
  // renders on non-tab routes to stop the bar from disappearing on detail
  // screens.
  const onTabRoute = segments.some((s) => s === '(tabs)')
  if (onTabRoute) return null

  if (!entry || !placed) return null

  const { spec, searchActive, toggleSearch } = entry
  const { back, filter, search, trailing, commit, menu } = placed

  const hasAny =
    !!back ||
    !!filter ||
    !!search ||
    trailing.length > 0 ||
    !!commit ||
    !!menu ||
    !!spec.title
  if (!hasAny) return null

  // Sit at the bottom safe-area edge — no tab row on detail routes.
  const bottomOffset = insets.bottom + 8

  // Hide while the keyboard is up unless search is expanded OR the current
  // search intent opts in to staying visible.
  const keepOnKeyboard = !!search?.keepVisibleOnKeyboard
  if (keyboardVisible && !searchActive && !keepOnKeyboard) return null

  const showSearchField = !!search && searchActive && search.mode === 'inline'
  const surface = a11y.reduceTransparency ? 'solid' : 'translucent'
  // Detail-route toolbars share the unified bar's muted-chrome tint — see
  // the ContextRow comment in MenuBarUnified.tsx for rationale.
  const tint = theme.onSurfaceMuted.val as string
  const size = a11y.boldText ? ICON_SIZE_BOLD : ICON_SIZE

  // Hug the surface unless a title occupies the middle slot — titles render
  // inside a `flexGrow: 1` centered view and need a stretched pill to sit in.
  // A filter alone hugs to its content, mirroring MenuBarUnified's ContextRow
  // which always pairs `hug compact` with a right-justify wrapper.
  const hug = !showSearchField && !spec.title

  const pill = (
    <MenuSurfacePill surface={surface} hug={hug}>
      {back ? (
        <RenderBack
          intent={back}
          reduceMotion={a11y.reduceMotion}
          size={size}
          tint={tint}
        />
      ) : null}

      {showSearchField && search ? (
        <RenderSearchField
          intent={search}
          onClose={toggleSearch}
          reduceMotion={a11y.reduceMotion}
          size={size}
          tint={tint}
        />
      ) : (
        <>
          <MiddleSlot
            title={spec.title}
            filter={placed.filter}
            boldText={a11y.boldText}
          />

          {search ? (
            <RenderSearchToggle
              intent={search}
              onToggle={toggleSearch}
              reduceMotion={a11y.reduceMotion}
              size={size}
              tint={tint}
            />
          ) : null}

          {trailing.length > 0 ? (
            <XStack gap="$1">
              {trailing.map((item) =>
                item.kind === 'act' ? (
                  <RenderAct
                    key={item.id}
                    intent={item}
                    reduceMotion={a11y.reduceMotion}
                    size={size}
                    tint={tint}
                  />
                ) : (
                  <RenderNav
                    key={item.id ?? item.label}
                    intent={item}
                    reduceMotion={a11y.reduceMotion}
                    size={size}
                    tint={tint}
                  />
                )
              )}
            </XStack>
          ) : null}

          {menu ? (
            <RenderMenu
              intent={menu}
              reduceMotion={a11y.reduceMotion}
              boldText={a11y.boldText}
            />
          ) : null}

          {commit ? (
            <RenderCommit
              intent={commit}
              reduceMotion={a11y.reduceMotion}
              boldText={a11y.boldText}
            />
          ) : null}
        </>
      )}
    </MenuSurfacePill>
  )

  return (
    <MenuBarFloating bottom={bottomOffset}>
      {hug ? <XStack justifyContent="flex-end">{pill}</XStack> : pill}
    </MenuBarFloating>
  )
}

function MiddleSlot({
  title,
  filter,
  boldText,
}: {
  title?: string
  filter?: ReturnType<typeof placeIntents>['filter']
  boldText?: boolean
}) {
  if (filter) {
    return <RenderFilter intent={filter} boldText={boldText} />
  }
  if (title) {
    return (
      <View flexGrow={1} flexShrink={1} alignItems="center" justifyContent="center">
        <RenderTitle title={title} boldText={boldText} />
      </View>
    )
  }
  return null
}

// Re-exported for type inference on render props.
export type { SearchIntent }
