/**
 * Tests for useStickyTabs hook
 *
 * Note: Due to jest.setup.js configuration issues with react-native mocks,
 * we test the core sticky tabs logic directly instead of using renderHook.
 */

// Re-implement the sticky tabs logic for testing
interface StickyTabsState {
  isSticky: boolean
  tabsHeight: number
  tabsPositionRef: { current: number }
  titleBarHeightRef: { current: number }
}

function createStickyTabsState(): StickyTabsState {
  return {
    isSticky: false,
    tabsHeight: 0,
    tabsPositionRef: { current: 0 },
    titleBarHeightRef: { current: 0 },
  }
}

function handleScroll(
  state: StickyTabsState,
  scrollY: number,
  setIsSticky: (value: boolean) => void
): void {
  if (scrollY > state.tabsPositionRef.current) {
    if (!state.isSticky) {
      setIsSticky(true)
    }
  } else {
    if (state.isSticky) {
      setIsSticky(false)
    }
  }
}

function handleTabsLayout(
  state: StickyTabsState,
  y: number,
  height: number,
  setTabsHeight: (value: number) => void
): void {
  state.tabsPositionRef.current = y
  setTabsHeight(height)
}

function handleTitleBarLayout(
  state: StickyTabsState,
  height: number
): void {
  state.titleBarHeightRef.current = height
}

describe('useStickyTabs - sticky tabs logic', () => {
  describe('initial state', () => {
    it('should have isSticky as false initially', () => {
      const state = createStickyTabsState()
      expect(state.isSticky).toBe(false)
    })

    it('should have tabsHeight as 0 initially', () => {
      const state = createStickyTabsState()
      expect(state.tabsHeight).toBe(0)
    })

    it('should have tabsPositionRef.current as 0 initially', () => {
      const state = createStickyTabsState()
      expect(state.tabsPositionRef.current).toBe(0)
    })

    it('should have titleBarHeightRef.current as 0 initially', () => {
      const state = createStickyTabsState()
      expect(state.titleBarHeightRef.current).toBe(0)
    })
  })

  describe('handleScroll', () => {
    it('should set isSticky to true when scrollY exceeds tabsPosition', () => {
      const state = createStickyTabsState()
      state.tabsPositionRef.current = 100
      let newIsSticky = state.isSticky

      handleScroll(state, 150, (value) => {
        newIsSticky = value
      })

      expect(newIsSticky).toBe(true)
    })

    it('should set isSticky to false when scrollY is below tabsPosition', () => {
      const state = createStickyTabsState()
      state.isSticky = true
      state.tabsPositionRef.current = 100
      let newIsSticky = state.isSticky

      handleScroll(state, 50, (value) => {
        newIsSticky = value
      })

      expect(newIsSticky).toBe(false)
    })

    it('should not call setIsSticky when already sticky and scrollY exceeds tabsPosition', () => {
      const state = createStickyTabsState()
      state.isSticky = true
      state.tabsPositionRef.current = 100
      let callCount = 0

      handleScroll(state, 150, () => {
        callCount++
      })

      expect(callCount).toBe(0)
    })

    it('should not call setIsSticky when not sticky and scrollY is below tabsPosition', () => {
      const state = createStickyTabsState()
      state.isSticky = false
      state.tabsPositionRef.current = 100
      let callCount = 0

      handleScroll(state, 50, () => {
        callCount++
      })

      expect(callCount).toBe(0)
    })

    it('should handle edge case when scrollY equals tabsPosition', () => {
      const state = createStickyTabsState()
      state.isSticky = true
      state.tabsPositionRef.current = 100
      let newIsSticky = state.isSticky

      handleScroll(state, 100, (value) => {
        newIsSticky = value
      })

      // scrollY (100) is not greater than tabsPosition (100), so should become false
      expect(newIsSticky).toBe(false)
    })
  })

  describe('handleTabsLayout', () => {
    it('should update tabsPositionRef with y value', () => {
      const state = createStickyTabsState()

      handleTabsLayout(state, 200, 50, () => {})

      expect(state.tabsPositionRef.current).toBe(200)
    })

    it('should call setTabsHeight with height value', () => {
      const state = createStickyTabsState()
      let newTabsHeight = 0

      handleTabsLayout(state, 200, 50, (value) => {
        newTabsHeight = value
      })

      expect(newTabsHeight).toBe(50)
    })

    it('should handle zero values', () => {
      const state = createStickyTabsState()
      let newTabsHeight = 100

      handleTabsLayout(state, 0, 0, (value) => {
        newTabsHeight = value
      })

      expect(state.tabsPositionRef.current).toBe(0)
      expect(newTabsHeight).toBe(0)
    })
  })

  describe('handleTitleBarLayout', () => {
    it('should update titleBarHeightRef with height value', () => {
      const state = createStickyTabsState()

      handleTitleBarLayout(state, 64)

      expect(state.titleBarHeightRef.current).toBe(64)
    })

    it('should handle zero height', () => {
      const state = createStickyTabsState()
      state.titleBarHeightRef.current = 100

      handleTitleBarLayout(state, 0)

      expect(state.titleBarHeightRef.current).toBe(0)
    })
  })

  describe('multiple scroll events', () => {
    it('should only trigger state change on actual transitions', () => {
      const state = createStickyTabsState()
      state.tabsPositionRef.current = 100
      let callCount = 0
      const setIsSticky = (value: boolean) => {
        callCount++
        state.isSticky = value
      }

      // Initial scroll past threshold - should trigger
      handleScroll(state, 150, setIsSticky)
      expect(callCount).toBe(1)
      expect(state.isSticky).toBe(true)

      // Another scroll past threshold - should NOT trigger
      handleScroll(state, 200, setIsSticky)
      expect(callCount).toBe(1)

      // Scroll back below threshold - should trigger
      handleScroll(state, 50, setIsSticky)
      expect(callCount).toBe(2)
      expect(state.isSticky).toBe(false)

      // Another scroll below threshold - should NOT trigger
      handleScroll(state, 30, setIsSticky)
      expect(callCount).toBe(2)
    })
  })
})
