import { mount } from '@vue/test-utils';
import { defineComponent, h } from 'vue';
import { describe, expect, it } from 'vitest';
import SearchResultGroup from '@/components/search/SearchResultGroup.vue';
import type { SearchResultGroupData } from '@/types/search';

const populatedGroup: SearchResultGroupData = {
    id: 'funds',
    title: 'Funds',
    description: 'Funds matching your query.',
    icon: 'portfolio',
    results: [
        {
            id: 7,
            title: 'North Atlantic Growth',
            href: '/funds/7',
            eyebrow: 'Growth equity',
            meta: 'EUR 320m',
        },
        {
            id: 11,
            title: 'Alpine Secondary Fund',
            href: '/funds/11',
            icon: 'chart',
        },
    ],
    emptyTitle: 'No funds found',
    emptyText: 'Try another name or alias.',
};

describe('SearchResultGroup', () => {
    it('renders an accessible heading, result list and native links by default', () => {
        const wrapper = mount(SearchResultGroup, {
            props: { group: populatedGroup },
        });

        expect(wrapper.get('section').attributes('aria-label')).toBe('Funds');
        expect(wrapper.get('h2').text()).toBe('Funds');
        expect(wrapper.get('ul').element.children).toHaveLength(2);
        expect(wrapper.findAll('a').map((link) => link.attributes('href'))).toEqual([
            '/funds/7',
            '/funds/11',
        ]);
        expect(wrapper.text()).toContain('Growth equity');
        expect(wrapper.text()).toContain('EUR 320m');
        expect(wrapper.get('.search-result-group__icon').attributes('aria-hidden')).toBe('true');
    });

    it('uses an explicit host link component without changing link semantics', async () => {
        const LinkStub = defineComponent({
            inheritAttrs: false,
            emits: ['click'],
            props: {
                href: { type: String, required: true },
                preserveScroll: Boolean,
            },
            setup(linkProps, { attrs, emit, slots }) {
                return () => h('a', {
                    ...attrs,
                    href: linkProps.href,
                    'data-preserve-scroll': String(linkProps.preserveScroll),
                    onClick: (event: MouseEvent) => {
                        event.preventDefault();
                        emit('click', event);
                    },
                }, slots.default?.());
            },
        });
        const group: SearchResultGroupData = {
            ...populatedGroup,
            results: [{
                ...populatedGroup.results[0],
                linkProps: { preserveScroll: true },
            }],
        };
        const wrapper = mount(SearchResultGroup, {
            props: {
                group,
                linkComponent: LinkStub,
            },
        });

        const link = wrapper.get('a');
        expect(link.attributes('href')).toBe('/funds/7');
        expect(link.attributes('data-preserve-scroll')).toBe('true');

        await link.trigger('click');

        expect(wrapper.emitted('select')?.[0]?.[0]).toMatchObject({
            id: 7,
            title: 'North Atlantic Growth',
        });
    });

    it('renders the shared compact empty state instead of an empty list', () => {
        const wrapper = mount(SearchResultGroup, {
            props: {
                group: {
                    ...populatedGroup,
                    results: [],
                },
                headingLevel: 3,
            },
        });

        expect(wrapper.get('h3').text()).toBe('Funds');
        expect(wrapper.find('ul').exists()).toBe(false);
        expect(wrapper.get('.ui-empty-state--search').text()).toContain('No funds found');
        expect(wrapper.text()).toContain('Try another name or alias.');
    });
});
