/**
 * Tests for CommonTestAndPreview Reducer
 *
 * Tests all reducer cases with edge cases and state transitions
 */

import { fromJS } from 'immutable';
import previewAndTestReducer from '../reducer';
import {
  SEARCH_CUSTOMERS_REQUESTED,
  SEARCH_CUSTOMERS_SUCCESS,
  SEARCH_CUSTOMERS_FAILURE,
  EXTRACT_TAGS_REQUESTED,
  EXTRACT_TAGS_SUCCESS,
  EXTRACT_TAGS_FAILURE,
  UPDATE_PREVIEW_REQUESTED,
  UPDATE_PREVIEW_SUCCESS,
  UPDATE_PREVIEW_FAILURE,
  SEND_TEST_MESSAGE_REQUESTED,
  SEND_TEST_MESSAGE_SUCCESS,
  SEND_TEST_MESSAGE_FAILURE,
  CLEAR_CUSTOMER_SEARCH_STATE,
  CLEAR_SEARCH_RESULTS,
  GET_TEST_CUSTOMERS_REQUESTED,
  GET_TEST_CUSTOMERS_SUCCESS,
  GET_TEST_CUSTOMERS_FAILURE,
  ADD_TEST_CUSTOMER,
  GET_TEST_GROUPS_REQUESTED,
  GET_TEST_GROUPS_SUCCESS,
  GET_TEST_GROUPS_FAILURE,
  CREATE_MESSAGE_META_REQUESTED,
  CREATE_MESSAGE_META_SUCCESS,
  CREATE_MESSAGE_META_FAILURE,
  GET_PREFILLED_VALUES_REQUESTED,
  GET_PREFILLED_VALUES_SUCCESS,
  GET_PREFILLED_VALUES_FAILURE,
  CLEAR_PREFILLED_VALUES,
  CLEAR_PREVIEW_ERRORS,
  GET_SENDER_DETAILS_REQUESTED,
  GET_SENDER_DETAILS_SUCCESS,
  GET_SENDER_DETAILS_FAILURE,
  GET_WECRM_ACCOUNTS_REQUESTED,
  GET_WECRM_ACCOUNTS_SUCCESS,
  GET_WECRM_ACCOUNTS_FAILURE,
  CHANNELS,
} from '../constants';

describe('previewAndTestReducer', () => {
  let initialState;

  beforeEach(() => {
    initialState = fromJS({
      searchQuery: '',
      customers: [],
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,
      extractedTags: [],
      requiredTags: [],
      optionalTags: [],
      isExtractingTags: false,
      extractTagsError: null,
      apiWarnings: [],
      apiErrors: [],
      previewData: null,
      isUpdatingPreview: false,
      updatePreviewError: null,
      updatePreviewErrors: [],
      isSendingTestMessage: false,
      sendTestMessageError: null,
      testMessageResponse: null,
      tags: {
        loading: false,
        error: null,
        required: [],
        optional: [],
      },
      testCustomers: [],
      isFetchingTestCustomers: false,
      fetchTestCustomersError: null,
      testGroups: [],
      isFetchingTestGroups: false,
      fetchTestGroupsError: null,
      messageMetaConfigId: null,
      isCreatingMessageMeta: false,
      createMessageMetaError: null,
      prefilledValues: {},
      isFetchingPrefilledValues: false,
      fetchPrefilledValuesError: null,
      fetchPrefilledValuesErrors: [],
      senderDetailsByChannel: fromJS({
        [CHANNELS.SMS]: [],
        [CHANNELS.EMAIL]: [],
        [CHANNELS.WHATSAPP]: [],
      }),
      wecrmAccounts: fromJS([]),
      isLoadingSenderDetails: false,
      fetchSenderDetailsError: null,
      fetchWeCrmAccountsError: null,
    });
  });

  describe('Initial State', () => {
    it('should return initial state when state is undefined', () => {
      const result = previewAndTestReducer(undefined, { type: 'UNKNOWN_ACTION' });
      expect(result).toEqual(initialState);
    });

    it('should return current state for unknown action', () => {
      const currentState = fromJS({ test: 'value' });
      const result = previewAndTestReducer(currentState, { type: 'UNKNOWN_ACTION' });
      expect(result).toEqual(currentState);
    });
  });

  describe('SEARCH_CUSTOMERS_REQUESTED', () => {
    it('should set search query and isSearchingCustomer to true', () => {
      const action = {
        type: SEARCH_CUSTOMERS_REQUESTED,
        payload: { query: 'test@example.com' },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('searchQuery')).toBe('test@example.com');
      expect(result.get('isSearchingCustomer')).toBe(true);
      expect(result.get('searchError')).toBeNull();
      expect(result.get('hasSearched')).toBe(false);
    });

    it('should handle empty query string', () => {
      const action = {
        type: SEARCH_CUSTOMERS_REQUESTED,
        payload: { query: '' },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('searchQuery')).toBe('');
      expect(result.get('isSearchingCustomer')).toBe(true);
    });

    it('should handle null query', () => {
      const action = {
        type: SEARCH_CUSTOMERS_REQUESTED,
        payload: { query: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('searchQuery')).toBeNull();
      expect(result.get('isSearchingCustomer')).toBe(true);
    });

    it('should reset searchError when starting new search', () => {
      const stateWithError = initialState.set('searchError', 'Previous error');
      const action = {
        type: SEARCH_CUSTOMERS_REQUESTED,
        payload: { query: 'new search' },
      };
      const result = previewAndTestReducer(stateWithError, action);

      expect(result.get('searchError')).toBeNull();
    });
  });

  describe('SEARCH_CUSTOMERS_SUCCESS', () => {
    it('should set customers and update flags', () => {
      const customers = [
        { id: 1, name: 'John Doe', email: 'john@example.com' },
        { id: 2, name: 'Jane Doe', email: 'jane@example.com' },
      ];
      const action = {
        type: SEARCH_CUSTOMERS_SUCCESS,
        payload: { customers },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('customers')).toEqual(customers);
      expect(result.get('isSearchingCustomer')).toBe(false);
      expect(result.get('searchError')).toBeNull();
      expect(result.get('hasSearched')).toBe(true);
    });

    it('should handle empty customers array', () => {
      const action = {
        type: SEARCH_CUSTOMERS_SUCCESS,
        payload: { customers: [] },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('customers')).toEqual([]);
      expect(result.get('hasSearched')).toBe(true);
    });

    it('should clear previous search error', () => {
      const stateWithError = initialState.set('searchError', 'Previous error');
      const action = {
        type: SEARCH_CUSTOMERS_SUCCESS,
        payload: { customers: [] },
      };
      const result = previewAndTestReducer(stateWithError, action);

      expect(result.get('searchError')).toBeNull();
    });
  });

  describe('SEARCH_CUSTOMERS_FAILURE', () => {
    it('should set error and clear customers', () => {
      const error = 'Search failed';
      const action = {
        type: SEARCH_CUSTOMERS_FAILURE,
        payload: { error },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('customers')).toEqual([]);
      expect(result.get('isSearchingCustomer')).toBe(false);
      expect(result.get('searchError')).toBe(error);
      expect(result.get('hasSearched')).toBe(true);
    });

    it('should handle null error', () => {
      const action = {
        type: SEARCH_CUSTOMERS_FAILURE,
        payload: { error: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('searchError')).toBeNull();
    });

    it('should clear existing customers on failure', () => {
      const stateWithCustomers = initialState.set('customers', [{ id: 1, name: 'Test' }]);
      const action = {
        type: SEARCH_CUSTOMERS_FAILURE,
        payload: { error: 'Error' },
      };
      const result = previewAndTestReducer(stateWithCustomers, action);

      expect(result.get('customers')).toEqual([]);
    });
  });

  describe('EXTRACT_TAGS_REQUESTED', () => {
    it('should set extracting flags and clear errors', () => {
      const action = { type: EXTRACT_TAGS_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isExtractingTags')).toBe(true);
      expect(result.get('extractTagsError')).toBeNull();
      expect(result.get('apiWarnings')).toEqual([]);
      expect(result.get('apiErrors')).toEqual([]);
      expect(result.get('tags.loading')).toBe(true);
      expect(result.get('tags.error')).toBeNull();
    });

    it('should clear previous errors', () => {
      const stateWithError = initialState
        .set('extractTagsError', 'Previous error')
        .set('tags.error', 'Previous tag error');
      const action = { type: EXTRACT_TAGS_REQUESTED };
      const result = previewAndTestReducer(stateWithError, action);

      expect(result.get('extractTagsError')).toBeNull();
      expect(result.get('tags.error')).toBeNull();
    });
  });

  describe('EXTRACT_TAGS_SUCCESS', () => {
    it('should set extracted tags and clear flags', () => {
      const extractedtags = [
        { name: 'firstName', fullPath: 'user.firstName' },
        { name: 'lastName', fullPath: 'user.lastName' },
      ];
      const action = {
        type: EXTRACT_TAGS_SUCCESS,
        payload: { extractedtags },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('extractedTags')).toEqual(extractedtags);
      expect(result.get('isExtractingTags')).toBe(false);
      expect(result.get('extractTagsError')).toBeNull();
      expect(result.get('tags.loading')).toBe(false);
      expect(result.get('tags.error')).toBeNull();
    });

    it('should handle empty tags array', () => {
      const action = {
        type: EXTRACT_TAGS_SUCCESS,
        payload: { extractedtags: [] },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('extractedTags')).toEqual([]);
    });

    it('should handle null tags', () => {
      const action = {
        type: EXTRACT_TAGS_SUCCESS,
        payload: { extractedtags: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('extractedTags')).toBeNull();
    });
  });

  describe('EXTRACT_TAGS_FAILURE', () => {
    it('should set error and clear tags', () => {
      const error = 'Extraction failed';
      const action = {
        type: EXTRACT_TAGS_FAILURE,
        payload: { error },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('extractedTags')).toEqual([]);
      expect(result.get('isExtractingTags')).toBe(false);
      expect(result.get('extractTagsError')).toBe(error);
      expect(result.get('apiWarnings')).toEqual([]);
      expect(result.get('apiErrors')).toEqual([]);
      expect(result.get('tags.loading')).toBe(false);
      expect(result.get('tags.error')).toBe(error);
    });

    it('should handle null error', () => {
      const action = {
        type: EXTRACT_TAGS_FAILURE,
        payload: { error: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('extractTagsError')).toBeNull();
      expect(result.get('tags.error')).toBeNull();
    });
  });

  describe('UPDATE_PREVIEW_REQUESTED', () => {
    it('should set updating flag and clear errors', () => {
      const action = { type: UPDATE_PREVIEW_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isUpdatingPreview')).toBe(true);
      expect(result.get('updatePreviewError')).toBeNull();
      expect(result.get('updatePreviewErrors')).toEqual(fromJS([]));
    });

    it('should preserve custom values during update', () => {
      const customValues = fromJS({ 'user.name': 'John' });
      const stateWithCustomValues = initialState.set('customValues', customValues);
      const action = { type: UPDATE_PREVIEW_REQUESTED };
      const result = previewAndTestReducer(stateWithCustomValues, action);

      expect(result.get('lastCustomValues')).toEqual(customValues);
    });

    it('should handle state without customValues', () => {
      const action = { type: UPDATE_PREVIEW_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('lastCustomValues')).toBeUndefined();
    });
  });

  describe('UPDATE_PREVIEW_SUCCESS', () => {
    it('should set preview data and clear flags', () => {
      const previewData = {
        resolvedBody: '<html>Test</html>',
        resolvedTitle: 'Test Subject',
      };
      const action = {
        type: UPDATE_PREVIEW_SUCCESS,
        payload: { previewData },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('previewData')).toEqual(previewData);
      expect(result.get('isUpdatingPreview')).toBe(false);
      expect(result.get('updatePreviewError')).toBeNull();
      expect(result.get('updatePreviewErrors')).toEqual(fromJS([]));
    });

    it('should restore custom values from lastCustomValues', () => {
      const customValues = fromJS({ 'user.name': 'John' });
      const stateWithLastValues = initialState.set('lastCustomValues', customValues);
      const action = {
        type: UPDATE_PREVIEW_SUCCESS,
        payload: { previewData: {} },
      };
      const result = previewAndTestReducer(stateWithLastValues, action);

      expect(result.get('customValues')).toEqual(customValues);
    });

    it('should use existing customValues if lastCustomValues is not set', () => {
      const customValues = fromJS({ 'user.name': 'Jane' });
      const stateWithCustomValues = initialState.set('customValues', customValues);
      const action = {
        type: UPDATE_PREVIEW_SUCCESS,
        payload: { previewData: {} },
      };
      const result = previewAndTestReducer(stateWithCustomValues, action);

      expect(result.get('customValues')).toEqual(customValues);
    });

    it('should handle null previewData', () => {
      const action = {
        type: UPDATE_PREVIEW_SUCCESS,
        payload: { previewData: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('previewData')).toBeNull();
    });
  });

  describe('UPDATE_PREVIEW_FAILURE', () => {
    it('should set error and clear preview data', () => {
      const error = 'Update failed';
      const errors = [{ code: 7078, message: 'User profile not found' }];
      const customValues = { 'user.name': 'John' };
      const action = {
        type: UPDATE_PREVIEW_FAILURE,
        payload: { error, errors, customValues },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('previewData')).toBeNull();
      expect(result.get('isUpdatingPreview')).toBe(false);
      expect(result.get('updatePreviewError')).toBe(error);
      expect(result.get('updatePreviewErrors')).toEqual(fromJS(errors));
      expect(result.get('customValues')).toEqual(fromJS(customValues));
    });

    it('should handle empty errors array', () => {
      const action = {
        type: UPDATE_PREVIEW_FAILURE,
        payload: { error: 'Error', errors: [], customValues: {} },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('updatePreviewErrors')).toEqual(fromJS([]));
    });

    it('should handle missing errors in payload', () => {
      const action = {
        type: UPDATE_PREVIEW_FAILURE,
        payload: { error: 'Error', customValues: {} },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('updatePreviewErrors')).toEqual(fromJS([]));
    });

    it('should handle null error', () => {
      const action = {
        type: UPDATE_PREVIEW_FAILURE,
        payload: { error: null, errors: [], customValues: {} },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('updatePreviewError')).toBeNull();
    });
  });

  describe('SEND_TEST_MESSAGE_REQUESTED', () => {
    it('should set sending flag and clear errors', () => {
      const action = { type: SEND_TEST_MESSAGE_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isSendingTestMessage')).toBe(true);
      expect(result.get('sendTestMessageError')).toBeNull();
      expect(result.get('testMessageResponse')).toBeNull();
    });

    it('should clear previous response', () => {
      const stateWithResponse = initialState.set('testMessageResponse', { success: true });
      const action = { type: SEND_TEST_MESSAGE_REQUESTED };
      const result = previewAndTestReducer(stateWithResponse, action);

      expect(result.get('testMessageResponse')).toBeNull();
    });
  });

  describe('SEND_TEST_MESSAGE_SUCCESS', () => {
    it('should set response and clear flags', () => {
      const response = { messageId: '123', status: 'sent' };
      const action = {
        type: SEND_TEST_MESSAGE_SUCCESS,
        payload: { response },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('testMessageResponse')).toEqual(response);
      expect(result.get('isSendingTestMessage')).toBe(false);
      expect(result.get('sendTestMessageError')).toBeNull();
    });

    it('should handle null response', () => {
      const action = {
        type: SEND_TEST_MESSAGE_SUCCESS,
        payload: { response: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('testMessageResponse')).toBeNull();
    });
  });

  describe('SEND_TEST_MESSAGE_FAILURE', () => {
    it('should set error and response', () => {
      const error = 'Send failed';
      const response = { status: 'failed' };
      const action = {
        type: SEND_TEST_MESSAGE_FAILURE,
        payload: { error, response },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('testMessageResponse')).toEqual(response);
      expect(result.get('isSendingTestMessage')).toBe(false);
      expect(result.get('sendTestMessageError')).toBe(error);
    });

    it('should handle null error', () => {
      const action = {
        type: SEND_TEST_MESSAGE_FAILURE,
        payload: { error: null, response: {} },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('sendTestMessageError')).toBeNull();
    });
  });

  describe('CLEAR_SEARCH_RESULTS', () => {
    it('should clear search results and reset flags', () => {
      const stateWithResults = initialState
        .set('customers', [{ id: 1, name: 'Test' }])
        .set('searchQuery', 'test')
        .set('hasSearched', true)
        .set('searchError', 'Error');
      const action = { type: CLEAR_SEARCH_RESULTS };
      const result = previewAndTestReducer(stateWithResults, action);

      expect(result.get('customers')).toEqual([]);
      expect(result.get('searchQuery')).toBe('');
      expect(result.get('hasSearched')).toBe(false);
      expect(result.get('searchError')).toBeNull();
    });
  });

  describe('CLEAR_CUSTOMER_SEARCH_STATE', () => {
    it('should reset to initial state', () => {
      const modifiedState = initialState
        .set('customers', [{ id: 1 }])
        .set('searchQuery', 'test')
        .set('extractedTags', [{ name: 'tag' }])
        .set('previewData', {});
      const action = { type: CLEAR_CUSTOMER_SEARCH_STATE };
      const result = previewAndTestReducer(modifiedState, action);

      expect(result).toEqual(initialState);
    });
  });

  describe('GET_TEST_CUSTOMERS_REQUESTED', () => {
    it('should set fetching flag and clear error', () => {
      const action = { type: GET_TEST_CUSTOMERS_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingTestCustomers')).toBe(true);
      expect(result.get('fetchTestCustomersError')).toBeNull();
    });
  });

  describe('GET_TEST_CUSTOMERS_SUCCESS', () => {
    it('should set customers and clear flag', () => {
      const customers = [{ id: 1, name: 'Test Customer' }];
      const action = {
        type: GET_TEST_CUSTOMERS_SUCCESS,
        payload: { customers },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('testCustomers')).toEqual(customers);
      expect(result.get('isFetchingTestCustomers')).toBe(false);
    });

    it('should handle empty customers array', () => {
      const action = {
        type: GET_TEST_CUSTOMERS_SUCCESS,
        payload: { customers: [] },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('testCustomers')).toEqual([]);
    });
  });

  describe('GET_TEST_CUSTOMERS_FAILURE', () => {
    it('should set error and clear flag', () => {
      const error = 'Fetch failed';
      const action = {
        type: GET_TEST_CUSTOMERS_FAILURE,
        payload: { error },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingTestCustomers')).toBe(false);
      expect(result.get('fetchTestCustomersError')).toBe(error);
    });
  });

  describe('ADD_TEST_CUSTOMER', () => {
    it('should add new customer to testCustomers list', () => {
      const customer = {
        userId: 'cust-1',
        customerId: 'cust-1',
        name: 'John',
        email: 'john@example.com',
        mobile: '',
      };
      const action = {
        type: ADD_TEST_CUSTOMER,
        payload: { customer },
      };
      const result = previewAndTestReducer(initialState, action);

      const list = result.get('testCustomers');
      expect(Array.isArray(list) ? list.length : list.size).toBe(1);
      const first = Array.isArray(list) ? list[0] : list.get(0);
      const id = first.userId != null ? first.userId : first.get('userId');
      const name = first.name != null ? first.name : first.get('name');
      expect(id).toBe('cust-1');
      expect(name).toBe('John');
    });

    it('should not add duplicate customer when userId already in list', () => {
      const existing = fromJS([
        { userId: 'cust-1', customerId: 'cust-1', name: 'John', email: 'john@example.com', mobile: '' },
      ]);
      const stateWithCustomer = initialState.set('testCustomers', existing);
      const customer = {
        userId: 'cust-1',
        customerId: 'cust-1',
        name: 'John Updated',
        email: 'john@example.com',
        mobile: '',
      };
      const action = {
        type: ADD_TEST_CUSTOMER,
        payload: { customer },
      };
      const result = previewAndTestReducer(stateWithCustomer, action);

      const list = result.get('testCustomers');
      expect(Array.isArray(list) ? list.length : list.size).toBe(1);
      const first = Array.isArray(list) ? list[0] : list.get(0);
      const name = first.name != null ? first.name : first.get('name');
      expect(name).toBe('John');
    });

    it('should use customerId when userId is missing', () => {
      const customer = {
        customerId: 'cust-2',
        name: 'Jane',
        email: 'jane@example.com',
        mobile: '',
      };
      const action = {
        type: ADD_TEST_CUSTOMER,
        payload: { customer },
      };
      const result = previewAndTestReducer(initialState, action);

      const list = result.get('testCustomers');
      expect(Array.isArray(list) ? list.length : list.size).toBe(1);
      const first = Array.isArray(list) ? list[0] : list.get(0);
      const id = first.customerId != null ? first.customerId : first.get('customerId');
      expect(id).toBe('cust-2');
    });
  });

  describe('GET_TEST_GROUPS_REQUESTED', () => {
    it('should set fetching flag and clear error', () => {
      const action = { type: GET_TEST_GROUPS_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingTestGroups')).toBe(true);
      expect(result.get('fetchTestGroupsError')).toBeNull();
    });
  });

  describe('GET_TEST_GROUPS_SUCCESS', () => {
    it('should set groups and clear flag', () => {
      const groups = [{ id: 1, name: 'Test Group' }];
      const action = {
        type: GET_TEST_GROUPS_SUCCESS,
        payload: { groups },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('testGroups')).toEqual(groups);
      expect(result.get('isFetchingTestGroups')).toBe(false);
    });
  });

  describe('GET_TEST_GROUPS_FAILURE', () => {
    it('should set error and clear flag', () => {
      const error = 'Fetch failed';
      const action = {
        type: GET_TEST_GROUPS_FAILURE,
        payload: { error },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingTestGroups')).toBe(false);
      expect(result.get('fetchTestGroupsError')).toBe(error);
    });
  });

  describe('CREATE_MESSAGE_META_REQUESTED', () => {
    it('should set creating flag and clear error', () => {
      const action = { type: CREATE_MESSAGE_META_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isCreatingMessageMeta')).toBe(true);
      expect(result.get('createMessageMetaError')).toBeNull();
    });
  });

  describe('CREATE_MESSAGE_META_SUCCESS', () => {
    it('should set messageMetaConfigId and clear flag', () => {
      const entity = 'config-123';
      const action = {
        type: CREATE_MESSAGE_META_SUCCESS,
        payload: { response: { entity } },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isCreatingMessageMeta')).toBe(false);
      expect(result.get('messageMetaConfigId')).toBe(entity);
    });

    it('should handle null entity', () => {
      const action = {
        type: CREATE_MESSAGE_META_SUCCESS,
        payload: { response: { entity: null } },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('messageMetaConfigId')).toBeNull();
    });
  });

  describe('CREATE_MESSAGE_META_FAILURE', () => {
    it('should set error and clear flag', () => {
      const error = 'Create failed';
      const action = {
        type: CREATE_MESSAGE_META_FAILURE,
        payload: { error },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isCreatingMessageMeta')).toBe(false);
      expect(result.get('createMessageMetaError')).toBe(error);
    });
  });

  describe('GET_PREFILLED_VALUES_REQUESTED', () => {
    it('should set fetching flag and clear errors', () => {
      const action = { type: GET_PREFILLED_VALUES_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingPrefilledValues')).toBe(true);
      expect(result.get('fetchPrefilledValuesError')).toBeNull();
      expect(result.get('fetchPrefilledValuesErrors')).toEqual(fromJS([]));
    });
  });

  describe('GET_PREFILLED_VALUES_SUCCESS', () => {
    it('should set prefilled values and clear flags', () => {
      const values = { 'user.name': 'John', 'user.email': 'john@example.com' };
      const action = {
        type: GET_PREFILLED_VALUES_SUCCESS,
        payload: { values },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingPrefilledValues')).toBe(false);
      expect(result.get('prefilledValues')).toEqual(fromJS(values));
      expect(result.get('fetchPrefilledValuesErrors')).toEqual(fromJS([]));
    });

    it('should handle empty values object', () => {
      const action = {
        type: GET_PREFILLED_VALUES_SUCCESS,
        payload: { values: {} },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('prefilledValues')).toEqual(fromJS({}));
    });

    it('should handle null values', () => {
      const action = {
        type: GET_PREFILLED_VALUES_SUCCESS,
        payload: { values: null },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('prefilledValues')).toEqual(fromJS(null));
    });
  });

  describe('GET_PREFILLED_VALUES_FAILURE', () => {
    it('should set error and errors array', () => {
      const error = 'Fetch failed';
      const errors = [{ code: 7078, message: 'User profile not found' }];
      const action = {
        type: GET_PREFILLED_VALUES_FAILURE,
        payload: { error, errors },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isFetchingPrefilledValues')).toBe(false);
      expect(result.get('fetchPrefilledValuesError')).toBe(error);
      expect(result.get('fetchPrefilledValuesErrors')).toEqual(fromJS(errors));
    });

    it('should handle empty errors array', () => {
      const action = {
        type: GET_PREFILLED_VALUES_FAILURE,
        payload: { error: 'Error', errors: [] },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('fetchPrefilledValuesErrors')).toEqual(fromJS([]));
    });

    it('should handle missing errors in payload', () => {
      const action = {
        type: GET_PREFILLED_VALUES_FAILURE,
        payload: { error: 'Error' },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('fetchPrefilledValuesErrors')).toEqual(fromJS([]));
    });
  });

  describe('CLEAR_PREFILLED_VALUES', () => {
    it('should clear prefilled values', () => {
      const stateWithValues = initialState.set('prefilledValues', fromJS({ 'user.name': 'John' }));
      const action = { type: CLEAR_PREFILLED_VALUES };
      const result = previewAndTestReducer(stateWithValues, action);

      expect(result.get('prefilledValues')).toEqual(fromJS({}));
    });
  });

  describe('GET_SENDER_DETAILS_REQUESTED', () => {
    it('should set isLoadingSenderDetails to true and clear fetchSenderDetailsError', () => {
      const action = {
        type: GET_SENDER_DETAILS_REQUESTED,
        payload: { channel: CHANNELS.SMS, orgUnitId: 123 },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isLoadingSenderDetails')).toBe(true);
      expect(result.get('fetchSenderDetailsError')).toBeNull();
    });
  });

  describe('GET_SENDER_DETAILS_SUCCESS', () => {
    it('should store domains for channel and set loading to false', () => {
      const domains = [
        { domainId: 1, domainName: 'Domain 1', gsmSenders: [] },
      ];
      const action = {
        type: GET_SENDER_DETAILS_SUCCESS,
        payload: { channel: CHANNELS.SMS, domains },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.getIn(['senderDetailsByChannel', CHANNELS.SMS])).toEqual(fromJS(domains));
      expect(result.get('isLoadingSenderDetails')).toBe(false);
      expect(result.get('fetchSenderDetailsError')).toBeNull();
    });

    it('should return state unchanged when channel is missing', () => {
      const action = {
        type: GET_SENDER_DETAILS_SUCCESS,
        payload: { domains: [] },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result).toEqual(initialState);
    });
  });

  describe('GET_SENDER_DETAILS_FAILURE', () => {
    it('should set loading to false and store error', () => {
      const action = {
        type: GET_SENDER_DETAILS_FAILURE,
        payload: { channel: CHANNELS.EMAIL, error: 'Failed to fetch' },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('isLoadingSenderDetails')).toBe(false);
      expect(result.get('fetchSenderDetailsError')).toBe('Failed to fetch');
    });
  });

  describe('GET_WECRM_ACCOUNTS_REQUESTED', () => {
    it('should clear fetchWeCrmAccountsError', () => {
      const stateWithError = initialState.set('fetchWeCrmAccountsError', 'Error');
      const action = {
        type: GET_WECRM_ACCOUNTS_REQUESTED,
        payload: { sourceName: 'WHATSAPP' },
      };
      const result = previewAndTestReducer(stateWithError, action);

      expect(result.get('fetchWeCrmAccountsError')).toBeNull();
    });
  });

  describe('GET_WECRM_ACCOUNTS_SUCCESS', () => {
    it('should store wecrm accounts and clear error', () => {
      const accounts = [{ name: 'Account 1', sourceAccountIdentifier: 'acc-1' }];
      const action = {
        type: GET_WECRM_ACCOUNTS_SUCCESS,
        payload: { accounts },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('wecrmAccounts')).toEqual(fromJS(accounts));
      expect(result.get('fetchWeCrmAccountsError')).toBeNull();
    });

    it('should handle empty accounts', () => {
      const action = {
        type: GET_WECRM_ACCOUNTS_SUCCESS,
        payload: { accounts: [] },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('wecrmAccounts')).toEqual(fromJS([]));
    });
  });

  describe('GET_WECRM_ACCOUNTS_FAILURE', () => {
    it('should store fetchWeCrmAccountsError', () => {
      const action = {
        type: GET_WECRM_ACCOUNTS_FAILURE,
        payload: { error: 'WeCRM fetch failed' },
      };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('fetchWeCrmAccountsError')).toBe('WeCRM fetch failed');
    });
  });

  describe('CLEAR_PREVIEW_ERRORS', () => {
    it('should clear all preview-related errors', () => {
      const stateWithErrors = initialState
        .set('updatePreviewError', 'Preview error')
        .set('updatePreviewErrors', fromJS([{ code: 7078 }]))
        .set('fetchPrefilledValuesError', 'Prefilled error')
        .set('fetchPrefilledValuesErrors', fromJS([{ code: 7078 }]));
      const action = { type: CLEAR_PREVIEW_ERRORS };
      const result = previewAndTestReducer(stateWithErrors, action);

      expect(result.get('updatePreviewError')).toBeNull();
      expect(result.get('updatePreviewErrors')).toEqual(fromJS([]));
      expect(result.get('fetchPrefilledValuesError')).toBeNull();
      expect(result.get('fetchPrefilledValuesErrors')).toEqual(fromJS([]));
    });
  });

  describe('Edge Cases', () => {
    it('should handle missing payload in action', () => {
      const action = { type: SEARCH_CUSTOMERS_REQUESTED };
      // The reducer will try to access action.payload.query which will be undefined
      // This will throw an error, so we verify the error is thrown
      expect(() => {
        previewAndTestReducer(initialState, action);
      }).toThrow();
      // Alternatively, test with a payload that has undefined query
      const actionWithPayload = {
        type: SEARCH_CUSTOMERS_REQUESTED,
        payload: { query: undefined },
      };
      const result = previewAndTestReducer(initialState, actionWithPayload);
      expect(result).toBeDefined();
      expect(result.get('isSearchingCustomer')).toBe(true);
    });

    it('should handle nested state updates correctly', () => {
      const action = { type: EXTRACT_TAGS_REQUESTED };
      const result = previewAndTestReducer(initialState, action);

      expect(result.get('tags.loading')).toBe(true);
      expect(result.get('tags.error')).toBeNull();
    });

    it('should handle multiple sequential actions', () => {
      let state = initialState;

      // Request search
      state = previewAndTestReducer(state, {
        type: SEARCH_CUSTOMERS_REQUESTED,
        payload: { query: 'test' },
      });
      expect(state.get('isSearchingCustomer')).toBe(true);

      // Success
      state = previewAndTestReducer(state, {
        type: SEARCH_CUSTOMERS_SUCCESS,
        payload: { customers: [{ id: 1 }] },
      });
      expect(state.get('isSearchingCustomer')).toBe(false);
      // customers is set directly from payload, so check if it's an Immutable List or plain array
      const customers = state.get('customers');
      expect(customers).toBeDefined();
      // Check size if Immutable List, or length if plain array
      const customerCount = customers && (customers.size !== undefined ? customers.size : customers.length);
      expect(customerCount).toBe(1);

      // Clear results
      state = previewAndTestReducer(state, { type: CLEAR_SEARCH_RESULTS });
      const clearedCustomers = state.get('customers');
      expect(clearedCustomers && (clearedCustomers.size || clearedCustomers.length)).toBe(0);
    });

    it('should handle Immutable.js state correctly', () => {
      const action = {
        type: SEARCH_CUSTOMERS_SUCCESS,
        payload: { customers: [{ id: 1 }] },
      };
      const result = previewAndTestReducer(initialState, action);

      // Verify it's still an Immutable object
      expect(result.get).toBeDefined();
      expect(result.set).toBeDefined();
      // customers is set as a plain array, so it may not have toJS method
      // Check if it's an Immutable collection or a plain array
      const customers = result.get('customers');
      expect(customers).toBeDefined();
      // If it's an Immutable List, it will have toJS, otherwise it's a plain array
      if (customers && typeof customers.toJS === 'function') {
        expect(customers.toJS).toBeDefined();
      } else {
        // Plain array is also acceptable
        expect(Array.isArray(customers)).toBe(true);
      }
    });
  });
});
