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

describe('VInput.vue', () => {
  it('binds modelValue and emits update:modelValue correctly (v-model)', async () => {
    const wrapper = mount(VInput, {
      props: { modelValue: 'initial text' },
    });
    const inputElement = wrapper.find('input');

    // Check initial value
    expect(inputElement.element.value).toBe('initial text');

    // Simulate user input
    await inputElement.setValue('new text');

    // Check emitted event
    expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
    expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['new text']);

    // Check that prop update (simulating parent v-model update) changes the value
    await wrapper.setProps({ modelValue: 'updated from parent' });
    expect(inputElement.element.value).toBe('updated from parent');
  });

  it('sets the input type correctly', () => {
    const wrapper = mount(VInput, {
      props: { modelValue: '', type: 'password' },
    });
    expect(wrapper.find('input').attributes('type')).toBe('password');
  });

  it('defaults type to "text" if not provided', () => {
    const wrapper = mount(VInput, { props: { modelValue: '' } });
    expect(wrapper.find('input').attributes('type')).toBe('text');
  });

  it('applies placeholder when provided', () => {
    const placeholderText = 'Enter here';
    const wrapper = mount(VInput, {
      props: { modelValue: '', placeholder: placeholderText },
    });
    expect(wrapper.find('input').attributes('placeholder')).toBe(placeholderText);
  });

  it('is disabled when disabled prop is true', () => {
    const wrapper = mount(VInput, {
      props: { modelValue: '', disabled: true },
    });
    expect(wrapper.find('input').attributes('disabled')).toBeDefined();
  });

  it('is not disabled by default', () => {
    const wrapper = mount(VInput, { props: { modelValue: '' } });
    expect(wrapper.find('input').attributes('disabled')).toBeUndefined();
  });

  it('is required when required prop is true', () => {
    const wrapper = mount(VInput, {
      props: { modelValue: '', required: true },
    });
    expect(wrapper.find('input').attributes('required')).toBeDefined();
  });

  it('is not required by default', () => {
    const wrapper = mount(VInput, { props: { modelValue: '' } });
    expect(wrapper.find('input').attributes('required')).toBeUndefined();
  });

  it('applies error class when error prop is true', () => {
    const wrapper = mount(VInput, {
      props: { modelValue: '', error: true },
    });
    expect(wrapper.find('input').classes()).toContain('form-input');
    expect(wrapper.find('input').classes()).toContain('error');
  });

  it('does not apply error class by default or when error is false', () => {
    const wrapperDefault = mount(VInput, { props: { modelValue: '' } });
    expect(wrapperDefault.find('input').classes()).toContain('form-input');
    expect(wrapperDefault.find('input').classes()).not.toContain('error');

    const wrapperFalse = mount(VInput, {
      props: { modelValue: '', error: false },
    });
    expect(wrapperFalse.find('input').classes()).toContain('form-input');
    expect(wrapperFalse.find('input').classes()).not.toContain('error');
  });

  it('sets aria-invalid attribute when error prop is true', () => {
    const wrapper = mount(VInput, {
      props: { modelValue: '', error: true },
    });
    expect(wrapper.find('input').attributes('aria-invalid')).toBe('true');
  });

  it('does not set aria-invalid attribute by default or when error is false', () => {
    const wrapperDefault = mount(VInput, { props: { modelValue: '' } });
    expect(wrapperDefault.find('input').attributes('aria-invalid')).toBeNull(); // Or undefined

    const wrapperFalse = mount(VInput, {
      props: { modelValue: '', error: false },
    });
    expect(wrapperFalse.find('input').attributes('aria-invalid')).toBeNull(); // Or undefined
  });

  it('passes id prop to the input element', () => {
    const inputId = 'my-custom-id';
    const wrapper = mount(VInput, {
      props: { modelValue: '', id: inputId },
    });
    expect(wrapper.find('input').attributes('id')).toBe(inputId);
  });

  it('does not have an id attribute if id prop is not provided', () => {
    const wrapper = mount(VInput, { props: { modelValue: '' } });
    expect(wrapper.find('input').attributes('id')).toBeUndefined();
  });
});
