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

describe('MLoader component', () => {
  it('should render correctly with the given props', () => {
    const wrapper = mount(MLoader, {
      props: {
        size: 's',
        appearance: 'accent',
      },
    });

    expect(wrapper.exists()).toBe(true);

    const loaderElement = wrapper.find('.mc-loader');
    expect(loaderElement.exists()).toBe(true);
    expect(loaderElement.classes()).toContain('mc-loader--s');
    expect(loaderElement.classes()).toContain('mc-loader--accent');

    const svg = wrapper.find('svg.mc-loader__icon');
    expect(svg.exists()).toBe(true);

    const circle = wrapper.find('circle.mc-loader__path');
    expect(circle.exists()).toBe(true);
  });

  it('changes class based on size prop', async () => {
    const wrapper = mount(MLoader, {
      props: {
        size: 's',
      },
    });

    let loader = wrapper.find('.mc-loader');
    expect(loader.classes()).toContain('mc-loader--s');

    await wrapper.setProps({ size: 'l' });
    loader = wrapper.find('.mc-loader');
    expect(loader.classes()).toContain('mc-loader--l');
  });

  it('changes class based on appearance prop', async () => {
    const wrapper = mount(MLoader, {
      props: {
        appearance: 'accent',
      },
    });

    let loader = wrapper.find('.mc-loader');
    expect(loader.classes()).toContain('mc-loader--accent');

    await wrapper.setProps({ appearance: 'inverse' });
    loader = wrapper.find('.mc-loader');
    expect(loader.classes()).toContain('mc-loader--inverse');
  });

  it('renders the loader text when text prop is provided', () => {
    const wrapper = mount(MLoader, {
      props: {
        text: 'Loading...',
      },
    });

    const textElement = wrapper.find('.mc-loader__text');
    expect(textElement.exists()).toBe(true);
    expect(textElement.text()).toBe('Loading...');
  });

  it('does not render the loader text when text prop is not provided', () => {
    const wrapper = mount(MLoader);

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

  it('sets the correct viewBox based on size prop', async () => {
    const wrapper = mount(MLoader, {
      props: {
        size: 's',
      },
    });

    const svg = wrapper.find('svg.mc-loader__icon');
    expect(svg.attributes('viewBox')).toBe('0 0 24 24');

    await wrapper.setProps({ size: 'l' });
    expect(svg.attributes('viewBox')).toBe('0 0 64 64');
  });

  it('sets the correct circle radius based on size prop', async () => {
    const wrapper = mount(MLoader, {
      props: {
        size: 's',
      },
    });

    const circle = wrapper.find('circle.mc-loader__path');
    expect(circle.attributes('r')).toBe('6');

    await wrapper.setProps({ size: 'l' });
    expect(circle.attributes('r')).toBe('19');
  });

  it('applies mc-loader--text-visible class when text prop is provided', () => {
    const wrapper = mount(MLoader, {
      props: { text: 'Loading data...' },
    });

    const loader = wrapper.find('.mc-loader');
    expect(loader.classes()).toContain('mc-loader--text-visible');
  });

  it('does not apply mc-loader--text-visible class when no text is provided', () => {
    const wrapper = mount(MLoader);
    const loader = wrapper.find('.mc-loader');
    expect(loader.classes()).not.toContain('mc-loader--text-visible');
  });

  it('uses default props correctly (appearance=standard, size=m)', () => {
    const wrapper = mount(MLoader);
    const loader = wrapper.find('.mc-loader');

    expect(loader.classes()).not.toContain('mc-loader--standard');
    expect(loader.classes()).not.toContain('mc-loader--m');

    const svg = wrapper.find('svg.mc-loader__icon');
    expect(svg.attributes('viewBox')).toBe('0 0 32 32');

    const circle = wrapper.find('circle.mc-loader__path');
    expect(circle.attributes('r')).toBe('9');
  });

  it('sets correct viewBox for xs size', async () => {
    const wrapper = mount(MLoader, { props: { size: 'xs' } });
    const svg = wrapper.find('svg.mc-loader__icon');
    expect(svg.attributes('viewBox')).toBe('0 0 20 20');
  });

  it('sets correct circle radius for xs size', async () => {
    const wrapper = mount(MLoader, { props: { size: 'xs' } });
    const circle = wrapper.find('circle.mc-loader__path');
    expect(circle.attributes('r')).toBe('6');
  });
});
