import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import BaseInput from '@/components/BaseInput.vue'

describe('BaseInput', () => {
  it('renders with label and default empty value', () => {
    const wrapper = mount(BaseInput, { props: { label: 'Name' } })
    expect(wrapper.find('label').text()).toBe('Name')
    expect((wrapper.find('input').element as HTMLInputElement).value).toBe('')
    expect(wrapper.find('.input-wrap--filled').exists()).toBe(false)
  })

  it('binds modelValue and emits update:modelValue on input', async () => {
    const wrapper = mount(BaseInput, { props: { label: 'Name', modelValue: 'Bob' } })
    const input = wrapper.find('input')
    expect((input.element as HTMLInputElement).value).toBe('Bob')

    await input.setValue('Alice')
    expect(wrapper.emitted('update:modelValue')).toBeTruthy()
    expect(wrapper.emitted('update:modelValue')![0]).toEqual(['Alice'])
  })

  it('marks .input-wrap--filled when modelValue is non-empty', () => {
    const wrapper = mount(BaseInput, { props: { label: 'Name', modelValue: 'x' } })
    expect(wrapper.find('.input-wrap--filled').exists()).toBe(true)
  })

  it('emits blur events', async () => {
    const wrapper = mount(BaseInput, { props: { label: 'Name' } })
    await wrapper.find('input').trigger('blur')
    expect(wrapper.emitted('blur')).toBeTruthy()
  })

  it('renders error message and applies error class when error is set', () => {
    const wrapper = mount(BaseInput, { props: { label: 'Name', error: 'Required' } })
    expect(wrapper.find('.input-wrap--error').exists()).toBe(true)
    expect(wrapper.find('.input-wrap__error').text()).toBe('Required')
    expect(wrapper.find('[role="alert"]').exists()).toBe(true)
  })

  it('honors a custom id and links the label via for=', () => {
    const wrapper = mount(BaseInput, { props: { label: 'Email', id: 'email' } })
    expect(wrapper.find('input').attributes('id')).toBe('email')
    expect(wrapper.find('label').attributes('for')).toBe('email')
  })

  it('uses a generated id when none is provided', () => {
    const wrapper = mount(BaseInput, { props: { label: 'Email' } })
    const id = wrapper.find('input').attributes('id')
    expect(id).toMatch(/^input-/)
    expect(wrapper.find('label').attributes('for')).toBe(id)
  })

  it('passes type prop down to the underlying input', () => {
    const wrapper = mount(BaseInput, { props: { label: 'Email', type: 'email' } })
    expect(wrapper.find('input').attributes('type')).toBe('email')
  })
})
