import { mount } from '@vue/test-utils';
import { Link, router } from '@inertiajs/vue3';
import { h, nextTick } from 'vue';
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
    KviewButton,
    KviewIconButton,
    KviewUiProvider,
} from '@kview/ui-core/vue';
import AppLink from '@/components/application/AppLink.vue';

afterEach(() => {
    vi.restoreAllMocks();
});

describe('AppLink Inertia adapter', () => {
    it('preserves native ARIA attributes and emits before the real Inertia click handler', async () => {
        const visit = vi.spyOn(router, 'visit').mockImplementation(() => undefined);
        const onClick = vi.fn();
        const wrapper = mount(AppLink, {
            props: {
                href: '/funds',
                inertia: true,
            },
            attrs: {
                'aria-label': 'Ouvrir les funds',
                'aria-current': 'page',
                onClick,
            },
            slots: {
                default: 'Funds',
            },
        });
        const link = wrapper.get('a');

        expect(link.attributes('aria-label')).toBe('Ouvrir les funds');
        expect(link.attributes('aria-current')).toBe('page');

        await link.trigger('click');

        expect(onClick).toHaveBeenCalledOnce();
        expect(visit).toHaveBeenCalledOnce();
    });

    it('lets a disabled kView link cancel the real Inertia visit during capture', async () => {
        const visit = vi.spyOn(router, 'visit').mockImplementation(() => undefined);
        const wrapper = mount(KviewUiProvider, {
            props: {
                linkComponent: AppLink,
            },
            slots: {
                default: () => h(KviewButton, {
                    href: '/funds',
                    inertia: true,
                    disabled: true,
                }, {
                    default: () => 'Funds',
                }),
            },
        });

        await wrapper.get('a').trigger('click');

        expect(visit).not.toHaveBeenCalled();
    });

    it('forwards scroll and state policies only to Inertia links', () => {
        const inertiaWrapper = mount(AppLink, {
            props: {
                href: '/activity?activity=added',
                inertia: true,
                preserveState: true,
                preserveScroll: true,
            },
        });
        const inertiaLink = inertiaWrapper.getComponent(Link);

        expect(inertiaLink.props('preserveState')).toBe(true);
        expect(inertiaLink.props('preserveScroll')).toBe(true);

        const nativeWrapper = mount(AppLink, {
            props: {
                href: '/',
                inertia: false,
                preserveState: true,
                preserveScroll: true,
            },
        });
        const nativeLink = nativeWrapper.get('a');

        expect(nativeLink.attributes('preservestate')).toBeUndefined();
        expect(nativeLink.attributes('preservescroll')).toBeUndefined();
    });

    it('keeps icon-button focus restoration working through the host component', async () => {
        const wrapper = mount(KviewUiProvider, {
            attachTo: document.body,
            props: {
                linkComponent: AppLink,
            },
            slots: {
                default: () => h(KviewIconButton, {
                    href: '/funds',
                    inertia: true,
                    icon: 'portfolio',
                    label: 'Ouvrir les funds',
                }),
            },
        });
        const iconButton = wrapper.findComponent(KviewIconButton);
        const component = iconButton.vm as unknown as {
            $?: { exposed?: { focus?: () => void } };
        };

        await nextTick();
        component.$?.exposed?.focus?.();

        expect(document.activeElement).toBe(wrapper.get('a').element);
        wrapper.unmount();
    });
});
