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

describe('VCheckbox.vue', () => {
  it('binds modelValue and emits update:modelValue correctly (v-model)', async () => {
    const wrapper = mount(VCheckbox, {
      props: { modelValue: false, id: 'test-check' }, // id is required due to default prop
    });
    const inputElement = wrapper.find('input[type="checkbox"]');

    // Check initial state (unchecked)
    expect(inputElement.element.checked).toBe(false);

    // Simulate user checking the box
    await inputElement.setChecked(true);

    // Check emitted event
    expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
    expect(wrapper.emitted()['update:modelValue'][0]).toEqual([true]);

    // Simulate parent v-model update (checked)
    await wrapper.setProps({ modelValue: true });
    expect(inputElement.element.checked).toBe(true);

    // Simulate user unchecking the box
    await inputElement.setChecked(false);
    expect(wrapper.emitted()['update:modelValue'][1]).toEqual([false]);

    // Simulate parent v-model update (unchecked)
    await wrapper.setProps({ modelValue: false });
    expect(inputElement.element.checked).toBe(false);
  });

  it('renders label when label prop is provided', () => {
    const labelText = 'Subscribe to newsletter';
    const wrapper = mount(VCheckbox, {
      props: { modelValue: false, label: labelText, id: 'newsletter-check' },
    });
    const labelElement = wrapper.find('.checkbox-text-label');
    expect(labelElement.exists()).toBe(true);
    expect(labelElement.text()).toBe(labelText);
  });

  it('does not render text label span when label prop is not provided', () => {
    const wrapper = mount(VCheckbox, {
      props: { modelValue: false, id: 'no-label-check' },
    });
    expect(wrapper.find('.checkbox-text-label').exists()).toBe(false);
  });

  it('is disabled when disabled prop is true', () => {
    const wrapper = mount(VCheckbox, {
      props: { modelValue: false, disabled: true, id: 'disabled-check' },
    });
    expect(wrapper.find('input[type="checkbox"]').attributes('disabled')).toBeDefined();
    expect(wrapper.find('.checkbox-label').classes()).toContain('disabled');
  });

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

  it('passes id prop to the input element and label for attribute', () => {
    const checkboxId = 'my-custom-checkbox-id';
    const wrapper = mount(VCheckbox, {
      props: { modelValue: false, id: checkboxId },
    });
    expect(wrapper.find('input[type="checkbox"]').attributes('id')).toBe(checkboxId);
    expect(wrapper.find('.checkbox-label').attributes('for')).toBe(checkboxId);
  });

  it('generates an id if not provided', () => {
    const wrapper = mount(VCheckbox, { props: { modelValue: false } });
    const inputId = wrapper.find('input[type="checkbox"]').attributes('id');
    expect(inputId).toBeDefined();
    expect(inputId).toContain('vcheckbox-');
    expect(wrapper.find('.checkbox-label').attributes('for')).toBe(inputId);
  });


  it('contains a .checkmark span', () => {
    const wrapper = mount(VCheckbox, { props: { modelValue: false, id: 'checkmark-check' } });
    expect(wrapper.find('.checkmark').exists()).toBe(true);
  });

  it('root element is a label with .checkbox-label class', () => {
    const wrapper = mount(VCheckbox, { props: { modelValue: false, id: 'root-check' } });
    expect(wrapper.element.tagName).toBe('LABEL');
    expect(wrapper.classes()).toContain('checkbox-label');
  });
});
