import { mount } from '@vue/test-utils';
import {
    defineComponent,
    nextTick,
} from 'vue';
import {
    afterEach,
    beforeEach,
    describe,
    expect,
    it,
    vi,
} from 'vitest';
import {
    KviewConfirmDialog,
    KviewPageHeader,
} from '@kview/ui-core/vue';
import { KviewInfoCard } from '@kview/visualization/vue';

vi.mock('@inertiajs/vue3', async (importOriginal) => {
    const actual = await importOriginal<typeof import('@inertiajs/vue3')>();

    return {
        ...actual,
        Head: defineComponent({
            name: 'InertiaHeadStub',
            props: { title: String },
            template: '<span data-head />',
        }),
    };
});

import ExchangeRateShowPage from '@/Pages/ExchangeRates/Show.vue';
import type { ExchangeRateShowPageProps } from '@/types/exchange-rate';

const pageProps: ExchangeRateShowPageProps = {
    exchangeRate: {
        id: 'rate-1',
        pair: 'GBP / USD',
        cards: [
            { id: 'from', label: 'From', value: 'GBP', icon: 'coins', variant: 'default' },
            { id: 'to', label: 'To', value: 'USD', icon: 'coins', variant: 'default' },
            { id: 'rate', label: 'Rate', value: '1.286956', icon: 'trend-up', variant: 'metric' },
            { id: 'date', label: 'Date', value: '2026-03-31', icon: 'calendar', variant: 'default' },
            { id: 'source', label: 'Source', value: 'DEMO', icon: 'document', variant: 'default' },
        ],
    },
    backLink: {
        href: '/exchange-rates',
        inertia: false,
    },
    editLink: {
        href: '/exchange-rates/rate-1/edit',
        inertia: false,
    },
    destroyAction: {
        href: '/exchange-rates/rate-1',
        confirm: {
            title: 'Delete exchange rate?',
            message: 'This exchange-rate observation will be permanently removed.',
            label: 'Delete exchange rate',
        },
    },
};

beforeEach(() => {
    const meta = document.createElement('meta');

    meta.name = 'csrf-token';
    meta.content = 'csrf-test-token';
    document.head.append(meta);
});

afterEach(() => {
    document.head.querySelector('meta[name="csrf-token"]')?.remove();
    document.body.innerHTML = '';
    vi.restoreAllMocks();
});

describe('Exchange-rate Inertia detail page', () => {
    it('keeps the historical information order inside shared card primitives', () => {
        const wrapper = mount(ExchangeRateShowPage, {
            props: pageProps,
        });
        const header = wrapper.getComponent(KviewPageHeader);
        const cards = wrapper.findAllComponents(KviewInfoCard);

        expect(wrapper.get('h1').text()).toBe('GBP / USD');
        expect(header.props()).toMatchObject({
            variant: 'detail',
            backHref: '/exchange-rates',
            backLabel: 'Back to currencies',
            backInertia: false,
        });
        expect(cards).toHaveLength(5);
        expect(cards.map((card) => card.props('label'))).toEqual([
            'From',
            'To',
            'Rate',
            'Date',
            'Source',
        ]);
        expect(cards[2]?.props()).toMatchObject({
            value: '1.286956',
            icon: 'trend-up',
            variant: 'metric',
        });
        expect(wrapper.get('a.btn-secondary').attributes('href')).toBe('/exchange-rates/rate-1/edit');
        expect(wrapper.get('form').attributes('action')).toBe('/exchange-rates/rate-1');
        expect(wrapper.get('input[name="_token"]').attributes('value')).toBe('csrf-test-token');
        expect(wrapper.get('input[name="_method"]').attributes('value')).toBe('DELETE');
        expect(wrapper.html()).not.toContain('data-ui-');
    });

    it('confirms once before submitting the native Laravel delete form', async () => {
        const requestSubmit = vi
            .spyOn(HTMLFormElement.prototype, 'requestSubmit')
            .mockImplementation(() => undefined);
        const wrapper = mount(ExchangeRateShowPage, {
            attachTo: document.body,
            props: pageProps,
        });
        const deleteTrigger = wrapper.get<HTMLButtonElement>('.btn-danger');

        deleteTrigger.element.focus();
        await deleteTrigger.trigger('click');
        await nextTick();

        const dialog = wrapper.findComponent(KviewConfirmDialog);
        const surface = document.body.querySelector<HTMLElement>('[role="alertdialog"]');
        const cancel = document.body.querySelector<HTMLButtonElement>('.ui-confirm-dialog__cancel');
        const confirm = document.body.querySelector<HTMLButtonElement>('.ui-confirm-dialog__accept');

        expect(dialog.exists()).toBe(true);
        expect(surface?.textContent).toContain('Delete exchange rate?');
        expect(document.activeElement).toBe(cancel);

        confirm?.click();
        await nextTick();

        expect(requestSubmit).toHaveBeenCalledTimes(1);
        expect(confirm?.disabled).toBe(true);
        expect(confirm?.getAttribute('aria-busy')).toBe('true');

        confirm?.click();
        expect(requestSubmit).toHaveBeenCalledTimes(1);
    });
});
