import { fromJS } from "immutable";
import previewAndTestReducer from "../reducer";
import {
  SEARCH_CUSTOMERS_REQUESTED,
  SEARCH_CUSTOMERS_SUCCESS,
  SEARCH_CUSTOMERS_FAILURE,
  FETCH_TEST_CUSTOMERS_SUCCESS,
  FETCH_TEST_CUSTOMERS_FAILURE,
  FETCH_TEST_CUSTOMERS_REQUESTED,
  CLEAR_PREFILLED_VALUES,
  GET_PREFILLED_VALUES_REQUESTED,
  GET_PREFILLED_VALUES_SUCCESS,
  GET_PREFILLED_VALUES_FAILURE,
  FETCH_TEST_GROUPS_SUCCESS,
  FETCH_TEST_GROUPS_FAILURE,
  FETCH_TEST_GROUPS_REQUESTED,
  EXTRACT_TAGS_REQUEST,
  EXTRACT_TAGS_SUCCESS,
  EXTRACT_TAGS_FAILURE,
  UPDATE_PREVIEW_REQUEST,
  UPDATE_PREVIEW_SUCCESS,
  UPDATE_PREVIEW_FAILURE,
  SEND_TEST_MESSAGE_REQUESTED,
  SEND_TEST_MESSAGE_SUCCESS,
  SEND_TEST_MESSAGE_FAILURE,
  CLEAR_SEARCH_RESULTS,
  CREATE_MESSAGE_META_REQUESTED,
  CREATE_MESSAGE_META_SUCCESS,
  CREATE_MESSAGE_META_FAILURE,
  CLEAR_CUSTOMER_SEARCH_STATE,
} from "../constants";

describe("previewAndTestReducer", () => {
  it("should handle SEARCH_CUSTOMERS_REQUESTED action", () => {
    const state = fromJS({
      searchQuery: "test",
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,
    });
    const action = { type: SEARCH_CUSTOMERS_REQUESTED, payload: { query: "test" } };
    const expectedResult = state.set("isSearchingCustomer", true);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });

  it("should handle SEARCH_CUSTOMERS_SUCCESS action", () => {
    const state = fromJS({
      searchQuery: "",
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,
    });
    const action = { type: SEARCH_CUSTOMERS_SUCCESS, payload: { customers: [{ id: 1, name: "John Doe" }] } };
    const expectedResult = state.set("isSearchingCustomer", false).set("hasSearched", true).set("customers", [{ id: 1, name: "John Doe" }]);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });

  it("should handle SEARCH_CUSTOMERS_FAILURE action", () => {
    const state = fromJS({
      searchQuery: "",
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,
    });
    const action = { type: SEARCH_CUSTOMERS_FAILURE, payload: { error: "Search failed" } };
    const expectedResult = state.set("isSearchingCustomer", false).set("searchError", "Search failed").set("hasSearched", true).set("customers", []);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });

  it("should handle EXTRACT_TAGS_REQUEST action", () => {
    const state = fromJS({
      isExtractingTags: false,
      extractTagsError: null,
      apiWarnings: [],
      apiErrors: [],
    });
    const action = { type: EXTRACT_TAGS_REQUEST };
    const expectedResult = state.set("isExtractingTags", true).set("extractTagsError", null).set("apiWarnings", []).set("apiErrors", []).set("tags.loading", true).set("tags.error", null);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle EXTRACT_TAGS_SUCCESS action", () => {
    const state = fromJS({
      isExtractingTags: false,
      extractTagsError: null,
      apiWarnings: [],
      apiErrors: [],
    });
    const action = { type: EXTRACT_TAGS_SUCCESS, payload: { extractedtags: [{ id: 1, name: "John Doe" }] } };
    const expectedResult = state.set("isExtractingTags", false).set("extractTagsError", null).set("apiWarnings", fromJS([])).set("apiErrors", fromJS([])).set("tags.loading", false).set("tags.error", null).set("extractedTags", [{ id: 1, name: "John Doe" }]);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle EXTRACT_TAGS_FAILURE action", () => {
    const state = fromJS({
      isExtractingTags: false,
      extractTagsError: null,
      apiWarnings: [],
      apiErrors: [],
    });
    const action = { type: EXTRACT_TAGS_FAILURE, payload: { error: "Extract tags failed" } };
    const expectedResult = state.set("isExtractingTags", false).set("extractTagsError", "Extract tags failed").set("apiWarnings", []).set("apiErrors", []).set("tags.loading", false).set("tags.error", "Extract tags failed").set("extractedTags", []);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });

  it("should handle UPDATE_PREVIEW_REQUEST action", () => {
    const state = fromJS({
      isUpdatingPreview: false,
      updatePreviewError: null,
      customValues: { test: "value" },
    });
    const action = { type: UPDATE_PREVIEW_REQUEST };
    const expectedResult = state
      .set("isUpdatingPreview", true)
      .set("updatePreviewError", null)
      .set("lastCustomValues", state.get("customValues"));
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle UPDATE_PREVIEW_SUCCESS action", () => {
    const customValues = fromJS({ test: "value" });
    const state = fromJS({
      isUpdatingPreview: false,
      updatePreviewError: null,
      lastCustomValues: customValues,
    });
    const action = { type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: "test", customValues: customValues.toJS() } };
    const expectedResult = state
      .set("isUpdatingPreview", false)
      .set("updatePreviewError", null)
      .set("previewData", "test")
      .set("customValues", customValues);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle UPDATE_PREVIEW_FAILURE action", () => {
    const customValues = fromJS({ test: "value" });
    const state = fromJS({
      isUpdatingPreview: false,
      updatePreviewError: null,
      lastCustomValues: customValues,
    });
    const action = { type: UPDATE_PREVIEW_FAILURE, payload: { error: "Update preview failed", customValues: customValues.toJS() } };
    const expectedResult = state
      .set("isUpdatingPreview", false)
      .set("updatePreviewError", "Update preview failed")
      .set("previewData", null)
      .set("customValues", fromJS(action.payload.customValues));
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });

  it("should handle FETCH_TEST_CUSTOMERS_REQUESTED action", () => {
    const state = fromJS({
      testCustomers: [],
      isFetchingTestCustomers: false,
      fetchTestCustomersError: null,
    });
    const action = { type: FETCH_TEST_CUSTOMERS_REQUESTED };
    const expectedResult = state.set("isFetchingTestCustomers", true);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle FETCH_TEST_CUSTOMERS_SUCCESS action", () => {
    const state = fromJS({
      testCustomers: [],
      isFetchingTestCustomers: false,
      fetchTestCustomersError: null,
    });
    const action = { type: FETCH_TEST_CUSTOMERS_SUCCESS, payload: { customers: [{ id: 1, name: "John Doe" }] } };
    const expectedResult = state.set("isFetchingTestCustomers", false).set("testCustomers", [{ id: 1, name: "John Doe" }]);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });

  it("should handle FETCH_TEST_CUSTOMERS_FAILURE action", () => {
    const state = fromJS({
      testCustomers: [],
      isFetchingTestCustomers: false,
      fetchTestCustomersError: null,
    });
    const action = { type: FETCH_TEST_CUSTOMERS_FAILURE, payload: { error: "Fetch test customers failed" } };
    const expectedResult = state.set("isFetchingTestCustomers", false).set("fetchTestCustomersError", "Fetch test customers failed");
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle CLEAR_PREFILLED_VALUES action", () => {
    const state = fromJS({
      prefilledValues: {
        test: "test",
      },
    });
    const action = { type: CLEAR_PREFILLED_VALUES };
    const expectedResult = state.set("prefilledValues", fromJS({}));
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle GET_PREFILLED_VALUES_SUCCESS action", () => {
    const state = fromJS({
      prefilledValues: {
        test: "test",
      },
    });
    const action = { type: GET_PREFILLED_VALUES_SUCCESS, payload: { values: { test: "test" } } };
    const expectedResult = state.set("prefilledValues", fromJS({ test: "test" })).set("isFetchingPrefilledValues", false);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle GET_PREFILLED_VALUES_FAILURE action", () => {
    const state = fromJS({
      prefilledValues: {
        test: "test",
      },
    });
    const action = { type: GET_PREFILLED_VALUES_FAILURE, payload: { error: "Fetch prefilled values failed" } };
    const expectedResult = state.set("isFetchingPrefilledValues", false).set("fetchPrefilledValuesError", "Fetch prefilled values failed");
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle FETCH_TEST_GROUPS_SUCCESS action", () => {
    const state = fromJS({
      testGroups: [],
      isFetchingTestGroups: false,
      fetchTestGroupsError: null,
    });
    const action = { type: FETCH_TEST_GROUPS_SUCCESS, payload: { groups: [{ id: 1, name: "Test Group" }] } };
    const expectedResult = state.set("isFetchingTestGroups", false).set("testGroups", [{ id: 1, name: "Test Group" }]);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle FETCH_TEST_GROUPS_FAILURE action", () => {
    const state = fromJS({
      testGroups: [],
      isFetchingTestGroups: false,
      fetchTestGroupsError: null,
    });
    const action = { type: FETCH_TEST_GROUPS_FAILURE, payload: { error: "Fetch test groups failed" } };
    const expectedResult = state.set("isFetchingTestGroups", false).set("fetchTestGroupsError", "Fetch test groups failed");
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle FETCH_TEST_GROUPS_REQUESTED action", () => {
    const state = fromJS({
      testGroups: [],
      isFetchingTestGroups: false,
      fetchTestGroupsError: null,
    });
    const action = { type: FETCH_TEST_GROUPS_REQUESTED };
    const expectedResult = state.set("isFetchingTestGroups", true);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle default action", () => {
    const state = fromJS({
      testGroups: [],
      isFetchingTestGroups: false,
      fetchTestGroupsError: null,
    });
    const action = { type: "DEFAULT" };
    const expectedResult = state;
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle SEND_TEST_MESSAGE_REQUESTED action", () => {
    const state = fromJS({
      isSendingTestMessage: false,
      sendTestMessageError: null,
    });
    const action = { type: SEND_TEST_MESSAGE_REQUESTED };
    const expectedResult = state.set("isSendingTestMessage", true).set("testMessageResponse", null);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle SEND_TEST_MESSAGE_SUCCESS action", () => {
    const state = fromJS({
      isSendingTestMessage: false,
      sendTestMessageError: null,
    });
    const action = { type: SEND_TEST_MESSAGE_SUCCESS, payload: { response: "test" } };
    const expectedResult = state.set("isSendingTestMessage", false).set("sendTestMessageError", null).set("testMessageResponse", "test");
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle SEND_TEST_MESSAGE_FAILURE action", () => {
    const state = fromJS({
      isSendingTestMessage: false,
      sendTestMessageError: null,
    });
    const action = { type: SEND_TEST_MESSAGE_FAILURE, payload: { error: "Send test message failed" } };
    const expectedResult = state.set("isSendingTestMessage", false).set("sendTestMessageError", "Send test message failed").set("testMessageResponse", undefined);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle CLEAR_SEARCH_RESULTS action", () => {
    const state = fromJS({
      searchQuery: "test",
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,
    });
    const action = { type: CLEAR_SEARCH_RESULTS };
    const expectedResult = state.set("searchQuery", "").set("isSearchingCustomer", false).set("searchError", null).set("hasSearched", false).set("customers", []);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle CREATE_MESSAGE_META_REQUESTED action", () => {
    const state = fromJS({
      isCreatingMessageMeta: false,
      createMessageMetaError: null,
    });
    const action = { type: CREATE_MESSAGE_META_REQUESTED };
    const expectedResult = state.set("isCreatingMessageMeta", true);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle CREATE_MESSAGE_META_SUCCESS action", () => {
    const state = fromJS({
      isCreatingMessageMeta: false,
      createMessageMetaError: null,
    });
    const action = { type: CREATE_MESSAGE_META_SUCCESS, payload: { response: { entity: "test" } } };
    const expectedResult = state.set("isCreatingMessageMeta", false).set("createMessageMetaError", null).set("messageMetaConfigId", "test");
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle CREATE_MESSAGE_META_FAILURE action", () => {
    const state = fromJS({
      isCreatingMessageMeta: false,
      createMessageMetaError: null,
    });
    const action = { type: CREATE_MESSAGE_META_FAILURE, payload: { error: "Create message meta failed" } };
    const expectedResult = state.set("isCreatingMessageMeta", false).set("createMessageMetaError", "Create message meta failed");
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
  it("should handle CLEAR_CUSTOMER_SEARCH_STATE action", () => {
    const state = fromJS({
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,
    });
    const action = { type: CLEAR_CUSTOMER_SEARCH_STATE };
    const initialState = fromJS({
      // Search state
      searchQuery: '',
      customers: [],
      isSearchingCustomer: false,
      searchError: null,
      hasSearched: false,

      // Selected customer and tags
      extractedTags: [],
      requiredTags: [],
      optionalTags: [],
      isExtractingTags: false,
      extractTagsError: null,
      apiWarnings: [],
      apiErrors: [],

      // Preview state
      previewData: null,
      isUpdatingPreview: false,
      updatePreviewError: null,

      // Test email state
      isSendingTestMessage: false,
      sendTestMessageError: null,
      testMessageResponse: null,

      tags: {
        loading: false,
        error: null,
        required: [],
        optional: [],
      },

      // Test Customers
      testCustomers: [],
      isFetchingTestCustomers: false,
      fetchTestCustomersError: null,

      // Test Groups
      testGroups: [],
      isFetchingTestGroups: false,
      fetchTestGroupsError: null,

      messageMetaConfigId: null,
      isCreatingMessageMeta: false,
      createMessageMetaError: null,
      prefilledValues: {},
      isFetchingPrefilledValues: false,
      fetchPrefilledValuesError: null,
    });
    expect(previewAndTestReducer(state, action)).toEqual(initialState);
  });
  it("should handle GET_PREFILLED_VALUES_REQUESTED action", () => {
    const state = fromJS({
      isFetchingPrefilledValues: false,
      fetchPrefilledValuesError: null,
    });
    const action = { type: GET_PREFILLED_VALUES_REQUESTED };
    const expectedResult = state.set("isFetchingPrefilledValues", true);
    expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
  });
});
