import {
    mount,
    type VueWrapper,
} from '@vue/test-utils';
import { nextTick } from 'vue';
import {
    afterEach,
    beforeEach,
    describe,
    expect,
    it,
    vi,
} from 'vitest';

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

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

import FinancialRecordPage from '@/components/business/FinancialRecordPage.vue';
import type { FinancialRecordPayload } from '@/types/business';

const record = (): FinancialRecordPayload => ({
    kind: 'investment',
    title: '<strong>Demo Alpha → Atlas</strong>',
    subtitle: 'Investor-fund position',
    icon: 'trend-up',
    metrics: [
        { id: 'commitment', label: 'Commitment', value: 'EUR 1.25m', icon: 'wallet', variant: 'metric' },
        { id: 'ownership', label: 'Ownership', value: '42.50%', icon: 'percentage', variant: 'metric' },
    ],
    summary: {
        eyebrow: 'Investment',
        title: 'Demo Alpha Growth IV',
        subtitle: 'Demo Atlas Pension Trust',
        icon: 'trend-up',
        metrics: [
            { id: 'nav', label: 'Latest NAV', value: 'EUR 820k' },
            { id: 'multiple', label: 'TVPI', value: '1.31x' },
        ],
        details: [
            {
                id: 'fund',
                label: 'Fund',
                value: 'Demo Alpha Growth IV',
                link: { href: '/funds/fund-1', inertia: true },
            },
            { id: 'currency', label: 'Currency', value: 'EUR' },
        ],
    },
    sections: [
        {
            id: 'terms',
            title: '<em>Investment terms</em>',
            icon: 'document',
            fields: [
                { id: 'status', label: 'Status', value: 'Active' },
                { id: 'notes', label: 'Notes', value: '<script>unsafe()</script>', wide: true },
            ],
        },
    ],
    tabs: [
        { id: 'overview', label: 'Overview', icon: 'info' },
        { id: 'cashflows', label: 'Calls & distributions', icon: 'coins', badge: 2 },
    ],
    tables: {
        cashflows: {
            id: 'investment-cashflows',
            title: 'Calls & distributions',
            description: 'Latest cash movements for this position.',
            total: 8,
            truncated: true,
            addLink: { href: '/call-distribs/create', inertia: true, label: 'Add cash flow' },
            columns: [
                { key: 'date', label: 'Event date', type: 'date' },
                { key: 'amount', label: 'Amount', type: 'amount' },
            ],
            rows: [
                {
                    id: 'flow-1',
                    href: '/call-distribs/flow-1',
                    inertia: true,
                    cells: {
                        date: { value: '2026-07-01', formatted: '1 Jul 2026' },
                        amount: { value: 1250000, formatted: 'EUR 1.25m' },
                    },
                },
                {
                    id: 'flow-2',
                    cells: {
                        date: { value: '2026-06-01', formatted: '1 Jun 2026' },
                        amount: { value: -300000, formatted: 'EUR (300k)' },
                    },
                },
            ],
            emptyText: 'No cash flows yet.',
        },
    },
});

const commonProps = {
    backLink: { href: '/investments', inertia: true, label: 'Back to investments' },
    editLink: { href: '/investments/investment-1/edit', inertia: true },
    destroyAction: {
        href: '/investments/investment-1',
        confirm: {
            title: 'Delete investment?',
            message: 'This investment will be permanently removed.',
            label: 'Delete investment',
        },
    },
};

let wrapper: VueWrapper | null = null;

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

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

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

describe('FinancialRecordPage', () => {
    it('composes metrics, summary and escaped overview sections', () => {
        wrapper = mount(FinancialRecordPage, {
            props: { record: record(), ...commonProps },
        });

        expect(wrapper.findAll('.info-card')).toHaveLength(2);
        expect(wrapper.get('.record-summary-card').text()).toContain('TVPI');
        expect(wrapper.get('.record-summary-card a').attributes('href')).toBe('/funds/fund-1');
        expect(wrapper.get('#investment-detail-tabs_overview_panel').attributes('hidden')).toBeUndefined();
        expect(wrapper.get('.business-record-section h2').text()).toBe('<em>Investment terms</em>');
        expect(wrapper.text()).toContain('<script>unsafe()</script>');
        expect(wrapper.find('.business-record-section em').exists()).toBe(false);
        expect(wrapper.find('.business-record-section script').exists()).toBe(false);
        expect(wrapper.html()).not.toContain('data-ui-');
    });

    it('switches tabs and renders the server-formatted detail table contract', async () => {
        wrapper = mount(FinancialRecordPage, {
            attachTo: document.body,
            props: { record: record(), ...commonProps },
        });
        const tabs = wrapper.findAll<HTMLButtonElement>('[role="tab"]');

        expect(wrapper.get('[role="tablist"]').attributes('aria-label')).toBe(
            '<strong>Demo Alpha → Atlas</strong> detail sections',
        );
        expect(tabs[1]?.text()).toContain('Calls & distributions');
        expect(tabs[1]?.text()).toContain('2');

        await tabs[1]?.trigger('click');
        await nextTick();

        expect(tabs[1]?.attributes('aria-selected')).toBe('true');
        expect(wrapper.get('#investment-detail-tabs_overview_panel').attributes('hidden')).toBeDefined();
        expect(wrapper.get('#investment-detail-tabs_cashflows_panel').attributes('hidden')).toBeUndefined();
        expect(wrapper.get('[role="region"]').attributes('aria-label')).toBe('Calls & distributions');
        expect(wrapper.findAll('tbody tr')).toHaveLength(2);
        expect(wrapper.text()).toContain('EUR 1.25m');
        expect(wrapper.text()).toContain('EUR (300k)');
        expect(wrapper.text()).toContain('Showing the latest 2 of 8 records.');
        expect(wrapper.get('a[aria-label="Add cash flow"]').attributes('href')).toBe('/call-distribs/create');
    });

    it('renders overview sections directly when the record has no peer tabs', () => {
        const payload = record();

        payload.tabs = [];
        payload.tables = {};
        wrapper = mount(FinancialRecordPage, {
            props: { record: payload, ...commonProps },
        });

        expect(wrapper.find('[role="tablist"]').exists()).toBe(false);
        expect(wrapper.get('.business-record-sections').text()).toContain('Investment terms');
    });
});
