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

describe('VToggleSwitch.vue', () => {
  it('binds modelValue and emits update:modelValue on change', async () => {
    const wrapper = mount(VToggleSwitch, {
      props: { modelValue: false, id: 'test-switch' }, // id is required due to default prop generation if not passed
    });
    const input = wrapper.find('input[type="checkbox"]');

    // Initial state
    expect(input.element.checked).toBe(false);

    // Simulate change by setting checked state (how user interacts)
    await input.setChecked(true);
    expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
    expect(wrapper.emitted()['update:modelValue'][0]).toEqual([true]);

    // Simulate parent updating modelValue
    await wrapper.setProps({ modelValue: true });
    expect(input.element.checked).toBe(true);

    await input.setChecked(false);
    expect(wrapper.emitted()['update:modelValue'][1]).toEqual([false]);
  });

  it('applies disabled state to input and container class', () => {
    const wrapper = mount(VToggleSwitch, {
      props: { modelValue: false, disabled: true, id: 'disabled-switch' },
    });
    expect(wrapper.find('input[type="checkbox"]').attributes('disabled')).toBeDefined();
    expect(wrapper.find('.switch-container').classes()).toContain('disabled');
  });

  it('is not disabled by default', () => {
    const wrapper = mount(VToggleSwitch, { props: { modelValue: false, id: 'enabled-switch' } });
    expect(wrapper.find('input[type="checkbox"]').attributes('disabled')).toBeUndefined();
    expect(wrapper.find('.switch-container').classes()).not.toContain('disabled');
  });

  it('applies provided id or generates one automatically', () => {
    const providedId = 'my-custom-id';
    const wrapperWithId = mount(VToggleSwitch, {
      props: { modelValue: false, id: providedId },
    });
    const inputWithId = wrapperWithId.find('input[type="checkbox"]');
    expect(inputWithId.attributes('id')).toBe(providedId);
    expect(wrapperWithId.find('label.switch').attributes('for')).toBe(providedId);

    const wrapperWithoutId = mount(VToggleSwitch, { props: { modelValue: false } });
    const inputWithoutId = wrapperWithoutId.find('input[type="checkbox"]');
    const generatedId = inputWithoutId.attributes('id');
    expect(generatedId).toMatch(/^v-toggle-switch-/);
    expect(wrapperWithoutId.find('label.switch').attributes('for')).toBe(generatedId);
  });

  it('renders accessible label (sr-only) from prop or default', () => {
    const labelText = 'Enable High Contrast Mode';
    const wrapperWithLabel = mount(VToggleSwitch, {
      props: { modelValue: false, label: labelText, id: 'label-switch' },
    });
    const srLabel1 = wrapperWithLabel.find('label.switch > span.sr-only');
    expect(srLabel1.exists()).toBe(true);
    expect(srLabel1.text()).toBe(labelText);

    const wrapperDefaultLabel = mount(VToggleSwitch, { props: { modelValue: false, id: 'default-label-switch' } });
    const srLabel2 = wrapperDefaultLabel.find('label.switch > span.sr-only');
    expect(srLabel2.exists()).toBe(true);
    expect(srLabel2.text()).toBe('Toggle Switch'); // Default label
  });

  it('input has role="switch"', () => {
    const wrapper = mount(VToggleSwitch, { props: { modelValue: false, id: 'role-switch' } });
    expect(wrapper.find('input[type="checkbox"]').attributes('role')).toBe('switch');
  });

  it('has .switch-container and label.switch classes', () => {
    const wrapper = mount(VToggleSwitch, { props: { modelValue: false, id: 'class-switch' } });
    expect(wrapper.find('.switch-container').exists()).toBe(true);
    expect(wrapper.find('label.switch').exists()).toBe(true);
  });

  it('renders onText when modelValue is true and onText is provided', () => {
    const wrapper = mount(VToggleSwitch, {
      props: { modelValue: true, onText: 'ON', offText: 'OFF', id: 'on-text-switch' }
    });
    const onTextView = wrapper.find('.switch-text-on');
    expect(onTextView.exists()).toBe(true);
    expect(onTextView.text()).toBe('ON');
    expect(wrapper.find('.switch-text-off').exists()).toBe(false);
  });

  it('renders offText when modelValue is false and offText is provided', () => {
    const wrapper = mount(VToggleSwitch, {
      props: { modelValue: false, onText: 'ON', offText: 'OFF', id: 'off-text-switch' }
    });
    const offTextView = wrapper.find('.switch-text-off');
    expect(offTextView.exists()).toBe(true);
    expect(offTextView.text()).toBe('OFF');
    expect(wrapper.find('.switch-text-on').exists()).toBe(false);
  });

  it('does not render onText/offText if not provided', () => {
    const wrapper = mount(VToggleSwitch, { props: { modelValue: false, id: 'no-text-switch' } });
    expect(wrapper.find('.switch-text-on').exists()).toBe(false);
    expect(wrapper.find('.switch-text-off').exists()).toBe(false);
  });
});
