/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import {
  describe,
  it,
  expect,
  vi,
  beforeEach,
  type MockedFunction,
  type Mock,
} from 'vitest';
import { act } from 'react';
import { renderHook } from '../../test-utils/render.js';
import { useApprovalModeIndicator } from './useApprovalModeIndicator.js';

import {
  Config,
  ApprovalMode,
  type Config as ActualConfigType,
} from '@google/gemini-cli-core';
import { useKeypress, type Key } from './useKeypress.js';
import { MessageType } from '../types.js';

vi.mock('./useKeypress.js');

vi.mock('@google/gemini-cli-core', async () => {
  const actualServerModule = await vi.importActual('@google/gemini-cli-core');
  return {
    ...actualServerModule,
    Config: vi.fn(),
    getAdminErrorMessage: vi.fn(
      (featureName: string) => `[Mock] ${featureName} is disabled`,
    ),
  };
});

interface MockConfigInstanceShape {
  getApprovalMode: Mock<() => ApprovalMode>;
  setApprovalMode: Mock<(value: ApprovalMode) => void>;
  isYoloModeDisabled: Mock<() => boolean>;
  isPlanEnabled: Mock<() => boolean>;
  isTrustedFolder: Mock<() => boolean>;
  getCoreTools: Mock<() => string[]>;
  getToolDiscoveryCommand: Mock<() => string | undefined>;
  getTargetDir: Mock<() => string>;
  getApiKey: Mock<() => string>;
  getModel: Mock<() => string>;
  getSandbox: Mock<() => boolean | string>;
  getDebugMode: Mock<() => boolean>;
  getQuestion: Mock<() => string | undefined>;

  getUserAgent: Mock<() => string>;
  getUserMemory: Mock<() => string>;
  getGeminiMdFileCount: Mock<() => number>;
  getToolRegistry: Mock<() => { discoverTools: Mock<() => void> }>;
  getRemoteAdminSettings: Mock<
    () => { strictModeDisabled?: boolean; mcpEnabled?: boolean } | undefined
  >;
}

type UseKeypressHandler = (key: Key) => void;

describe('useApprovalModeIndicator', () => {
  let mockConfigInstance: MockConfigInstanceShape;
  let capturedUseKeypressHandler: UseKeypressHandler;
  let mockedUseKeypress: MockedFunction<typeof useKeypress>;

  beforeEach(() => {
    vi.resetAllMocks();

    (
      Config as unknown as MockedFunction<() => MockConfigInstanceShape>
    ).mockImplementation(() => {
      const instanceGetApprovalModeMock = vi
        .fn()
        .mockReturnValue(ApprovalMode.DEFAULT);
      const instanceSetApprovalModeMock = vi.fn();

      const instance: MockConfigInstanceShape = {
        getApprovalMode: instanceGetApprovalModeMock as Mock<
          () => ApprovalMode
        >,
        setApprovalMode: instanceSetApprovalModeMock as Mock<
          (value: ApprovalMode) => void
        >,
        isYoloModeDisabled: vi.fn().mockReturnValue(false),
        isPlanEnabled: vi.fn().mockReturnValue(true),
        isTrustedFolder: vi.fn().mockReturnValue(true) as Mock<() => boolean>,
        getCoreTools: vi.fn().mockReturnValue([]) as Mock<() => string[]>,
        getToolDiscoveryCommand: vi.fn().mockReturnValue(undefined) as Mock<
          () => string | undefined
        >,
        getTargetDir: vi.fn().mockReturnValue('.') as Mock<() => string>,
        getApiKey: vi.fn().mockReturnValue('test-api-key') as Mock<
          () => string
        >,
        getModel: vi.fn().mockReturnValue('test-model') as Mock<() => string>,
        getSandbox: vi.fn().mockReturnValue(false) as Mock<
          () => boolean | string
        >,
        getDebugMode: vi.fn().mockReturnValue(false) as Mock<() => boolean>,
        getQuestion: vi.fn().mockReturnValue(undefined) as Mock<
          () => string | undefined
        >,

        getUserAgent: vi.fn().mockReturnValue('test-user-agent') as Mock<
          () => string
        >,
        getUserMemory: vi.fn().mockReturnValue('') as Mock<() => string>,
        getGeminiMdFileCount: vi.fn().mockReturnValue(0) as Mock<() => number>,
        getToolRegistry: vi
          .fn()
          .mockReturnValue({ discoverTools: vi.fn() }) as Mock<
          () => { discoverTools: Mock<() => void> }
        >,
        getRemoteAdminSettings: vi.fn().mockReturnValue(undefined) as Mock<
          () => { strictModeDisabled?: boolean } | undefined
        >,
      };
      instanceSetApprovalModeMock.mockImplementation((value: ApprovalMode) => {
        instanceGetApprovalModeMock.mockReturnValue(value);
      });
      return instance;
    });

    mockedUseKeypress = useKeypress as MockedFunction<typeof useKeypress>;
    mockedUseKeypress.mockImplementation(
      (handler: UseKeypressHandler, _options) => {
        capturedUseKeypressHandler = handler;
      },
    );

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    mockConfigInstance = new (Config as any)() as MockConfigInstanceShape;
  });

  it('should initialize with ApprovalMode.AUTO_EDIT if config.getApprovalMode returns ApprovalMode.AUTO_EDIT', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.AUTO_EDIT);
    const { result } = await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
      }),
    );
    expect(result.current).toBe(ApprovalMode.AUTO_EDIT);
    expect(mockConfigInstance.getApprovalMode).toHaveBeenCalledTimes(1);
  });

  it('should initialize with ApprovalMode.DEFAULT if config.getApprovalMode returns ApprovalMode.DEFAULT', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
    const { result } = await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
      }),
    );
    expect(result.current).toBe(ApprovalMode.DEFAULT);
    expect(mockConfigInstance.getApprovalMode).toHaveBeenCalledTimes(1);
  });

  it('should initialize with ApprovalMode.YOLO if config.getApprovalMode returns ApprovalMode.YOLO', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.YOLO);
    const { result } = await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
      }),
    );
    expect(result.current).toBe(ApprovalMode.YOLO);
    expect(mockConfigInstance.getApprovalMode).toHaveBeenCalledTimes(1);
  });

  it('should cycle the indicator and update config when Shift+Tab or Ctrl+Y is pressed', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
    const { result } = await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
      }),
    );
    expect(result.current).toBe(ApprovalMode.DEFAULT);

    // Shift+Tab cycles to AUTO_EDIT
    act(() => {
      capturedUseKeypressHandler({
        name: 'tab',
        shift: true,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.AUTO_EDIT,
    );
    expect(result.current).toBe(ApprovalMode.AUTO_EDIT);

    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.YOLO,
    );
    expect(result.current).toBe(ApprovalMode.YOLO);

    // Shift+Tab cycles back to AUTO_EDIT (from YOLO)
    act(() => {
      capturedUseKeypressHandler({
        name: 'tab',
        shift: true,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.AUTO_EDIT,
    );
    expect(result.current).toBe(ApprovalMode.AUTO_EDIT);

    // Ctrl+Y toggles YOLO
    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.YOLO,
    );
    expect(result.current).toBe(ApprovalMode.YOLO);

    // Shift+Tab from YOLO jumps to AUTO_EDIT
    act(() => {
      capturedUseKeypressHandler({
        name: 'tab',
        shift: true,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.AUTO_EDIT,
    );
    expect(result.current).toBe(ApprovalMode.AUTO_EDIT);
  });

  it('should not toggle if only one key or other keys combinations are pressed', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
      }),
    );

    act(() => {
      capturedUseKeypressHandler({
        name: 'tab',
        shift: false,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();

    act(() => {
      capturedUseKeypressHandler({
        name: 'unknown',
        shift: true,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();

    act(() => {
      capturedUseKeypressHandler({
        name: 'a',
        shift: false,
        ctrl: false,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();

    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: false } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();

    act(() => {
      capturedUseKeypressHandler({ name: 'a', ctrl: true } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();

    act(() => {
      capturedUseKeypressHandler({ name: 'y', shift: true } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();

    act(() => {
      capturedUseKeypressHandler({
        name: 'a',
        shift: true,
        ctrl: true,
      } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();
  });

  it('should update indicator when config value changes externally (useEffect dependency)', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
    const { result, rerender } = await renderHook(
      (props: { config: ActualConfigType; addItem: () => void }) =>
        useApprovalModeIndicator(props),
      {
        initialProps: {
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: vi.fn(),
        },
      },
    );
    expect(result.current).toBe(ApprovalMode.DEFAULT);

    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.AUTO_EDIT);

    rerender({
      config: mockConfigInstance as unknown as ActualConfigType,
      addItem: vi.fn(),
    });
    expect(result.current).toBe(ApprovalMode.AUTO_EDIT);
    expect(mockConfigInstance.getApprovalMode).toHaveBeenCalledTimes(3);
  });

  describe('in untrusted folders', () => {
    beforeEach(() => {
      mockConfigInstance.isTrustedFolder.mockReturnValue(false);
    });

    it('should not enable YOLO mode when Ctrl+Y is pressed', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
      mockConfigInstance.setApprovalMode.mockImplementation(() => {
        throw new Error(
          'Cannot enable privileged approval modes in an untrusted folder.',
        );
      });
      const mockAddItem = vi.fn();
      const { result } = await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      expect(result.current).toBe(ApprovalMode.DEFAULT);

      act(() => {
        capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
      });

      // We expect setApprovalMode to be called, and the error to be caught.
      expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
        ApprovalMode.YOLO,
      );
      expect(mockAddItem).toHaveBeenCalled();
      // Verify the underlying config value was not changed
      expect(mockConfigInstance.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
    });

    it('should not enable AUTO_EDIT mode when Shift+Tab is pressed', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
      mockConfigInstance.setApprovalMode.mockImplementation(() => {
        throw new Error(
          'Cannot enable privileged approval modes in an untrusted folder.',
        );
      });
      const mockAddItem = vi.fn();
      const { result } = await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      expect(result.current).toBe(ApprovalMode.DEFAULT);

      act(() => {
        capturedUseKeypressHandler({
          name: 'tab',
          shift: true,
        } as Key);
      });

      // We expect setApprovalMode to be called, and the error to be caught.
      expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
        ApprovalMode.AUTO_EDIT,
      );
      expect(mockAddItem).toHaveBeenCalled();
      // Verify the underlying config value was not changed
      expect(mockConfigInstance.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
    });

    it('should disable YOLO mode when Ctrl+Y is pressed', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.YOLO);
      const mockAddItem = vi.fn();
      await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      act(() => {
        capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
      });

      expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
        ApprovalMode.DEFAULT,
      );
      expect(mockConfigInstance.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
    });

    it('should disable AUTO_EDIT mode when Shift+Tab is pressed', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(
        ApprovalMode.AUTO_EDIT,
      );
      const mockAddItem = vi.fn();
      await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      act(() => {
        capturedUseKeypressHandler({
          name: 'tab',
          shift: true,
        } as Key);
      });

      expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
        ApprovalMode.DEFAULT,
      );
      expect(mockConfigInstance.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
    });

    it('should show a warning when trying to enable privileged modes', async () => {
      // Mock the error thrown by setApprovalMode
      const errorMessage =
        'Cannot enable privileged approval modes in an untrusted folder.';
      mockConfigInstance.setApprovalMode.mockImplementation(() => {
        throw new Error(errorMessage);
      });

      const mockAddItem = vi.fn();
      await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      // Try to enable YOLO mode
      act(() => {
        capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
      });

      expect(mockAddItem).toHaveBeenCalledWith(
        {
          type: MessageType.INFO,
          text: errorMessage,
        },
        expect.any(Number),
      );

      // Try to enable AUTO_EDIT mode
      act(() => {
        capturedUseKeypressHandler({
          name: 'tab',
          shift: true,
        } as Key);
      });

      expect(mockAddItem).toHaveBeenCalledWith(
        {
          type: MessageType.INFO,
          text: errorMessage,
        },
        expect.any(Number),
      );

      expect(mockAddItem).toHaveBeenCalledTimes(2);
    });
  });

  describe('when YOLO mode is disabled by settings', () => {
    beforeEach(() => {
      // Ensure isYoloModeDisabled returns true for these tests
      if (mockConfigInstance && mockConfigInstance.isYoloModeDisabled) {
        mockConfigInstance.isYoloModeDisabled.mockReturnValue(true);
      }
    });

    it('should not enable YOLO mode when Ctrl+Y is pressed and add an info message', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
      mockConfigInstance.getRemoteAdminSettings.mockReturnValue({
        strictModeDisabled: true,
      });
      const mockAddItem = vi.fn();
      const { result } = await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      expect(result.current).toBe(ApprovalMode.DEFAULT);

      act(() => {
        capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
      });

      // setApprovalMode should not be called because the check should return early
      expect(mockConfigInstance.setApprovalMode).not.toHaveBeenCalled();
      // An info message should be added
      expect(mockAddItem).toHaveBeenCalledWith(
        {
          type: MessageType.WARNING,
          text: 'You cannot enter YOLO mode since it is disabled in your settings.',
        },
        expect.any(Number),
      );
      // The mode should not change
      expect(result.current).toBe(ApprovalMode.DEFAULT);
    });

    it('should show admin error message when YOLO mode is disabled by admin', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
      mockConfigInstance.getRemoteAdminSettings.mockReturnValue({
        mcpEnabled: true,
      });

      const mockAddItem = vi.fn();
      await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      act(() => {
        capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
      });

      expect(mockAddItem).toHaveBeenCalledWith(
        {
          type: MessageType.WARNING,
          text: '[Mock] YOLO mode is disabled',
        },
        expect.any(Number),
      );
    });

    it('should show default error message when admin settings are empty', async () => {
      mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
      mockConfigInstance.getRemoteAdminSettings.mockReturnValue({});

      const mockAddItem = vi.fn();
      await renderHook(() =>
        useApprovalModeIndicator({
          config: mockConfigInstance as unknown as ActualConfigType,
          addItem: mockAddItem,
        }),
      );

      act(() => {
        capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
      });

      expect(mockAddItem).toHaveBeenCalledWith(
        {
          type: MessageType.WARNING,
          text: 'You cannot enter YOLO mode since it is disabled in your settings.',
        },
        expect.any(Number),
      );
    });
  });

  it('should call onApprovalModeChange when switching to YOLO mode', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);

    const mockOnApprovalModeChange = vi.fn();

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        onApprovalModeChange: mockOnApprovalModeChange,
      }),
    );

    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
    });

    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.YOLO,
    );
    expect(mockOnApprovalModeChange).toHaveBeenCalledWith(ApprovalMode.YOLO);
  });

  it('should call onApprovalModeChange when switching to AUTO_EDIT mode', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);

    const mockOnApprovalModeChange = vi.fn();

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        onApprovalModeChange: mockOnApprovalModeChange,
      }),
    );

    act(() => {
      capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
    });

    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.AUTO_EDIT,
    );
    expect(mockOnApprovalModeChange).toHaveBeenCalledWith(
      ApprovalMode.AUTO_EDIT,
    );
  });

  it('should call onApprovalModeChange when switching to DEFAULT mode', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.YOLO);

    const mockOnApprovalModeChange = vi.fn();

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        onApprovalModeChange: mockOnApprovalModeChange,
      }),
    );

    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key); // This should toggle from YOLO to DEFAULT
    });

    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.DEFAULT,
    );
    expect(mockOnApprovalModeChange).toHaveBeenCalledWith(ApprovalMode.DEFAULT);
  });

  it('should not call onApprovalModeChange when callback is not provided', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
      }),
    );

    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
    });

    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.YOLO,
    );
    // Should not throw an error when callback is not provided
  });

  it('should handle multiple mode changes correctly', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);

    const mockOnApprovalModeChange = vi.fn();

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        onApprovalModeChange: mockOnApprovalModeChange,
      }),
    );

    // Switch to YOLO
    act(() => {
      capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
    });

    // Switch to AUTO_EDIT
    act(() => {
      capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
    });

    expect(mockOnApprovalModeChange).toHaveBeenCalledTimes(2);
    expect(mockOnApprovalModeChange).toHaveBeenNthCalledWith(
      1,
      ApprovalMode.YOLO,
    );
    expect(mockOnApprovalModeChange).toHaveBeenNthCalledWith(
      2,
      ApprovalMode.AUTO_EDIT,
    );
  });

  it('should cycle to PLAN when allowPlanMode is true', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.AUTO_EDIT);

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
        allowPlanMode: true,
      }),
    );

    // AUTO_EDIT -> PLAN
    act(() => {
      capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.PLAN,
    );
  });

  it('should cycle to DEFAULT when allowPlanMode is false', async () => {
    mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.AUTO_EDIT);

    await renderHook(() =>
      useApprovalModeIndicator({
        config: mockConfigInstance as unknown as ActualConfigType,
        addItem: vi.fn(),
        allowPlanMode: false,
      }),
    );

    // AUTO_EDIT -> DEFAULT
    act(() => {
      capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
    });
    expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
      ApprovalMode.DEFAULT,
    );
  });
});
