import {describe, expect, it, vi, beforeEach} from 'vitest'

import {useShopActions} from '../../internal/useShopActions'
import {render, screen, userEvent} from '../../test-utils'

import {TextInput} from './text-input'

vi.mock('../../internal/useShopActions', () => ({
  useShopActions: vi.fn(() => ({
    translateContentUp: vi.fn(),
    translateContentDown: vi.fn(),
  })),
}))

describe('TextInput', () => {
  let mockTranslateContentUp: ReturnType<typeof vi.fn>
  let mockTranslateContentDown: ReturnType<typeof vi.fn>

  beforeEach(() => {
    vi.clearAllMocks()

    mockTranslateContentUp = vi.fn()
    mockTranslateContentDown = vi.fn()
    ;(useShopActions as ReturnType<typeof vi.fn>).mockReturnValue({
      translateContentUp: mockTranslateContentUp,
      translateContentDown: mockTranslateContentDown,
    })
  })

  it('forwards all input props correctly', () => {
    render(
      <TextInput
        placeholder="Test input"
        value="test value"
        disabled
        type="email"
        className="custom-class"
        id="test-input"
      />
    )

    const input = screen.getByPlaceholderText('Test input')
    expect(input).toHaveValue('test value')
    expect(input).toBeDisabled()
    expect(input).toHaveAttribute('type', 'email')
    expect(input).toHaveClass('custom-class')
    expect(input).toHaveAttribute('id', 'test-input')

    expect(input).toBeInstanceOf(HTMLInputElement)
    expect(input.tagName).toBe('INPUT')
  })

  it('calls translateContentUp on focus', async () => {
    const user = userEvent.setup()

    render(<TextInput placeholder="Test input" />)

    const input = screen.getByPlaceholderText('Test input')

    await user.click(input)

    expect(mockTranslateContentUp).toHaveBeenCalledTimes(1)
  })

  it('calls translateContentDown on blur', async () => {
    const user = userEvent.setup()

    render(<TextInput placeholder="Test input" />)

    const input = screen.getByPlaceholderText('Test input')

    await user.click(input)
    await user.tab()

    expect(mockTranslateContentDown).toHaveBeenCalledTimes(1)
  })

  it('calls custom onFocus handler when provided', async () => {
    const user = userEvent.setup()
    const customOnFocus = vi.fn()

    render(<TextInput placeholder="Test input" onFocus={customOnFocus} />)

    const input = screen.getByPlaceholderText('Test input')
    await user.click(input)

    expect(customOnFocus).toHaveBeenCalledTimes(1)
  })

  it('calls custom onBlur handler when provided', async () => {
    const user = userEvent.setup()
    const customOnBlur = vi.fn()

    render(<TextInput placeholder="Test input" onBlur={customOnBlur} />)

    const input = screen.getByPlaceholderText('Test input')

    // Focus first, then blur
    await user.click(input)
    await user.tab()

    expect(customOnBlur).toHaveBeenCalledTimes(1)
  })
})
