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

const defaultSteps = [
  { id: '1', label: 'Step 1' },
  { id: '2', label: 'Step 2', additionalInfo: 'Additional info' },
  { id: '3', label: 'Step 3' },
];

describe('MStepperStacked', () => {
  describe('Accessibility', () => {
    it('sets aria-current="step" on the current step item', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '2' },
      });

      const items = wrapper.findAll('.mc-stepper-stacked__item');
      expect(items[1].attributes('aria-current')).toBe('step');
      expect(items[0].attributes('aria-current')).toBeUndefined();
      expect(items[2].attributes('aria-current')).toBeUndefined();
    });
  });

  describe('Basic rendering', () => {
    it('renders as many li elements as there are steps', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps },
      });
      const items = wrapper.findAll('.mc-stepper-stacked__item');
      expect(items).toHaveLength(defaultSteps.length);
    });

    it('renders the label of each step', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps },
      });
      defaultSteps.forEach((step) => {
        expect(wrapper.text()).toContain(step.label);
      });
    });

    it('renders step numbers (1, 2, 3...)', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '1' },
      });
      expect(wrapper.text()).toContain('2');
      expect(wrapper.text()).toContain('3');
    });

    it('renders additionalInfo when provided', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps },
      });
      expect(wrapper.text()).toContain('Additional info');
    });

    it('adds the has-additional class on items with additionalInfo', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps },
      });
      const items = wrapper.findAll('.mc-stepper-stacked__item');
      expect(items[1].classes()).toContain('has-additional');
      expect(items[0].classes()).not.toContain('has-additional');
    });
  });

  describe('Step states', () => {
    it('marks the current step circle with the is-current class', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '2' },
      });
      const circles = wrapper.findAll('.mc-stepper-stacked__circle');
      const currentCircle = circles.find((c) => c.classes('is-current'));
      expect(currentCircle).toBeTruthy();
      expect(currentCircle?.text()).toBe('2');
    });

    it('marks the current step label with the is-current class', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '2' },
      });
      const labels = wrapper.findAll('.mc-stepper-stacked__label');
      expect(labels[1].classes()).toContain('is-current');
      expect(labels[0].classes()).not.toContain('is-current');
      expect(labels[2].classes()).not.toContain('is-current');
    });

    it('renders the Check icon for completed steps', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '3' },
      });
      const checkIcons = wrapper.findAll('.mc-stepper-stacked__icon--check');
      expect(checkIcons).toHaveLength(2);
    });

    it('does not render the Check icon for the current step', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '1' },
      });
      const checkIcons = wrapper.findAll('.mc-stepper-stacked__icon--check');
      expect(checkIcons).toHaveLength(0);
    });

    it('renders a numbered circle for non-completed steps', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '1' },
      });
      const circles = wrapper.findAll('.mc-stepper-stacked__circle');
      expect(circles).toHaveLength(3);
    });
  });

  describe('active step — string type', () => {
    it('falls back to step 1 if currentStep is less than 1', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: 'unknown id' },
      });
      const labels = wrapper.findAll('.mc-stepper-stacked__label');
      expect(labels[0].classes()).toContain('is-current');
    });

    it('works with no steps (default value)', () => {
      const wrapper = mount(MStepperStacked);
      expect(wrapper.findAll('.mc-stepper-stacked__item')).toHaveLength(0);
    });
  });

  describe('active step — number type', () => {
    it('clamps to step 1 when currentStep is 0 or less', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: 0 },
      });
      const labels = wrapper.findAll('.mc-stepper-stacked__label');
      expect(labels[0].classes()).toContain('is-current');
    });

    it('clamps to the last step when currentStep exceeds steps length', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: 99 },
      });
      const labels = wrapper.findAll('.mc-stepper-stacked__label');
      expect(labels[defaultSteps.length - 1].classes()).toContain('is-current');
    });
  });

  describe('Default currentStep', () => {
    it('defaults to currentStep=1', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps },
      });
      const labels = wrapper.findAll('.mc-stepper-stacked__label');
      expect(labels[0].classes()).toContain('is-current');
    });
  });

  describe('First and last step', () => {
    it('has no completed steps when currentStep=1', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '1' },
      });
      expect(wrapper.findAll('.mc-stepper-stacked__icon--check')).toHaveLength(
        0,
      );
    });

    it('marks all previous steps as completed when on the last step', () => {
      const wrapper = mount(MStepperStacked, {
        props: { steps: defaultSteps, currentStep: '3' },
      });
      const checkIcons = wrapper.findAll('.mc-stepper-stacked__icon--check');
      expect(checkIcons).toHaveLength(defaultSteps.length - 1);
    });
  });
});
