import { describe, it, expect } from 'vitest'
import React from 'react'
import { render, screen } from '@testing-library/react-native'
import { Text } from 'react-native'
import { OnboardingStep } from '@/src/shared/components/OnboardingStep'

/**
 * Helper to recursively find a node in the rendered tree by its element type name.
 * Returns the first match or null.
 */
function findByType(tree: any, typeName: string): any {
  if (!tree) return null
  if (tree.type === typeName) return tree
  if (tree.children && Array.isArray(tree.children)) {
    for (const child of tree.children) {
      if (typeof child === 'object') {
        const found = findByType(child, typeName)
        if (found) return found
      }
    }
  }
  return null
}

/**
 * Helper to count nodes of a given type in the tree
 */
function countByType(tree: any, typeName: string): number {
  if (!tree) return 0
  let count = tree.type === typeName ? 1 : 0
  if (tree.children && Array.isArray(tree.children)) {
    for (const child of tree.children) {
      if (typeof child === 'object') {
        count += countByType(child, typeName)
      }
    }
  }
  return count
}

describe('OnboardingStep', () => {
  it('renders children', () => {
    render(
      <OnboardingStep step={1} totalSteps={6}>
        <Text testID="child-content">Welcome</Text>
      </OnboardingStep>
    )
    expect(screen.getByTestId('child-content')).toBeTruthy()
  })

  it('renders progress bar with track and fill Views', () => {
    const { toJSON } = render(
      <OnboardingStep step={1} totalSteps={6}>
        <Text>Step 1</Text>
      </OnboardingStep>
    )
    const tree = toJSON()
    // OnboardingStep should have:
    // - A root View (container)
    //   - A View (progressTrack)
    //     - An Animated.View (progressFill) — rendered as View by mock
    //   - An Animated.View (content wrapper)
    expect(tree).toBeTruthy()
    expect(tree?.type).toBe('View') // root container
    expect(tree?.children).toBeDefined()
    expect(tree!.children!.length).toBeGreaterThanOrEqual(2) // progress track + content
  })

  it('step 1 of 6 snapshot', () => {
    const { toJSON } = render(
      <OnboardingStep step={1} totalSteps={6}>
        <Text>First step</Text>
      </OnboardingStep>
    )
    expect(toJSON()).toMatchSnapshot()
  })

  it('step 6 of 6 (final step) snapshot', () => {
    const { toJSON } = render(
      <OnboardingStep step={6} totalSteps={6}>
        <Text>Final step</Text>
      </OnboardingStep>
    )
    expect(toJSON()).toMatchSnapshot()
  })

  it('renders multiple children inside content area', () => {
    render(
      <OnboardingStep step={3} totalSteps={6}>
        <Text testID="title">Title</Text>
        <Text testID="description">Description</Text>
      </OnboardingStep>
    )
    expect(screen.getByTestId('title')).toBeTruthy()
    expect(screen.getByTestId('description')).toBeTruthy()
  })

  it('does not crash with step 0 (edge case snapshot)', () => {
    const { toJSON } = render(
      <OnboardingStep step={0} totalSteps={6}>
        <Text>Edge case</Text>
      </OnboardingStep>
    )
    // Should render without error — snapshot captures structure
    expect(toJSON()).toMatchSnapshot()
  })

  it('container uses safe area top inset for paddingTop', () => {
    const { toJSON } = render(
      <OnboardingStep step={1} totalSteps={6}>
        <Text>Check padding</Text>
      </OnboardingStep>
    )
    const tree = toJSON()
    // Root container should have paddingTop accounting for safe area (mock returns top=47)
    const rootStyle = tree?.props?.style
    const flatStyles = Array.isArray(rootStyle) ? rootStyle : [rootStyle]
    const hasPaddingTop = flatStyles.some(
      (s: any) => s && typeof s === 'object' && typeof s.paddingTop === 'number' && s.paddingTop > 0
    )
    expect(hasPaddingTop).toBe(true)
  })
})
