import { mount } from '@vue/test-utils';
import { describe, it, expect } from 'vitest';
import MButton from './MButton.vue';
import ChevronRight24 from '@mozaic-ds/icons-vue/src/components/ChevronRight24/ChevronRight24.vue';
import MLoader from '../loader/MLoader.vue';

describe('MButton component', () => {
  it('renders with a label', () => {
    const wrapper = mount(MButton, {
      slots: {
        default: 'Click Me',
      },
    });
    expect(wrapper.text()).toContain('Click Me');
  });

  it('applies the correct appearance class based on the appearance prop', () => {
    const wrapper = mount(MButton, {
      props: {
        appearance: 'accent',
      },
      slots: {
        default: 'Styled Button',
      },
    });

    expect(wrapper.classes()).toContain('mc-button--accent');
  });

  it('applies the correct size class based on the size prop', () => {
    const wrapper = mount(MButton, {
      props: {
        label: 'Sized Button',
        size: 'l',
      },
      slots: {
        default: 'Sized Button',
      },
    });

    expect(wrapper.classes()).toContain('mc-button--l');
  });

  it('disables the button when the disabled prop is true', async () => {
    const wrapper = mount(MButton, {
      props: {
        disabled: true,
      },
      slots: {
        default: 'Disabled Button',
      },
    });

    const button = wrapper.find('button');
    expect(button.attributes('disabled')).toBeDefined();
  });

  it('applies the correct ghost class when ghost prop is true', () => {
    const wrapper = mount(MButton, {
      props: {
        ghost: true,
      },
      slots: {
        default: 'Ghost Button',
      },
    });

    expect(wrapper.classes()).toContain('mc-button--ghost');
  });

  it('applies the outlined class when outlined prop is true', () => {
    const wrapper = mount(MButton, {
      props: {
        outlined: true,
      },
      slots: {
        default: 'Outlined Button',
      },
    });

    expect(wrapper.classes()).toContain('mc-button--outlined');
  });

  it('has type="button" by default', () => {
    const wrapper = mount(MButton, {
      slots: {
        default: 'Default Button',
      },
    });

    const button = wrapper.find('button');
    expect(button.attributes('type')).toBe('button');
  });

  it('can have type="submit" when the type prop is "submit"', () => {
    const wrapper = mount(MButton, {
      props: {
        type: 'submit',
      },
      slots: {
        default: 'Submit Button',
      },
    });

    const button = wrapper.find('button');
    expect(button.attributes('type')).toBe('submit');
  });

  it('renders with an icon in the left position', () => {
    const wrapper = mount(MButton, {
      props: {
        iconPosition: 'left',
      },
      slots: {
        default: 'Button with Icon',
        icon: ChevronRight24,
      },
    });

    const icon = wrapper.findComponent(ChevronRight24);
    expect(icon.exists()).toBe(true);
  });

  it('renders with an icon in the right position', () => {
    const wrapper = mount(MButton, {
      props: {
        iconPosition: 'right',
      },
      slots: {
        default: 'Button with Icon',
        icon: ChevronRight24,
      },
    });

    const icon = wrapper.findComponent(ChevronRight24);
    expect(icon.exists()).toBe(true);
  });

  it('renders with only an icon when iconPosition is "only"', () => {
    const wrapper = mount(MButton, {
      props: {
        iconPosition: 'only',
      },
      slots: {
        default: 'Icon Only Button',
        icon: ChevronRight24,
      },
    });

    const icon = wrapper.findComponent(ChevronRight24);
    expect(icon.exists()).toBe(true);

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

  it('renders loader when isLoading prop is true', () => {
    const wrapper = mount(MButton, {
      props: {
        isLoading: true,
      },
      slots: {
        default: 'Loading Button',
      },
    });

    const loader = wrapper.findComponent(MLoader);
    expect(loader.exists()).toBe(true);

    const label = wrapper.find('.mc-button__label');
    expect(label.attributes('style')).toContain('visibility: hidden');
  });

  it('does not render loader when isLoading prop is false', () => {
    const wrapper = mount(MButton, {
      props: {
        isLoading: false,
      },
      slots: {
        default: 'Normal Button',
      },
    });

    const loader = wrapper.findComponent(MLoader);
    expect(loader.exists()).toBe(false);

    const label = wrapper.find('.mc-button__label');
    expect(label.exists()).toBe(true);
    expect(label.text()).toBe('Normal Button');
  });
});
