/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { renderHook } from '../../test-utils/render.js';
import { vi } from 'vitest';
import { useFlickerDetector } from './useFlickerDetector.js';
import { useConfig } from '../contexts/ConfigContext.js';
import { recordFlickerFrame } from 'sixth-cli-core';
import {} from 'sixth-cli-core';
import { measureElement } from 'ink';
import { useUIState } from '../contexts/UIStateContext.js';
import { appEvents, AppEvent } from '../../utils/events.js';
// Mock dependencies
vi.mock('../contexts/ConfigContext.js');
vi.mock('../contexts/UIStateContext.js');
vi.mock('sixth-cli-core', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        recordFlickerFrame: vi.fn(),
        GEMINI_DIR: '.gemini',
    };
});
vi.mock('ink', async (importOriginal) => {
    const original = await importOriginal();
    return {
        ...original,
        measureElement: vi.fn(),
    };
});
vi.mock('../../utils/events.js', () => ({
    appEvents: {
        emit: vi.fn(),
    },
    AppEvent: {
        Flicker: 'flicker',
    },
}));
const mockUseConfig = useConfig;
const mockUseUIState = useUIState;
const mockRecordFlickerFrame = recordFlickerFrame;
const mockMeasureElement = measureElement;
const mockAppEventsEmit = appEvents.emit;
describe('useFlickerDetector', () => {
    const mockConfig = {};
    let mockRef;
    beforeEach(() => {
        mockUseConfig.mockReturnValue(mockConfig);
        mockRef = { current: { yogaNode: {} } };
        // Default UI state
        mockUseUIState.mockReturnValue({ constrainHeight: true });
    });
    afterEach(() => {
        vi.clearAllMocks();
    });
    it('should not record a flicker when height is less than terminal height', () => {
        mockMeasureElement.mockReturnValue({ width: 80, height: 20 });
        renderHook(() => useFlickerDetector(mockRef, 25));
        expect(mockRecordFlickerFrame).not.toHaveBeenCalled();
        expect(mockAppEventsEmit).not.toHaveBeenCalled();
    });
    it('should not record a flicker when height is equal to terminal height', () => {
        mockMeasureElement.mockReturnValue({ width: 80, height: 25 });
        renderHook(() => useFlickerDetector(mockRef, 25));
        expect(mockRecordFlickerFrame).not.toHaveBeenCalled();
        expect(mockAppEventsEmit).not.toHaveBeenCalled();
    });
    it('should record a flicker when height is greater than terminal height and height is constrained', () => {
        mockMeasureElement.mockReturnValue({ width: 80, height: 30 });
        renderHook(() => useFlickerDetector(mockRef, 25));
        expect(mockRecordFlickerFrame).toHaveBeenCalledTimes(1);
        expect(mockRecordFlickerFrame).toHaveBeenCalledWith(mockConfig);
        expect(mockAppEventsEmit).toHaveBeenCalledTimes(1);
        expect(mockAppEventsEmit).toHaveBeenCalledWith(AppEvent.Flicker);
    });
    it('should NOT record a flicker when height is greater than terminal height but height is NOT constrained', () => {
        // Override default UI state for this test
        mockUseUIState.mockReturnValue({ constrainHeight: false });
        mockMeasureElement.mockReturnValue({ width: 80, height: 30 });
        renderHook(() => useFlickerDetector(mockRef, 25));
        expect(mockRecordFlickerFrame).not.toHaveBeenCalled();
        expect(mockAppEventsEmit).not.toHaveBeenCalled();
    });
    it('should not check for flicker if the ref is not set', () => {
        mockRef.current = null;
        mockMeasureElement.mockReturnValue({ width: 80, height: 30 });
        renderHook(() => useFlickerDetector(mockRef, 25));
        expect(mockMeasureElement).not.toHaveBeenCalled();
        expect(mockRecordFlickerFrame).not.toHaveBeenCalled();
        expect(mockAppEventsEmit).not.toHaveBeenCalled();
    });
    it('should re-evaluate on re-render', () => {
        // Start with a valid height
        mockMeasureElement.mockReturnValue({ width: 80, height: 20 });
        const { rerender } = renderHook(() => useFlickerDetector(mockRef, 25));
        expect(mockRecordFlickerFrame).not.toHaveBeenCalled();
        // Now, simulate a re-render where the height is too great
        mockMeasureElement.mockReturnValue({ width: 80, height: 30 });
        rerender();
        expect(mockRecordFlickerFrame).toHaveBeenCalledTimes(1);
        expect(mockAppEventsEmit).toHaveBeenCalledTimes(1);
    });
});
//# sourceMappingURL=useFlickerDetector.test.js.map