import { describe, it, expect, beforeEach, vi } from 'vitest';
import { defineComponent } from 'vue';
import { mount } from '@vue/test-utils';
import { useIsMobile } from './use-is-mobile.composable';

describe('useIsMobile', () => {
  beforeEach(() => {
    window.matchMedia = vi.fn().mockImplementation((query: string) => ({
      matches: false,
      media: query,
      addEventListener: vi.fn(),
      removeEventListener: vi.fn(),
    }));
  });

  const createWrapper = (breakpoint?: number) => {
    const component = defineComponent({
      setup() {
        const result = useIsMobile(breakpoint);
        return { isMobile: result.isMobile };
      },
      template: '<div>{{ isMobile }}</div>',
    });
    return mount(component);
  };

  it('should detect desktop screen', () => {
    const wrapper = createWrapper();

    expect(wrapper.vm.isMobile).toBe(false);
  });

  it('should detect mobile screen', () => {
    window.matchMedia = vi.fn().mockReturnValue({
      matches: true,
      media: '',
      addEventListener: vi.fn(),
      removeEventListener: vi.fn(),
    });

    const wrapper = createWrapper();

    expect(wrapper.vm.isMobile).toBe(true);
  });

  it('should use default breakpoint (780px)', () => {
    createWrapper();

    expect(window.matchMedia).toHaveBeenCalledWith('(max-width: 780px)');
  });

  it('should accept custom breakpoint', () => {
    createWrapper(1024);

    expect(window.matchMedia).toHaveBeenCalledWith('(max-width: 1024px)');
  });

  it('should add and remove event listener', () => {
    const addSpy = vi.spyOn(window, 'addEventListener');
    const removeSpy = vi.spyOn(window, 'removeEventListener');

    const wrapper = createWrapper();

    expect(addSpy).toHaveBeenCalledWith('resize', expect.any(Function));

    wrapper.unmount();

    expect(removeSpy).toHaveBeenCalledWith('resize', expect.any(Function));
  });
});
