import { mount } from '@vue/test-utils';
import { defineComponent, h } from 'vue';
import { describe, expect, it } from 'vitest';
import KviewUiHost from '@/components/KviewUiHost.vue';
import {
    defaultKviewUiMessages,
    KviewAlert,
    KviewButtonGroup,
    KviewEmptyState,
    KviewFormField,
    KviewLoadingState,
    KviewPageHeader,
    KviewResourceHeading,
    KviewSegmentedControl,
    KviewTabs,
    KviewUiProvider,
    mergeKviewUiMessages,
    useKviewUi,
} from '@kview/ui-core/vue';

describe('kView Vue UI context', () => {
    it('keeps explicit English package defaults and merges partial overrides', () => {
        expect(defaultKviewUiMessages).toMatchObject({
            alert: { info: 'Info', dismiss: 'Dismiss alert' },
            common: {
                back: 'Back',
                cancel: 'Cancel',
                confirm: 'Confirm',
                loading: 'Loading',
                required: 'required',
                save: 'Save',
                saving: 'Saving...',
            },
            confirm: {
                title: 'Confirm action',
                message: 'Are you sure you want to continue?',
            },
            navigation: {
                breadcrumb: 'Breadcrumb',
                groupedActions: 'Grouped actions',
                section: 'Section navigation',
                segmentedControl: 'Segmented control',
            },
            toast: {
                dismiss: 'Dismiss notification',
                working: 'Working',
                failed: 'Something went wrong',
            },
        });

        expect(mergeKviewUiMessages({
            common: { back: 'Retour' },
        })).toMatchObject({
            common: {
                back: 'Retour',
                cancel: 'Cancel',
                confirm: 'Confirm',
                loading: 'Loading',
                required: 'required',
                save: 'Save',
                saving: 'Saving...',
            },
        });
    });

    it('localizes primitive defaults and resolves host resource icons', async () => {
        const wrapper = mount(KviewUiProvider, {
            props: {
                messages: {
                    alert: { info: 'Information', dismiss: "Fermer l’alerte" },
                    common: {
                        back: 'Retour',
                        cancel: 'Annuler',
                        loading: 'Chargement',
                        required: 'obligatoire',
                        save: 'Enregistrer',
                        saving: 'Enregistrement...',
                    },
                    navigation: {
                        breadcrumb: "Fil d’Ariane",
                        groupedActions: 'Actions groupées',
                        section: 'Navigation de section',
                        segmentedControl: 'Contrôle segmenté',
                    },
                    toast: {
                        dismiss: 'Fermer la notification',
                        working: 'Traitement en cours',
                    },
                },
                resourceIcons: {
                    fund: 'portfolio',
                },
            },
            slots: {
                default: () => [
                    h(KviewAlert),
                    h(KviewLoadingState, { variant: 'spinner' }),
                    h(KviewFormField, {
                        id: 'fund-name',
                        label: 'Nom',
                        required: true,
                    }, {
                        default: () => h('input', { id: 'fund-name' }),
                    }),
                    h(KviewPageHeader, {
                        resource: 'fund',
                        title: 'Funds',
                        backHref: '/funds',
                    }),
                    h(KviewButtonGroup, null, {
                        default: () => h('button', { type: 'button' }, 'CSV'),
                    }),
                    h(KviewSegmentedControl, {
                        items: [{ value: 'all', label: 'Tout' }],
                    }),
                    h(KviewTabs, {
                        tabs: [{ id: 'overview', label: 'Vue générale' }],
                    }, {
                        overview: () => h('p', 'Contenu'),
                    }),
                ],
            },
        });

        expect(wrapper.get('.ui-alert strong').text()).toBe('Information');
        expect(wrapper.get('.ui-alert-close').attributes('aria-label')).toBe('Fermer l’alerte');
        expect(wrapper.get('.ui-loading-state').attributes('aria-label')).toBe('Chargement');
        expect(wrapper.get('.ui-form-field__label').text()).toContain('obligatoire');
        expect(wrapper.get('.ui-page-header__back').text()).toBe('Retour');
        expect(wrapper.find('.ui-resource-heading__icon').exists()).toBe(true);
        expect(wrapper.get('.ui-button-group').attributes('aria-label')).toBe('Actions groupées');
        expect(wrapper.get('.ui-segmented-control').attributes('aria-label')).toBe('Contrôle segmenté');
        expect(wrapper.get('.ui-tab-list').attributes('aria-label')).toBe('Navigation de section');

        await wrapper.setProps({
            messages: {
                common: { loading: 'Veuillez patienter' },
            },
        });

        expect(wrapper.get('.ui-loading-state').attributes('aria-label')).toBe('Veuillez patienter');
        expect(wrapper.get('.ui-page-header__back').text()).toBe('Back');
    });

    it('exposes an optional non-serialized host link component', () => {
        const LinkStub = defineComponent({
            name: 'LinkStub',
            props: {
                href: { type: String, required: true },
                inertia: { type: Boolean, default: false },
            },
            setup: (props, { slots }) => () => h('a', {
                href: props.href,
                'data-inertia': String(props.inertia),
            }, slots.default?.()),
        });
        const ContextProbe = defineComponent({
            setup() {
                const ui = useKviewUi();

                return () => h('span', {
                    'data-link-component': ui.linkComponent ? 'available' : 'missing',
                });
            },
        });
        const wrapper = mount(KviewUiProvider, {
            props: {
                linkComponent: LinkStub,
            },
            slots: {
                default: () => [
                    h(ContextProbe),
                    h(KviewEmptyState, {
                        actionUrl: '/funds',
                        actionLabel: 'Ouvrir les funds',
                        actionInertia: true,
                    }),
                ],
            },
        });

        expect(wrapper.get('[data-link-component]').attributes('data-link-component')).toBe('available');
        expect(wrapper.get('a[href="/funds"]').attributes('data-inertia')).toBe('true');
    });

    it('uses the serialized initial Inertia context before the page child mounts', () => {
        const ContextProbe = defineComponent({
            setup() {
                const ui = useKviewUi();

                return () => h('span', {
                    'data-message': ui.messages.common.save,
                    'data-resource-icon': ui.resourceIcons.fund,
                    'data-link-component': ui.linkComponent ? 'available' : 'missing',
                });
            },
        });
        const wrapper = mount(KviewUiHost, {
            props: {
                initialUi: {
                    messages: mergeKviewUiMessages({
                        common: { save: 'Enregistrer' },
                    }),
                    resourceIcons: { fund: 'portfolio' },
                },
            },
            slots: {
                default: () => h(ContextProbe),
            },
        });
        const probe = wrapper.get('[data-message]');

        expect(probe.attributes('data-message')).toBe('Enregistrer');
        expect(probe.attributes('data-resource-icon')).toBe('portfolio');
        expect(probe.attributes('data-link-component')).toBe('available');
    });

    it('falls back to English and no resource icon without a provider', () => {
        const alert = mount(KviewAlert);
        const heading = mount(KviewResourceHeading, {
            props: {
                resource: 'fund',
                title: 'Funds',
            },
        });

        expect(alert.get('strong').text()).toBe('Info');
        expect(alert.get('button').attributes('aria-label')).toBe('Dismiss alert');
        expect(heading.find('.ui-resource-heading__icon').exists()).toBe(false);
    });
});
