import { useSegments } from 'expo-router'
import { useMemo } from 'react'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { BAR_HEIGHT } from 'src/components/menu/MenuBar'
import { TAB_BAR_HEIGHT } from 'src/components/menu/tabBarMetrics'

// Bottom-offset reserve applied below the menu bar — a 16-pt gap so the last
// item never sits flush under the floating pill.
const BOTTOM_GAP = 16

// Minimum top reserve on routes without an explicit header. The floating
// context pill on tab routes sits inset.top + 8 above the tab strip — content
// sliding under it needs at least the safe-area inset.
export type ScreenScrollInsetsInput = {
  // Extra height consumed by a sticky page header rendered above the content.
  // The hook adds this to the top inset so content starts below the header.
  headerHeight?: number
}

export type ScreenScrollInsets = {
  contentInsetAdjustmentBehavior: 'never'
  // Kept in the shape for spread compatibility; always zeroed. See the hook
  // body for why iOS no longer uses native contentInset.
  contentInset: { top: number; bottom: number }
  scrollIndicatorInsets: { top: number; bottom: number }
  // Top/bottom reserve is applied uniformly via contentContainerStyle padding
  // on both platforms. This stays reactive to inset changes (rotation,
  // dynamic type, provider remount) instead of getting baked into the iOS
  // UIScrollView at mount.
  contentContainerStyle: { paddingTop: number; paddingBottom: number }
  // Raw values for consumers that can't take the spread — e.g.
  // `progressViewOffset` on RefreshControl, inline headers, or non-scrollable
  // wrappers.
  topInset: number
  bottomInset: number
}

// Central scroller-layout math for Batch B's screen shell. Returns the set
// of props a FlashList / ScrollView / animated list needs to (a) start its
// content below the safe-area / sticky header, (b) scroll underneath that
// header on iOS, (c) leave room at the bottom for the floating menu pill
// and tab strip.
//
// Tab routes add the tab-strip height; detail / settings routes leave it out
// so settings pages don't reserve dead space beneath their last row.
export function useScreenScrollInsets({
  headerHeight = 0,
}: ScreenScrollInsetsInput = {}): ScreenScrollInsets {
  const insets = useSafeAreaInsets()
  const segments = useSegments()
  const onTabRoute = segments.some((s) => s === '(tabs)')

  return useMemo(() => {
    const topInset = insets.top + headerHeight
    const bottomInset =
      insets.bottom + BAR_HEIGHT + (onTabRoute ? TAB_BAR_HEIGHT : 0) + BOTTOM_GAP

    // Uniform padding on both platforms. iOS's native `contentInset` is
    // baked into the UIScrollView at mount — any inset change after first
    // paint (rotation, dynamic type, late-arriving SafeAreaProvider metrics)
    // is silently ignored. `contentContainerStyle` stays reactive, and the
    // absolute-positioned StickyHeader still gets the scroll-under effect
    // because content scrolls up behind it in the same stacking context.
    // `scrollIndicatorInsets` is kept so the vertical indicator still avoids
    // the header on iOS.
    return {
      contentInsetAdjustmentBehavior: 'never' as const,
      contentInset: { top: 0, bottom: 0 },
      scrollIndicatorInsets: { top: topInset, bottom: bottomInset },
      contentContainerStyle: {
        paddingTop: topInset,
        paddingBottom: bottomInset,
      },
      topInset,
      bottomInset,
    }
  }, [insets.top, insets.bottom, headerHeight, onTabRoute])
}
