import React from 'react';
import { act, render, screen } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { RelatedListHydrationBoundary } from '../src/platform/features/record/components/RelatedListHydrationBoundary';

let observerCallback: IntersectionObserverCallback;
const observe = vi.fn();
const disconnect = vi.fn();

function ExpensiveList() {
    return <div data-testid="expensive-list">hydrated</div>;
}

describe('RelatedListHydrationBoundary', () => {
    beforeEach(() => {
        observe.mockClear();
        disconnect.mockClear();
        class MockIntersectionObserver {
            readonly root = null;
            readonly rootMargin = '';
            readonly thresholds: number[] = [];
            readonly observe = observe;
            readonly disconnect = disconnect;
            readonly unobserve = vi.fn();
            readonly takeRecords = vi.fn(() => []);

            constructor(callback: IntersectionObserverCallback) {
                observerCallback = callback;
            }
        }
        vi.stubGlobal('IntersectionObserver', MockIntersectionObserver);
    });

    afterEach(() => vi.unstubAllGlobals());

    it('keeps a stable pending-hydration heading without mounting hidden work', () => {
        const { container } = render(
            <RelatedListHydrationBoundary label="Month End ARRs">
                <ExpensiveList />
            </RelatedListHydrationBoundary>,
        );

        expect(screen.getByRole('heading', { name: 'Month End ARRs' })).toBeTruthy();
        expect(screen.queryByTestId('expensive-list')).toBeNull();
        expect(container.querySelector('[data-related-list-hydration="pending"]')).toBeTruthy();
        expect(container.querySelector('[data-related-list-hydration-margin-px="300"]')).toBeTruthy();
        expect(observe).toHaveBeenCalledOnce();
    });

    it('hydrates at the viewport boundary and never unloads again', () => {
        const view = render(
            <RelatedListHydrationBoundary label="Contracts">
                <ExpensiveList />
            </RelatedListHydrationBoundary>,
        );

        act(() => observerCallback([{ isIntersecting: true } as IntersectionObserverEntry], {} as IntersectionObserver));
        expect(screen.getByTestId('expensive-list')).toBeTruthy();

        view.rerender(
            <RelatedListHydrationBoundary label="Contracts" forceLoad={false}>
                <ExpensiveList />
            </RelatedListHydrationBoundary>,
        );
        expect(screen.getByTestId('expensive-list')).toBeTruthy();
    });

    it('hydrates an offscreen quick-link target immediately and latches it', () => {
        const view = render(
            <RelatedListHydrationBoundary label="Orgs" forceLoad>
                <ExpensiveList />
            </RelatedListHydrationBoundary>,
        );
        expect(screen.getByTestId('expensive-list')).toBeTruthy();
        expect(observe).not.toHaveBeenCalled();

        view.rerender(
            <RelatedListHydrationBoundary label="Orgs" forceLoad={false}>
                <ExpensiveList />
            </RelatedListHydrationBoundary>,
        );
        expect(screen.getByTestId('expensive-list')).toBeTruthy();
    });
});
