import {
    flushPromises,
    mount,
    type VueWrapper,
} from '@vue/test-utils';
import { nextTick } from 'vue';
import {
    afterEach,
    describe,
    expect,
    it,
} from 'vitest';
import BusinessDetailTable from '@/components/business/BusinessDetailTable.vue';
import type { BusinessDetailTablePayload } from '@/types/business';

const flush = async (): Promise<void> => {
    await flushPromises();
    await nextTick();
    await new Promise((resolve) => setTimeout(resolve, 0));
    await nextTick();
};

let wrapper: VueWrapper | null = null;

afterEach(() => {
    wrapper?.unmount();
    wrapper = null;
    document.body.innerHTML = '';
});

describe('BusinessDetailTable', () => {
    it('renders reusable performance metrics before the related-record table', () => {
        const table: BusinessDetailTablePayload = {
            id: 'gp-performance',
            title: 'Recent performance',
            metrics: [
                { id: 'capital-accounts', label: 'Capital accounts', value: '4', icon: 'layers' },
                { id: 'latest-report', label: 'Latest report', value: '30 Jun 2036', icon: 'calendar' },
                { id: 'average-tvpi', label: 'Average TVPI', value: '1.25x', icon: 'chart' },
                { id: 'cash-flows', label: 'Calls/distribs', value: '7', icon: 'transfer' },
            ],
            columns: [{ key: 'fund', label: 'Fund', type: 'entity' }],
            rows: [],
        };

        wrapper = mount(BusinessDetailTable, {
            props: { table },
        });

        const metrics = wrapper.get('.business-detail-table__metrics');

        expect(metrics.text()).toContain('Capital accounts');
        expect(metrics.text()).toContain('30 Jun 2036');
        expect(metrics.text()).toContain('1.25x');
        expect(metrics.text()).toContain('Calls/distribs');
        expect(wrapper.get('#gp-performance').attributes('id')).toBe('gp-performance');
    });

    it('opens legacy view previews in the shared accessible drawer and restores focus on Escape', async () => {
        const table: BusinessDetailTablePayload = {
            id: 'investor-investments',
            title: 'Investments',
            columns: [
                { key: 'fund', label: 'Fund', type: 'entity' },
                { key: 'nav', label: 'NAV', type: 'amount' },
            ],
            rows: [{
                id: 'investment-1',
                cells: {
                    fund: 'Demo Alpha Growth IV',
                    nav: { value: 38200000, formatted: 'EUR 38.2m' },
                },
                actions: [{
                    type: 'view',
                    label: 'Preview investment',
                    url: '/investments/investment-1',
                    inertia: true,
                    preview: {
                        eyebrow: 'Investment preview',
                        title: '<img src=x onerror=alert(1)>',
                        subtitle: 'Demo Atlas Pension Trust',
                        summary: 'Commitment and latest reported NAV.',
                        url: '/investments/investment-1',
                        inertia: true,
                        badges: [{ label: 'Active', variant: 'success' }],
                        metrics: [{ label: 'NAV', value: 'EUR 38.2m' }],
                        fields: [{ label: 'Currency', value: 'EUR' }],
                    },
                }],
            }],
        };

        wrapper = mount(BusinessDetailTable, {
            attachTo: document.body,
            props: { table },
        });
        const trigger = wrapper.get<HTMLElement>('[aria-label="Preview investment"]');

        trigger.element.focus();
        await trigger.trigger('click');
        await flush();

        const drawer = document.body.querySelector<HTMLElement>('#investor-investments_preview_drawer');

        expect(drawer).not.toBeNull();
        expect(drawer?.getAttribute('role')).toBe('dialog');
        expect(drawer?.getAttribute('aria-modal')).toBe('true');
        expect(drawer?.textContent).toContain('<img src=x onerror=alert(1)>');
        expect(drawer?.textContent).toContain('EUR 38.2m');
        expect(drawer?.textContent).toContain('Currency');
        expect(drawer?.querySelector('img')).toBeNull();
        expect(document.activeElement?.getAttribute('aria-label')).toBe('Close');

        document.dispatchEvent(new KeyboardEvent('keydown', {
            key: 'Escape',
            bubbles: true,
            cancelable: true,
        }));
        await flush();

        expect(document.body.querySelector('#investor-investments_preview_drawer')).toBeNull();
        expect(document.activeElement).toBe(trigger.element);
    });
});
