/**
 * Tests for CommonTestAndPreview Sagas
 *
 * Tests all saga functions with success, failure, and edge cases
 */

import {
  call, put, takeLatest, all,
} from 'redux-saga/effects';
import {
  searchCustomersSaga,
  extractTagsSaga,
  updatePreviewSaga,
  sendTestMessageSaga,
  getBulkCustomerDetails,
  fetchTestCustomersSaga,
  fetchTestGroupsSaga,
  createMessageMetaSaga,
  getPrefilledValuesSaga,
  watchSearchCustomers,
  watchExtractTags,
  watchUpdatePreview,
  watchSendTestMessage,
  watchFetchTestCustomers,
  watchFetchTestGroups,
  watchCreateMessageMeta,
  watchGetPrefilledValues,
  getSenderDetailsSaga,
  getWeCrmAccountsSaga,
  watchGetSenderDetails,
  watchGetWeCrmAccounts,
  commonTestAndPreviewSaga,
} from '../sagas';
import * as Api from '../../../services/api';
jest.mock('../DeliverySettings/utils/parseSenderDetailsResponse', () => ({
  parseSenderDetailsResponse: jest.fn((channel, response) => ({ domains: response?.entity?.[channel] || [] })),
}));
import { parseSenderDetailsResponse } from '../DeliverySettings/utils/parseSenderDetailsResponse';
import {
  SEARCH_CUSTOMERS_SUCCESS,
  SEARCH_CUSTOMERS_FAILURE,
  EXTRACT_TAGS_SUCCESS,
  EXTRACT_TAGS_FAILURE,
  UPDATE_PREVIEW_SUCCESS,
  UPDATE_PREVIEW_FAILURE,
  SEND_TEST_MESSAGE_SUCCESS,
  SEND_TEST_MESSAGE_FAILURE,
  GET_TEST_CUSTOMERS_SUCCESS,
  GET_TEST_CUSTOMERS_FAILURE,
  GET_TEST_GROUPS_SUCCESS,
  GET_TEST_GROUPS_FAILURE,
  CREATE_MESSAGE_META_SUCCESS,
  CREATE_MESSAGE_META_FAILURE,
  GET_PREFILLED_VALUES_SUCCESS,
  GET_PREFILLED_VALUES_FAILURE,
  GET_SENDER_DETAILS_SUCCESS,
  GET_SENDER_DETAILS_FAILURE,
  GET_WECRM_ACCOUNTS_SUCCESS,
  GET_WECRM_ACCOUNTS_FAILURE,
} from '../constants';

describe('CommonTestAndPreview Sagas', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('searchCustomersSaga', () => {
    it('should search customers successfully', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const customers = [
        { id: 1, name: 'John Doe', email: 'john@example.com' },
      ];
      const response = {
        isError: false,
        result: { data: customers },
      };

      const generator = searchCustomersSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.searchCustomers, { query: 'test@example.com' })
      );

      expect(generator.next(response).value).toEqual(
        put({ type: SEARCH_CUSTOMERS_SUCCESS, payload: { customers } })
      );

      expect(generator.next().done).toBe(true);
    });

    it('should handle API error response', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const response = {
        isError: true,
        message: 'Search failed',
      };

      const generator = searchCustomersSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: SEARCH_CUSTOMERS_FAILURE,
          payload: { error: 'Search failed' },
        })
      );

      expect(generator.next().done).toBe(true);
    });

    it('should handle API error without message', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const response = {
        isError: true,
      };

      const generator = searchCustomersSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: SEARCH_CUSTOMERS_FAILURE,
          payload: { error: 'Failed to search customers' },
        })
      );
    });

    it('should handle network error', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const error = new Error('Network error');

      const generator = searchCustomersSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: SEARCH_CUSTOMERS_FAILURE,
          payload: { error: 'Network error' },
        })
      );
    });

    it('should handle error without message', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const error = {};

      const generator = searchCustomersSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: SEARCH_CUSTOMERS_FAILURE,
          payload: { error: 'Network error occurred' },
        })
      );
    });

    it('should handle empty customers array', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const response = {
        isError: false,
        result: { data: [] },
      };

      const generator = searchCustomersSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({ type: SEARCH_CUSTOMERS_SUCCESS, payload: { customers: [] } })
      );
    });

    it('should handle missing result.data', () => {
      const action = {
        payload: { query: 'test@example.com' },
      };
      const response = {
        isError: false,
        result: {},
      };

      const generator = searchCustomersSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({ type: SEARCH_CUSTOMERS_SUCCESS, payload: { customers: [] } })
      );
    });
  });

  describe('extractTagsSaga', () => {
    it('should extract tags successfully', () => {
      const action = {
        payload: {
          templateSubject: 'Hello {{name}}',
          templateContent: 'Welcome {{email}}',
        },
      };
      const extractedTags = [
        { name: 'name', fullPath: 'user.name' },
        { name: 'email', fullPath: 'user.email' },
      ];
      const response = {
        data: extractedTags,
      };

      const generator = extractTagsSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.extractTagsWithMetaData, {
          messageTitle: 'Hello {{name}}',
          messageBody: 'Welcome {{email}}',
        })
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: EXTRACT_TAGS_SUCCESS,
          payload: { extractedtags: extractedTags },
        })
      );

      expect(generator.next().done).toBe(true);
    });

    it('should handle empty templateSubject', () => {
      const action = {
        payload: {
          templateSubject: '',
          templateContent: 'Welcome {{email}}',
        },
      };
      const generator = extractTagsSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.extractTagsWithMetaData, {
          messageTitle: '',
          messageBody: 'Welcome {{email}}',
        })
      );
    });

    it('should handle empty templateContent', () => {
      const action = {
        payload: {
          templateSubject: 'Hello {{name}}',
          templateContent: '',
        },
      };

      const generator = extractTagsSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.extractTagsWithMetaData, {
          messageTitle: 'Hello {{name}}',
          messageBody: '',
        })
      );
    });

    it('should handle missing templateSubject', () => {
      const action = {
        payload: {
          templateContent: 'Welcome {{email}}',
        },
      };
      const generator = extractTagsSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.extractTagsWithMetaData, {
          messageTitle: '',
          messageBody: 'Welcome {{email}}',
        })
      );
    });

    it('should handle missing templateContent', () => {
      const action = {
        payload: {
          templateSubject: 'Hello {{name}}',
        },
      };

      const generator = extractTagsSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.extractTagsWithMetaData, {
          messageTitle: 'Hello {{name}}',
          messageBody: '',
        })
      );
    });

    it('should handle empty tags array', () => {
      const action = {
        payload: {
          templateSubject: 'Hello',
          templateContent: 'Welcome',
        },
      };
      const response = {
        data: [],
        error: 'No tags found',
      };

      const generator = extractTagsSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: EXTRACT_TAGS_FAILURE,
          payload: { error: 'No tags found' },
        })
      );
    });

    it('should handle response without data', () => {
      const action = {
        payload: {
          templateSubject: 'Hello',
          templateContent: 'Welcome',
        },
      };
      const response = {
        error: 'Extraction failed',
      };

      const generator = extractTagsSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: EXTRACT_TAGS_FAILURE,
          payload: { error: 'Extraction failed' },
        })
      );
    });

    it('should handle response without error message', () => {
      const action = {
        payload: {
          templateSubject: 'Hello',
          templateContent: 'Welcome',
        },
      };
      const response = {};

      const generator = extractTagsSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: EXTRACT_TAGS_FAILURE,
          payload: { error: 'Failed to extract tags' },
        })
      );
    });

    it('should handle network error', () => {
      const action = {
        payload: {
          templateSubject: 'Hello {{name}}',
          templateContent: 'Welcome {{email}}',
        },
      };
      const error = new Error('Network error');

      const generator = extractTagsSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: EXTRACT_TAGS_FAILURE,
          payload: { error: 'Network error' },
        })
      );
    });
  });

  describe('updatePreviewSaga', () => {
    it('should update preview successfully', () => {
      const customValues = { 'user.name': 'John' };
      const action = {
        payload: {
          channel: 'EMAIL',
          resolvedBody: '<html>Test</html>',
          resolvedTags: customValues,
        },
      };
      const response = {
        data: {
          resolvedBody: '<html>Test</html>',
          resolvedTitle: 'Test Subject',
        },
      };

      const generator = updatePreviewSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.updateEmailPreview, action.payload)
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: UPDATE_PREVIEW_SUCCESS,
          payload: {
            previewData: response.data,
            customValues,
          },
        })
      );

      expect(generator.next().done).toBe(true);
    });

    it('should handle API error response with errors array', () => {
      const customValues = { 'user.name': 'John' };
      const action = {
        payload: {
          channel: 'EMAIL',
          resolvedTags: customValues,
        },
      };
      const response = {
        error: 'Update failed',
        errors: [
          { code: 7078, message: 'User profile not found' },
        ],
      };

      const generator = updatePreviewSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: UPDATE_PREVIEW_FAILURE,
          payload: {
            error: 'Update failed',
            errors: response.errors,
            customValues,
          },
        })
      );
    });

    it('should handle API error without errors array', () => {
      const customValues = { 'user.name': 'John' };
      const action = {
        payload: {
          channel: 'EMAIL',
          resolvedTags: customValues,
        },
      };
      const response = {
        error: 'Update failed',
      };

      const generator = updatePreviewSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: UPDATE_PREVIEW_FAILURE,
          payload: {
            error: 'Update failed',
            errors: [],
            customValues,
          },
        })
      );
    });

    it('should handle API error without error message', () => {
      const customValues = { 'user.name': 'John' };
      const action = {
        payload: {
          channel: 'EMAIL',
          resolvedTags: customValues,
        },
      };
      const response = {};

      const generator = updatePreviewSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: UPDATE_PREVIEW_FAILURE,
          payload: {
            error: 'Failed to update preview',
            errors: [],
            customValues,
          },
        })
      );
    });

    it('should handle network error', () => {
      const customValues = { 'user.name': 'John' };
      const action = {
        payload: {
          channel: 'EMAIL',
          resolvedTags: customValues,
        },
      };
      const error = new Error('Network error');

      const generator = updatePreviewSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: UPDATE_PREVIEW_FAILURE,
          payload: {
            error: 'Network error',
            errors: [],
            customValues,
          },
        })
      );
    });

    it('should handle error without message', () => {
      const customValues = { 'user.name': 'John' };
      const action = {
        payload: {
          channel: 'EMAIL',
          resolvedTags: customValues,
        },
      };
      const error = {};

      const generator = updatePreviewSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: UPDATE_PREVIEW_FAILURE,
          payload: {
            error: 'Network error occurred',
            errors: [],
            customValues,
          },
        })
      );
    });

    it('should handle missing resolvedTags in payload', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
        },
      };
      const response = {
        data: { resolvedBody: '<html>Test</html>' },
      };

      const generator = updatePreviewSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.updateEmailPreview, action.payload)
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: UPDATE_PREVIEW_SUCCESS,
          payload: {
            previewData: response.data,
            customValues: undefined,
          },
        })
      );
    });
  });

  describe('sendTestMessageSaga', () => {
    it('should send test message successfully', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
          recipients: ['test@example.com'],
        },
        callback,
      };
      const response = {};

      const generator = sendTestMessageSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.sendTestMessage, action.payload)
      );

      expect(generator.next(response).value).toEqual(
        put({ type: SEND_TEST_MESSAGE_SUCCESS, payload: { response: true } })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(true);
      expect(generator.next().done).toBe(true);
    });

    it('should handle API error response', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
          recipients: ['test@example.com'],
        },
        callback,
      };
      const response = {
        errors: ['Send failed'],
      };

      const generator = sendTestMessageSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: SEND_TEST_MESSAGE_FAILURE,
          payload: {
            response: false,
            error: response.errors || 'Failed to send test email',
          },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(false);
    });

    it('should handle API error without errors array', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        callback,
      };
      // Empty response without errors is treated as success
      const response = {};

      const generator = sendTestMessageSaga(action);

      generator.next();
      // Empty response (no errors) is treated as success
      expect(generator.next(response).value).toEqual(
        put({
          type: SEND_TEST_MESSAGE_SUCCESS,
          payload: {
            response: true,
          },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(true);
    });

    it('should handle network error', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        callback,
      };
      const error = new Error('Network error');

      const generator = sendTestMessageSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: SEND_TEST_MESSAGE_FAILURE,
          payload: {
            response: false,
            error: 'Network error',
          },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(false);
    });

    it('should handle error without message', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        callback,
      };
      const error = {};

      const generator = sendTestMessageSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: SEND_TEST_MESSAGE_FAILURE,
          payload: {
            response: false,
            error: 'Network error occurred',
          },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(false);
    });

    it('should handle missing callback', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        callback: undefined,
      };
      const response = {};

      const generator = sendTestMessageSaga(action);

      generator.next();
      expect(() => {
        generator.next(response);
      }).not.toThrow();
    });
  });

  describe('fetchTestCustomersSaga', () => {
    it('should fetch test customers successfully', () => {
      const response = {
        entity: {
          userIds: ['1', '2'],
        },
      };

      const generator = fetchTestCustomersSaga();

      expect(generator.next().value).toEqual(
        call(Api.fetchTestCustomers)
      );

      // Mock getBulkCustomerDetails call
      const bulkGenerator = generator.next(response);
      expect(bulkGenerator.value).toEqual(
        call(getBulkCustomerDetails, { fetchedUserIds: ['1', '2'] })
      );
    });

    it('should handle empty userIds array', () => {
      const response = {
        entity: {
          userIds: [],
        },
      };

      const generator = fetchTestCustomersSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_CUSTOMERS_FAILURE,
          payload: { error: 'No test customers found' },
        })
      );
    });

    it('should handle non-array userIds', () => {
      const response = {
        entity: {
          userIds: 'not-an-array',
        },
      };

      const generator = fetchTestCustomersSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_CUSTOMERS_FAILURE,
          payload: { error: 'No test customers found' },
        })
      );
    });

    it('should handle missing entity', () => {
      const response = {
        error: 'Failed to fetch',
      };

      const generator = fetchTestCustomersSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_CUSTOMERS_FAILURE,
          payload: { error: 'Failed to fetch' },
        })
      );
    });

    it('should handle missing error message', () => {
      const response = {};

      const generator = fetchTestCustomersSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_CUSTOMERS_FAILURE,
          payload: { error: 'Failed to fetch test customers' },
        })
      );
    });

    it('should handle network error', () => {
      const error = new Error('Network error');

      const generator = fetchTestCustomersSaga();

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: GET_TEST_CUSTOMERS_FAILURE,
          payload: { error: 'Network error' },
        })
      );
    });
  });

  describe('fetchTestGroupsSaga', () => {
    it('should fetch test groups successfully', () => {
      const response = {
        entity: {
          userGroups: [
            { id: 1, name: 'Test Group 1' },
            { id: 2, name: 'Test Group 2' },
          ],
        },
      };

      const generator = fetchTestGroupsSaga();

      expect(generator.next().value).toEqual(
        call(Api.fetchTestGroups)
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_GROUPS_SUCCESS,
          payload: { groups: response.entity.userGroups },
        })
      );

      expect(generator.next().done).toBe(true);
    });

    it('should handle missing entity', () => {
      const response = {
        error: 'Failed to fetch',
      };

      const generator = fetchTestGroupsSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_GROUPS_FAILURE,
          payload: { error: 'Failed to fetch' },
        })
      );
    });

    it('should handle missing error message', () => {
      const response = {};

      const generator = fetchTestGroupsSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_GROUPS_FAILURE,
          payload: { error: 'Failed to fetch test groups' },
        })
      );
    });

    it('should handle network error', () => {
      const error = new Error('Network error');

      const generator = fetchTestGroupsSaga();

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: GET_TEST_GROUPS_FAILURE,
          payload: { error: 'Network error' },
        })
      );
    });

    it('should handle null userGroups', () => {
      const response = {
        entity: {
          userGroups: null,
        },
      };

      const generator = fetchTestGroupsSaga();

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_TEST_GROUPS_SUCCESS,
          payload: { groups: null },
        })
      );
    });
  });

  describe('createMessageMetaSaga', () => {
    it('should create message meta successfully', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
          templateId: '123',
        },
        messageMetaConfigId: null,
        callback,
      };
      const response = {
        entity: 'config-456',
      };

      const generator = createMessageMetaSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.createTestMessageMeta, action.payload)
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: CREATE_MESSAGE_META_SUCCESS,
          payload: { response },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(response);
      expect(generator.next().done).toBe(true);
    });

    it('should update message meta when messageMetaConfigId is provided', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
          templateId: '123',
        },
        messageMetaConfigId: 'config-456',
        callback,
      };
      const response = {
        entity: 'config-456',
      };

      const generator = createMessageMetaSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.updateTestMessageMeta, {
          data: action.payload,
          messageMetaConfigId: 'config-456',
        })
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: CREATE_MESSAGE_META_SUCCESS,
          payload: { response },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(response);
    });

    it('should handle API error response', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        messageMetaConfigId: null,
        callback,
      };
      const response = {
        errors: ['Create failed'],
      };

      const generator = createMessageMetaSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: CREATE_MESSAGE_META_FAILURE,
          payload: { error: ['Create failed'] },
        })
      );

      expect(callback).not.toHaveBeenCalled();
    });

    it('should handle API error without errors array', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        messageMetaConfigId: null,
        callback,
      };
      // Empty response without errors is treated as success
      const response = {};

      const generator = createMessageMetaSaga(action);

      generator.next();
      // Empty response (no errors) is treated as success
      expect(generator.next(response).value).toEqual(
        put({
          type: CREATE_MESSAGE_META_SUCCESS,
          payload: { response },
        })
      );

      // Advance generator to execute callback
      generator.next();
      expect(callback).toHaveBeenCalledWith(response);
    });

    it('should handle network error', () => {
      const callback = jest.fn();
      const action = {
        payload: {
          channel: 'EMAIL',
        },
        messageMetaConfigId: null,
        callback,
      };
      const error = new Error('Network error');

      const generator = createMessageMetaSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: CREATE_MESSAGE_META_FAILURE,
          payload: { error },
        })
      );
    });
  });

  describe('getPrefilledValuesSaga', () => {
    it('should get prefilled values successfully', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const response = {
        data: {
          resolvedTagValues: {
            'user.name': 'John',
            'user.email': 'john@example.com',
          },
        },
      };

      const generator = getPrefilledValuesSaga(action);

      expect(generator.next().value).toEqual(
        call(Api.updateEmailPreview, action.payload)
      );

      expect(generator.next(response).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_SUCCESS,
          payload: { values: response.data.resolvedTagValues },
        })
      );

      expect(generator.next().done).toBe(true);
    });

    it('should handle API error response with errors array', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const response = {
        error: 'Fetch failed',
        errors: [
          { code: 7078, message: 'User profile not found' },
        ],
      };

      const generator = getPrefilledValuesSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_FAILURE,
          payload: {
            error: 'Fetch failed',
            errors: response.errors,
          },
        })
      );
    });

    it('should handle API error without errors array', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const response = {
        error: 'Fetch failed',
      };

      const generator = getPrefilledValuesSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_FAILURE,
          payload: {
            error: 'Fetch failed',
            errors: [],
          },
        })
      );
    });

    it('should handle API error without error message', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const response = {};

      const generator = getPrefilledValuesSaga(action);

      generator.next();
      expect(generator.next(response).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_FAILURE,
          payload: {
            error: 'Failed to fetch prefilled values',
            errors: [],
          },
        })
      );
    });

    it('should handle network error', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const error = new Error('Network error');

      const generator = getPrefilledValuesSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_FAILURE,
          payload: {
            error: 'Network error',
            errors: [],
          },
        })
      );
    });

    it('should handle error object without message', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const error = { code: 500 };

      const generator = getPrefilledValuesSaga(action);

      generator.next();
      expect(generator.throw(error).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_FAILURE,
          payload: {
            error: { code: 500 },
            errors: [],
          },
        })
      );
    });

    it('should handle string error', () => {
      const action = {
        payload: {
          channel: 'EMAIL',
          customerId: '123',
        },
      };
      const error = 'String error';

      const generator = getPrefilledValuesSaga(action);

      generator.next();
      // When error is a string, it's used directly (error.message || error || 'Network error occurred')
      expect(generator.throw(error).value).toEqual(
        put({
          type: GET_PREFILLED_VALUES_FAILURE,
          payload: {
            error: error || 'Network error occurred',
            errors: [],
          },
        })
      );
    });
  });

  describe('Watcher Sagas', () => {
    it('should watch for SEARCH_CUSTOMERS_REQUESTED', () => {
      const generator = watchSearchCustomers();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/SEARCH_CUSTOMERS_REQUESTED', searchCustomersSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for EXTRACT_TAGS_REQUESTED', () => {
      const generator = watchExtractTags();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/EXTRACT_TAGS_REQUESTED', extractTagsSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for UPDATE_PREVIEW_REQUESTED', () => {
      const generator = watchUpdatePreview();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/UPDATE_PREVIEW_REQUESTED', updatePreviewSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for SEND_TEST_MESSAGE_REQUESTED', () => {
      const generator = watchSendTestMessage();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/SEND_TEST_MESSAGE_REQUESTED', sendTestMessageSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for GET_TEST_CUSTOMERS_REQUESTED', () => {
      const generator = watchFetchTestCustomers();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/GET_TEST_CUSTOMERS_REQUESTED', fetchTestCustomersSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for GET_TEST_GROUPS_REQUESTED', () => {
      const generator = watchFetchTestGroups();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/GET_TEST_GROUPS_REQUESTED', fetchTestGroupsSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for CREATE_MESSAGE_META_REQUESTED', () => {
      const generator = watchCreateMessageMeta();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/CREATE_MESSAGE_META_REQUESTED', createMessageMetaSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for GET_PREFILLED_VALUES_REQUESTED', () => {
      const generator = watchGetPrefilledValues();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/GET_PREFILLED_VALUES_REQUESTED', getPrefilledValuesSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for GET_SENDER_DETAILS_REQUESTED', () => {
      const generator = watchGetSenderDetails();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/GET_SENDER_DETAILS_REQUESTED', getSenderDetailsSaga)
      );
      expect(generator.next().done).toBe(true);
    });

    it('should watch for GET_WECRM_ACCOUNTS_REQUESTED', () => {
      const generator = watchGetWeCrmAccounts();
      expect(generator.next().value).toEqual(
        takeLatest('app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_REQUESTED', getWeCrmAccountsSaga)
      );
      expect(generator.next().done).toBe(true);
    });
  });

  describe('getSenderDetailsSaga', () => {
    it('should fetch sender details and put SUCCESS with parsed domains', () => {
      const action = { payload: { channel: 'SMS', orgUnitId: 100 } };
      const apiResponse = { entity: { SMS: [{ id: 1, domainProperties: {} }] } };
      parseSenderDetailsResponse.mockReturnValue({ domains: [{ domainId: 1 }] });

      const generator = getSenderDetailsSaga(action);

      expect(generator.next().value).toEqual(call(Api.getSenderDetails, 'SMS', 100));
      expect(generator.next(apiResponse).value).toEqual(
        put({ type: GET_SENDER_DETAILS_SUCCESS, payload: { channel: 'SMS', domains: [{ domainId: 1 }] } })
      );
      expect(generator.next().done).toBe(true);
    });

    it('should use orgUnitId -1 when not provided', () => {
      const action = { payload: { channel: 'EMAIL' } };
      const apiResponse = { entity: { EMAIL: [] } };
      parseSenderDetailsResponse.mockReturnValue({ domains: [] });

      const generator = getSenderDetailsSaga(action);

      expect(generator.next().value).toEqual(call(Api.getSenderDetails, 'EMAIL', -1));
      generator.next(apiResponse);
      expect(generator.next().done).toBe(true);
    });

    it('should return early when channel is missing', () => {
      const action = { payload: {} };
      const generator = getSenderDetailsSaga(action);
      expect(generator.next().done).toBe(true);
    });

    it('should put FAILURE when response has errors', () => {
      const action = { payload: { channel: 'SMS' } };
      const apiResponse = { errors: [{ message: 'Forbidden' }] };

      const generator = getSenderDetailsSaga(action);
      generator.next();
      expect(generator.next(apiResponse).value).toEqual(
        put({
          type: GET_SENDER_DETAILS_FAILURE,
          payload: { channel: 'SMS', error: [{ message: 'Forbidden' }] },
        })
      );
      expect(generator.next().done).toBe(true);
    });

    it('should put FAILURE on throw', () => {
      const action = { payload: { channel: 'WHATSAPP' } };
      const generator = getSenderDetailsSaga(action);
      generator.next();
      const err = generator.throw(new Error('Network error'));
      expect(err.value).toEqual(
        put({
          type: GET_SENDER_DETAILS_FAILURE,
          payload: { channel: 'WHATSAPP', error: 'Network error' },
        })
      );
      expect(generator.next().done).toBe(true);
    });
  });

  describe('getWeCrmAccountsSaga', () => {
    it('should fetch wecrm accounts and put SUCCESS with list from response', () => {
      const action = { payload: { sourceName: 'WHATSAPP' } };
      const apiResult = { response: [{ name: 'WABA1', sourceAccountIdentifier: 'waba-1' }] };

      const generator = getWeCrmAccountsSaga(action);

      expect(generator.next().value).toEqual(call(Api.fetchWeCrmAccounts, 'WHATSAPP'));
      expect(generator.next(apiResult).value).toEqual(
        put({ type: GET_WECRM_ACCOUNTS_SUCCESS, payload: { accounts: [{ name: 'WABA1', sourceAccountIdentifier: 'waba-1' }] } })
      );
      expect(generator.next().done).toBe(true);
    });

    it('should use WHATSAPP when sourceName not provided', () => {
      const action = { payload: {} };
      const generator = getWeCrmAccountsSaga(action);
      expect(generator.next().value).toEqual(call(Api.fetchWeCrmAccounts, 'WHATSAPP'));
    });

    it('should use entity when response not present', () => {
      const action = { payload: {} };
      const apiResult = { entity: [{ name: 'Acc1' }] };

      const generator = getWeCrmAccountsSaga(action);
      generator.next();
      expect(generator.next(apiResult).value).toEqual(
        put({ type: GET_WECRM_ACCOUNTS_SUCCESS, payload: { accounts: [{ name: 'Acc1' }] } })
      );
    });

    it('should put empty array when result has no list', () => {
      const action = { payload: {} };
      const generator = getWeCrmAccountsSaga(action);
      generator.next();
      expect(generator.next({}).value).toEqual(
        put({ type: GET_WECRM_ACCOUNTS_SUCCESS, payload: { accounts: [] } })
      );
    });

    it('should put FAILURE on throw', () => {
      const action = { payload: {} };
      const generator = getWeCrmAccountsSaga(action);
      generator.next();
      const err = generator.throw(new Error('API failed'));
      expect(err.value).toEqual(
        put({ type: GET_WECRM_ACCOUNTS_FAILURE, payload: { error: 'API failed' } })
      );
      expect(generator.next().done).toBe(true);
    });
  });

  describe('commonTestAndPreviewSaga', () => {
    it('should fork all watcher sagas', () => {
      const generator = commonTestAndPreviewSaga();

      expect(generator.next().value).toEqual(
        all([
          watchSearchCustomers(),
          watchExtractTags(),
          watchUpdatePreview(),
          watchSendTestMessage(),
          watchFetchTestCustomers(),
          watchFetchTestGroups(),
          watchCreateMessageMeta(),
          watchGetPrefilledValues(),
          watchGetSenderDetails(),
          watchGetWeCrmAccounts(),
        ])
      );

      expect(generator.next().done).toBe(true);
    });
  });
});
