import { createTestingPinia } from '@pinia/testing';
import { screen, cleanup } from '@testing-library/vue';
import { flushPromises } from '@vue/test-utils';
import RunDataJson from '@/features/ndv/runData/components/RunDataJson.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { useElementSize } from '@vueuse/core'; // Import the composable to mock
import { Mock } from 'vitest';
import { computed } from 'vue';
import { WorkflowIdKey } from '@/app/constants/injectionKeys';

vi.mock('@vueuse/core', async () => {
	const originalModule = await vi.importActual('@vueuse/core');

	return {
		...originalModule, // Keep all original exports
		useElementSize: vi.fn(), // Mock useElementSize
	};
});

(useElementSize as Mock).mockReturnValue({
	height: 500, // Mocked height value
	width: 300, // Mocked width value
});

const renderComponent = createComponentRenderer(RunDataJson, {
	props: {
		mappingEnabled: true,
		editMode: { enabled: false },
		inputData: [
			{
				json: {
					list: [1, 2, 3],
					record: { name: 'Joe' },
					myNumber: 123,
					myStringNumber: '456',
					myStringText: 'abc',
					nil: null,
					d: undefined,
				},
			},
		],
		node: {
			parameters: {
				keepOnlySet: false,
				values: {},
				options: {},
			},
			id: '820ea733-d8a6-4379-8e73-88a2347ea003',
			name: 'Set',
			type: 'n8n-nodes-base.set',
			typeVersion: 1,
			position: [380, 1060],
			disabled: false,
		},
	},
});

describe('RunDataJson.vue', () => {
	beforeEach(cleanup);

	it('renders json values properly', async () => {
		const { container } = renderComponent({
			global: {
				plugins: [createTestingPinia()],
				// RunDataJsonActions (lazy child) injects the workflow id on mount.
				provide: {
					[WorkflowIdKey as unknown as string]: computed(() => '1'),
				},
			},
		});
		// Resolve the defineAsyncComponent import to prevent EnvironmentTeardownError.
		// flushPromises() only drains microtasks; dynamicImportSettled() waits for the
		// dynamic import() itself to finish so it can't resolve after env teardown.
		await flushPromises();
		await vi.dynamicImportSettled();

		expect(container).toMatchSnapshot();

		expect(screen.getByText('123')).toBeInTheDocument();
		expect(screen.getByText('"456"')).toBeInTheDocument();
		expect(screen.getByText('"abc"')).toBeInTheDocument();
		expect(screen.getByText('null')).toBeInTheDocument();
		expect(screen.queryByText('undefined')).not.toBeInTheDocument();
	});
});
