import { render } from '@testing-library/vue';
import { describe, expect, test, vi } from 'vitest';
import { defineComponent, h, ref } from 'vue';
import { UiSlider } from '../index';

let emitUndefinedPayload = false;

vi.mock('@/components/core/slider', () => {
  return {
    Slider: defineComponent({
      name: 'ShadcnSliderMock',
      emits: ['update:modelValue', 'valueCommit'],
      setup(_props, { emit }) {
        return () =>
          h('button', {
            type: 'button',
            onClick: () => {
              const payload = emitUndefinedPayload ? undefined : [51];
              emit('update:modelValue', payload);
              if (!emitUndefinedPayload) {
                emit('valueCommit', [51]);
              }
            },
          });
      },
    }),
  };
});

describe('UiSlider', () => {
  test('re-emits update:modelValue and valueCommit from the vendor slider', async () => {
    const { container, emitted } = render(UiSlider, {
      props: { modelValue: [50] },
    });

    const button = container.querySelector('button');
    expect(button).toBeInTheDocument();
    await (button as HTMLButtonElement).click();

    expect(emitted('update:modelValue')?.[0]).toEqual([[51]]);
    expect(emitted('valueCommit')?.[0]).toEqual([[51]]);
  });

  test('normalizes invalid update:modelValue payloads to an empty array', async () => {
    emitUndefinedPayload = true;
    const { container, emitted } = render(UiSlider);
    const button = container.querySelector('button');
    expect(button).toBeInTheDocument();
    await (button as HTMLButtonElement).click();

    expect(emitted('update:modelValue')?.[0]).toEqual([[]]);
    emitUndefinedPayload = false;
  });

  test('supports controlled mode via v-model:modelValue', async () => {
    const { container, getByText } = render({
      components: { UiSlider },
      setup() {
        const value = ref([50]);
        return { value };
      },
      template: `
        <div>
          <div>Value: {{ value[0] }}</div>
          <UiSlider v-model:modelValue="value" />
        </div>
      `,
    });

    const button = container.querySelector('button');
    expect(button).toBeInTheDocument();
    await (button as HTMLButtonElement).click();

    expect(getByText('Value: 51')).toBeInTheDocument();
  });
});
