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

// Simple placeholder for slotted input content in tests
const TestInputComponent = {
  template: '<input id="test-input" type="text" />',
  props: ['id'], // Accept id if needed to match label's `for`
};

describe('VFormField.vue', () => {
  it('renders default slot content', () => {
    const wrapper = mount(VFormField, {
      slots: {
        default: '<input type="text" id="my-input" />',
      },
    });
    const input = wrapper.find('input[type="text"]');
    expect(input.exists()).toBe(true);
    expect(input.attributes('id')).toBe('my-input');
  });

  it('renders a label when label prop is provided', () => {
    const labelText = 'Username';
    const wrapper = mount(VFormField, {
      props: { label: labelText, forId: 'user-input' },
      slots: { default: '<input id="user-input" />' }
    });
    const label = wrapper.find('label');
    expect(label.exists()).toBe(true);
    expect(label.text()).toBe(labelText);
    expect(label.attributes('for')).toBe('user-input');
    expect(label.classes()).toContain('form-label');
  });

  it('does not render a label when label prop is not provided', () => {
    const wrapper = mount(VFormField, {
      slots: { default: '<input />' }
    });
    expect(wrapper.find('label').exists()).toBe(false);
  });

  it('renders an error message when errorMessage prop is provided', () => {
    const errorText = 'This field is required.';
    const wrapper = mount(VFormField, {
      props: { errorMessage: errorText },
      slots: { default: '<input />' }
    });
    const errorMessage = wrapper.find('.form-error-message');
    expect(errorMessage.exists()).toBe(true);
    expect(errorMessage.text()).toBe(errorText);
  });

  it('does not render an error message when errorMessage prop is not provided', () => {
    const wrapper = mount(VFormField, {
      slots: { default: '<input />' }
    });
    expect(wrapper.find('.form-error-message').exists()).toBe(false);
  });

  it('applies the forId prop to the label\'s "for" attribute', () => {
    const inputId = 'email-field';
    const wrapper = mount(VFormField, {
      props: { label: 'Email', forId: inputId },
      slots: { default: `<input id="${inputId}" />` }
    });
    const label = wrapper.find('label');
    expect(label.attributes('for')).toBe(inputId);
  });

  it('label "for" attribute is present even if forId is null or undefined, but empty', () => {
    // Vue typically removes attributes if their value is null/undefined.
    // Let's test the behavior. If forId is not provided, 'for' shouldn't be on the label.
    const wrapperNull = mount(VFormField, {
      props: { label: 'Test', forId: null },
      slots: { default: '<input />' }
    });
    const labelNull = wrapperNull.find('label');
    expect(labelNull.attributes('for')).toBeUndefined(); // Or it might be an empty string depending on Vue version/handling

    const wrapperUndefined = mount(VFormField, {
      props: { label: 'Test' }, // forId is undefined
      slots: { default: '<input />' }
    });
    const labelUndefined = wrapperUndefined.find('label');
    expect(labelUndefined.attributes('for')).toBeUndefined();
  });


  it('applies the .form-group class to the root element', () => {
    const wrapper = mount(VFormField, {
      slots: { default: '<input />' }
    });
    expect(wrapper.classes()).toContain('form-group');
  });

  it('renders label, input, and error message all together', () => {
    const wrapper = mount(VFormField, {
      props: {
        label: 'Password',
        forId: 'pass',
        errorMessage: 'Too short'
      },
      slots: {
        default: '<input type="password" id="pass" />'
      }
    });
    expect(wrapper.find('label').exists()).toBe(true);
    expect(wrapper.find('input[type="password"]').exists()).toBe(true);
    expect(wrapper.find('.form-error-message').exists()).toBe(true);
  });
});
