import * as React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import { CStepper } from '../index'

const stepsMock = [
  { label: 'Step 1', content: <div>Content 1</div> },
  { label: 'Step 2', content: <div>Content 2</div> },
  { label: 'Step 3', content: <div>Content 3</div> },
]

test('loads and displays CStepper component', async () => {
  const { container } = render(<CStepper steps={stepsMock} />)
  expect(container).toMatchSnapshot()
})

test('CStepper renders vertical layout', async () => {
  const { container } = render(<CStepper steps={stepsMock} layout="vertical" />)
  expect(container).toMatchSnapshot()
})

test('CStepper disables future steps in linear mode', async () => {
  render(<CStepper steps={stepsMock} linear={true} />)

  const buttons = screen.getAllByRole('tab')
  expect(buttons[0]).toBeEnabled()
  expect(buttons[1]).toBeDisabled()
  expect(buttons[2]).toBeDisabled()
})

test('CStepper allows all steps in non-linear mode', async () => {
  render(<CStepper steps={stepsMock} linear={false} />)

  const buttons = screen.getAllByRole('tab')
  expect(buttons[0]).toBeEnabled()
  expect(buttons[1]).toBeEnabled()
  expect(buttons[2]).toBeEnabled()
})

test('CStepper calls onStepChange when step is clicked', async () => {
  const handleStepChange = jest.fn()
  render(<CStepper steps={stepsMock} linear={false} onStepChange={handleStepChange} />)

  const buttons = screen.getAllByRole('tab')
  fireEvent.click(buttons[2])

  expect(handleStepChange).toHaveBeenCalledWith(3) // stepNumber = index + 1
})

test('CStepper renders only active step content in horizontal layout', async () => {
  render(<CStepper steps={stepsMock} layout="horizontal" />)

  expect(screen.getByText('Content 1')).toBeVisible()
  expect(screen.queryByText('Content 2')).not.toBeInTheDocument()
  expect(screen.queryByText('Content 3')).not.toBeInTheDocument()
})

test('CStepper finish calls onFinish only after last step and valid', async () => {
  const handleFinish = jest.fn()
  render(<CStepper steps={stepsMock} onFinish={handleFinish} linear={false} />)

  const buttons = screen.getAllByRole('tab')
  fireEvent.click(buttons[2])

  fireEvent.click(screen.getByText('Step 3'))
  expect(handleFinish).toHaveBeenCalledTimes(1)
})

test('CStepper resets correctly and focuses first step', async () => {
  const handleReset = jest.fn()
  const stepperRef = React.createRef<any>()

  render(<CStepper ref={stepperRef} steps={stepsMock} onReset={handleReset} />)

  stepperRef.current?.next()
  stepperRef.current?.reset()

  expect(handleReset).toHaveBeenCalled()
  expect(screen.getAllByRole('tab')[0]).toHaveFocus()
})

test('CStepper works in uncontrolled mode with defaultActiveStepIndex', async () => {
  render(<CStepper steps={stepsMock} defaultActiveStepIndex={1} />)

  expect(screen.getByText('Content 2')).toBeVisible()
  expect(screen.queryByText('Content 1')).not.toBeInTheDocument()
})

test('CStepper works in controlled mode with activeStepIndex', async () => {
  const { rerender } = render(<CStepper steps={stepsMock} activeStepIndex={0} />)

  expect(screen.getByText('Content 1')).toBeVisible()

  rerender(<CStepper steps={stepsMock} activeStepIndex={2} />)

  expect(screen.getByText('Content 3')).toBeVisible()
  expect(screen.queryByText('Content 1')).not.toBeInTheDocument()
})
