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

describe('MField component', () => {
  it('renders the label and associates it with the correct id', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'username',
        label: 'Username',
      },
    });

    const label = wrapper.find('.mc-field__label');
    expect(label.exists()).toBe(true);
    expect(label.text()).toContain('Username');
    expect(label.attributes('for')).toBe('username');
  });

  it('renders the requirement text when provided', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'email',
        label: 'Email',
        requirementText: 'required',
      },
    });

    const requirement = wrapper.find('.mc-field__requirement');
    expect(requirement.exists()).toBe(true);
    expect(requirement.text()).toContain('(required)');
  });

  it('does not render requirement text when not provided', () => {
    const wrapper = mount(MField, {
      props: { id: 'email', label: 'Email' },
    });

    const requirement = wrapper.find('.mc-field__requirement');
    expect(requirement.exists()).toBe(false);
  });

  it('renders help text when helpId and helpText are provided', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'password',
        label: 'Password',
        helpText: 'At least 8 characters.',
        helpId: 'password-help',
      },
    });

    const help = wrapper.find('.mc-field__help');
    expect(help.exists()).toBe(true);
    expect(help.attributes('id')).toBe('password-help');
    expect(help.text()).toBe('At least 8 characters.');
  });

  it('does not render help text if helpId or helpText is missing', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'password',
        label: 'Password',
        helpText: 'Help text',
      },
    });

    const help = wrapper.find('.mc-field__help');
    expect(help.exists()).toBe(false);
  });

  it('renders slot content inside .mc-field__content', () => {
    const wrapper = mount(MField, {
      props: { id: 'field1', label: 'Field Label' },
      slots: { default: '<input id="field1" />' },
    });

    const content = wrapper.find('.mc-field__content');
    expect(content.exists()).toBe(true);
    expect(content.find('input').exists()).toBe(true);
  });

  it('renders validation message when message and valid state are provided', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'email',
        label: 'Email',
        isValid: true,
        messageId: 'msg1',
        message: 'Looks good!',
      },
    });

    const message = wrapper.find('.mc-field__validation-message');
    expect(message.exists()).toBe(true);
    expect(message.attributes('id')).toBe('msg1');
    expect(message.text()).toContain('Looks good!');
    expect(message.classes()).toContain('is-valid');
  });

  it('renders validation message when invalid', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'email',
        label: 'Email',
        isInvalid: true,
        messageId: 'msg2',
        message: 'Invalid email address.',
      },
    });

    const message = wrapper.find('.mc-field__validation-message');
    expect(message.exists()).toBe(true);
    expect(message.text()).toContain('Invalid email address.');
    expect(message.classes()).toContain('is-invalid');
  });

  it('renders loader and message when loading', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'loadingField',
        label: 'Loading Label',
        isLoading: true,
        messageId: 'loading-msg',
        message: 'Loading...',
      },
    });

    const message = wrapper.find('.mc-field__validation-message');
    expect(message.exists()).toBe(true);
    expect(message.classes()).toContain('is-loading');

    const loader = wrapper.findComponent(MLoader);
    expect(loader.exists()).toBe(true);
    expect(loader.props('size')).toBe('xs');
  });

  it('does not render validation message when no state (valid/invalid/loading)', () => {
    const wrapper = mount(MField, {
      props: {
        id: 'email',
        label: 'Email',
        messageId: 'msg3',
        message: 'Message without state',
      },
    });

    const message = wrapper.find('.mc-field__validation-message');
    expect(message.exists()).toBe(false);
  });

  it('renders multiple validation states correctly', async () => {
    const wrapper = mount(MField, {
      props: {
        id: 'stateField',
        label: 'Field',
        messageId: 'msg4',
        message: 'State message',
        isValid: true,
      },
    });

    let message = wrapper.find('.mc-field__validation-message');
    expect(message.classes()).toContain('is-valid');

    await wrapper.setProps({ isValid: false, isInvalid: true });
    message = wrapper.find('.mc-field__validation-message');
    expect(message.classes()).toContain('is-invalid');

    await wrapper.setProps({ isInvalid: false, isLoading: true });
    message = wrapper.find('.mc-field__validation-message');
    expect(message.classes()).toContain('is-loading');
  });
});
