import BmsMenuNav from '@/components/navigation/BmsMenuNav.vue';
import { MenuItem } from '@/models/menu.model';
import { mount, MountingOptions, RouterLinkStub } from '@vue/test-utils';

const intersectionObserverMock = () => ({
  observe: () => null,
});

const menuItems: MenuItem[] = [
  {
    label: 'Item menu 1',
    link: { name: 'link-one' },
    id: 'menu0',
  },
  {
    label: 'Item menu 2',
    link: { name: 'link-two' },
    id: 'menu1',
  },
];

const factory = (options: MountingOptions<any, {}> = {}) => {
  const wrapper = mount(BmsMenuNav, {
    global: {
      stubs: {
        UiButton: true,
        'router-link': RouterLinkStub,
        teleport: true,
      },
    },
    props: {
      items: menuItems,
      activeLink: { name: 'unknown' },
    },
    ...options,
  } as any);

  return {
    wrapper,
  };
};

describe('BmsMenuNav', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    window.IntersectionObserver = vi
      .fn()
      .mockImplementation(intersectionObserverMock);
  });
  describe('isItemActive', () => {
    it('should not have any active', () => {
      const { wrapper } = factory({
        props: { items: menuItems, activeLink: { name: 'unknown' } },
      });
      expect(wrapper.findAll('.active').length).toEqual(0);
    });
    it('should have active if route has meta menu item id', () => {
      const { wrapper } = factory({
        props: {
          items: menuItems,
          activeLink: { name: 'unknown', meta: { menuItemId: 'menu0' } },
        },
      });
      expect(wrapper.findAll('.active').length).toEqual(1);
      expect(wrapper.findAll('.active')[0].text()).toEqual('Item menu 1');
    });
    it('should have active if route has same name', () => {
      const { wrapper } = factory({
        props: {
          items: menuItems,
          activeLink: { name: 'link-one' },
        },
      });
      expect(wrapper.findAll('.active').length).toEqual(1);
      expect(wrapper.findAll('.active')[0].text()).toEqual('Item menu 1');
    });
    it('should have active if route has same path', () => {
      const { wrapper } = factory({
        props: {
          items: [
            {
              label: 'Item menu 1',
              link: { path: '/path' },
              id: 'menu0',
            },
            {
              label: 'Item menu 2',
              link: { name: 'link-two' },
              id: 'menu1',
            },
          ],
          activeLink: { path: '/path' },
        },
      });
      expect(wrapper.findAll('.active').length).toEqual(1);
      expect(wrapper.findAll('.active')[0].text()).toEqual('Item menu 1');
    });
    it('should have active if item is string and route has same name', () => {
      const { wrapper } = factory({
        props: {
          items: [
            {
              label: 'Item menu 1',
              link: 'link-one',
              id: 'menu0',
            },
            {
              label: 'Item menu 2',
              link: { name: 'link-two' },
              id: 'menu1',
            },
          ],
          activeLink: { name: 'link-one' },
        },
      });
      expect(wrapper.findAll('.active').length).toEqual(1);
      expect(wrapper.findAll('.active')[0].text()).toEqual('Item menu 1');
    });
    it('should have active if item is string and route has same path', () => {
      const { wrapper } = factory({
        props: {
          items: [
            {
              label: 'Item menu 1',
              link: '/link-one',
              id: 'menu0',
            },
            {
              label: 'Item menu 2',
              link: { path: '/link-two' },
              id: 'menu1',
            },
          ],
          activeLink: { path: '/link-one' },
        },
      });
      expect(wrapper.findAll('.active').length).toEqual(1);
      expect(wrapper.findAll('.active')[0].text()).toEqual('Item menu 1');
    });
  });

  describe('non-collapsible parent', () => {
    it('should show children without chevron and without click', () => {
      const { wrapper } = factory({
        props: {
          items: [
            {
              label: 'Parent',
              id: 'parent',
              collapsible: false,
              items: [
                {
                  label: 'Child 1',
                  link: { name: 'child-one' },
                  id: 'child1',
                },
                {
                  label: 'Child 2',
                  link: { name: 'child-two' },
                  id: 'child2',
                },
              ],
            },
          ],
          activeLink: { name: 'unknown' },
        },
      });

      expect(wrapper.text()).toContain('Parent');
      expect(wrapper.text()).toContain('Child 1');
      expect(wrapper.text()).toContain('Child 2');
      expect(wrapper.find('[data-lucide="chevron-down"]').exists()).toBe(false);
      expect(wrapper.find('[data-lucide="chevron-up"]').exists()).toBe(false);
    });
  });
});
