import { render, RenderOptions } from '@testing-library/react';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';

import { addRootReducer } from 'app/store/configureStore';

import { SCIMSettingsData } from '../../types';

import { SCIM_CONFIG_SOURCE } from './constants';
import { authConfigSCIMReducer } from './state/reducers';

// Mock data for testing
export const mockSCIMSettings: SCIMSettingsData = {
  userSyncEnabled: false,
  groupSyncEnabled: false,
  rejectNonProvisionedUsers: false,
  source: SCIM_CONFIG_SOURCE.FILE,
};

export const mockSCIMSettingsWithStatic: SCIMSettingsData = {
  userSyncEnabled: true,
  groupSyncEnabled: true,
  rejectNonProvisionedUsers: true,
  source: SCIM_CONFIG_SOURCE.DATABASE,
};

export const mockDomainInfo = {
  domain: 'grafana.net',
  subdomain: 'test-stack',
};

// Mock Grafana runtime
export const mockGrafanaRuntime = {
  config: {
    featureToggles: {
      enableSCIM: true,
    },
    appSubUrl: 'https://test.grafana.net',
    namespace: 'stacks-12345',
  },
  getBackendSrv: jest.fn(),
  locationService: {
    push: jest.fn(),
    reload: jest.fn(),
    getHistory: jest.fn(() => ({
      push: jest.fn(),
      replace: jest.fn(),
      go: jest.fn(),
      goBack: jest.fn(),
      goForward: jest.fn(),
      block: jest.fn(),
      listen: jest.fn(),
      location: { pathname: '/', search: '', hash: '', state: null },
    })),
  },
};

// Mock core services
export const mockContextSrv = {
  hasPermission: jest.fn().mockReturnValue(true),
};

// Custom render function with Redux store
export const renderWithRedux = (ui: React.ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => {
  addRootReducer(authConfigSCIMReducer);

  return render(ui, {
    wrapper: TestProvider,
    ...options,
  });
};

// Mock action creators
export const createMockActions = () => ({
  loadSCIMSettings: jest.fn(),
  saveSCIMSettingsDebounced: jest.fn(),
  resetSCIMSettings: jest.fn(),
  resetError: jest.fn(),
  settingsLoaded: jest.fn(),
  settingsUpdated: jest.fn(),
  setError: jest.fn(),
  setIsUpdated: jest.fn(),
});

// Setup function for common mocks
export const setupMocks = () => {
  jest.clearAllMocks();

  // Mock @grafana/runtime
  jest.doMock('@grafana/runtime', () => ({
    ...jest.requireActual('@grafana/runtime'),
    config: {
      ...jest.requireActual('@grafana/runtime').config,
      ...mockGrafanaRuntime.config,
    },
    getBackendSrv: mockGrafanaRuntime.getBackendSrv,
    locationService: mockGrafanaRuntime.locationService,
  }));

  // Mock app/core/core
  jest.doMock('app/core/core', () => ({
    contextSrv: mockContextSrv,
  }));
};

// Cleanup function
export const cleanupMocks = () => {
  jest.restoreAllMocks();
};
