/**
 * Customer Search Section Sagas
 */

import {
  call, put, takeLatest, all,
} from 'redux-saga/effects';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import * as Api from '../../services/api';
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,
  GET_TEST_CUSTOMERS_REQUESTED,
  GET_TEST_GROUPS_REQUESTED,
  GET_TEST_CUSTOMERS_SUCCESS,
  GET_TEST_CUSTOMERS_FAILURE,
  GET_TEST_GROUPS_SUCCESS,
  GET_TEST_GROUPS_FAILURE,
  CREATE_MESSAGE_META_REQUESTED,
  IDENTIFIER_TYPE_MOBILE,
  IDENTIFIER_TYPE_EMAIL,
  CREATE_MESSAGE_META_SUCCESS,
  CREATE_MESSAGE_META_FAILURE,
  GET_PREFILLED_VALUES_REQUESTED,
  GET_PREFILLED_VALUES_SUCCESS,
  GET_PREFILLED_VALUES_FAILURE,
  GET_SENDER_DETAILS_REQUESTED,
  GET_SENDER_DETAILS_SUCCESS,
  GET_SENDER_DETAILS_FAILURE,
  GET_WECRM_ACCOUNTS_REQUESTED,
  GET_WECRM_ACCOUNTS_SUCCESS,
  GET_WECRM_ACCOUNTS_FAILURE,
  ERROR_MESSAGES,
  CHANNELS,
} from './constants';
import { parseSenderDetailsResponse } from './DeliverySettings/utils/parseSenderDetailsResponse';

// Search Customers Saga
export function* searchCustomersSaga(action) {
  try {
    const { query } = action.payload;
    const response = yield call(Api.searchCustomers, { query });

    if (response.isError) {
      yield put({ type: SEARCH_CUSTOMERS_FAILURE, payload: { error: response.message || ERROR_MESSAGES.FAILED_TO_SEARCH_CUSTOMERS } });
    } else {
      const customers = response?.result?.data || [];
      yield put({ type: SEARCH_CUSTOMERS_SUCCESS, payload: { customers } });
    }
  } catch (error) {
    yield put({ type: SEARCH_CUSTOMERS_FAILURE, payload: { error: error.message || ERROR_MESSAGES.NETWORK_ERROR } });
  }
}

// Extract Tags Saga
export function* extractTagsSaga(action) {
  try {
    const { templateSubject, templateContent } = action.payload;

    const payload = {
      messageTitle: templateSubject || '',
      messageBody: templateContent || '',
    };

    const response = yield call(Api.extractTagsWithMetaData, payload);
    if (response?.data?.length > 0) {
      yield put({ type: EXTRACT_TAGS_SUCCESS, payload: { extractedtags: response.data } });
    } else {
      yield put({ type: EXTRACT_TAGS_FAILURE, payload: { error: response.error || ERROR_MESSAGES.FAILED_TO_EXTRACT_TAGS } });
    }
  } catch (error) {
    yield put({ type: EXTRACT_TAGS_FAILURE, payload: { error: error.message || ERROR_MESSAGES.NETWORK_ERROR } });
  }
}

// Update Preview Saga
export function* updatePreviewSaga(action) {
  try {
    // Store custom values before making the API call
    const customValues = action.payload.resolvedTags;

    const response = yield call(Api.updateEmailPreview, action.payload);
    if (response?.data) {
      yield put({
        type: UPDATE_PREVIEW_SUCCESS,
        payload: {
          previewData: response.data,
          customValues, // Pass custom values to be preserved
        },
      });
    } else {
      // Pass all errors from API response to state
      yield put({
        type: UPDATE_PREVIEW_FAILURE,
        payload: {
          error: response.error || ERROR_MESSAGES.FAILED_TO_UPDATE_PREVIEW,
          errors: response?.errors || [], // Pass all errors array from API response
          customValues, // Pass custom values even on failure
        },
      });
    }
  } catch (error) {
    // Keep catch block simple - just pass error message
    yield put({
      type: UPDATE_PREVIEW_FAILURE,
      payload: {
        error: error.message || ERROR_MESSAGES.NETWORK_ERROR,
        errors: [], // No errors array in catch block
        customValues: action.payload.resolvedTags, // Pass custom values on error
      },
    });
  }
}

// Send Test Email Saga
export function* sendTestMessageSaga(action) {
  try {
    const { callback } = action;
    const response = yield call(Api.sendTestMessage, action.payload);

    if (!response.errors) {
      yield put({ type: SEND_TEST_MESSAGE_SUCCESS, payload: { response: true } });
      callback(true);
    } else {
      yield put({ type: SEND_TEST_MESSAGE_FAILURE, payload: { response: false, error: response.errors || ERROR_MESSAGES.FAILED_TO_SEND_TEST_EMAIL } });
      callback(false);
    }
  } catch (error) {
    yield put({ type: SEND_TEST_MESSAGE_FAILURE, payload: { response: false, error: error.message || ERROR_MESSAGES.NETWORK_ERROR } });
    action.callback(false);
  }
}

export function* getBulkCustomerDetails({fetchedUserIds}) {
  try {
    const bulkCustomerDetails = yield call(Api.getBulkCustomerDetails, {
      userIds: fetchedUserIds,
    });
    const transformedData = get(bulkCustomerDetails, 'result.data').map(
      (item) => {
        const profile = get(item, 'entity.profiles[0]', {});
        if (isEmpty(profile)) {
          throw new Error(item?.errors?.[0]?.message || ERROR_MESSAGES.PROFILE_IS_EMPTY);
        }
        const mobileIdentifier = profile?.identifiers?.find(
          (identifier) => identifier.type === IDENTIFIER_TYPE_MOBILE,
        );
        const emailIdentifier = profile?.identifiers?.find(
          (identifier) => identifier.type === IDENTIFIER_TYPE_EMAIL,
        );
        const nameParts = [profile?.firstName, profile?.lastName].filter(Boolean);
        return {
          userId: item?.entity?.id,
          name: nameParts.join(' '),
          mobile: mobileIdentifier?.value,
          email: emailIdentifier?.value,
        };
      },
    );
    yield put({
      type: GET_TEST_CUSTOMERS_SUCCESS,
      payload: { customers: transformedData },
    });
  } catch (error) {
    yield put({
      type: GET_TEST_CUSTOMERS_FAILURE,
      payload: { error },
    });
  }
}

export function* fetchTestCustomersSaga() {
  try {
    const response = yield call(Api.fetchTestCustomers);
    if (response.entity) {
      const fetchedUserIds = get(response, 'entity.userIds');
      if (Array.isArray(fetchedUserIds) && fetchedUserIds.length > 0) {
        yield call(getBulkCustomerDetails, { fetchedUserIds });
      } else {
        yield put({
          type: GET_TEST_CUSTOMERS_FAILURE,
          payload: { error: ERROR_MESSAGES.NO_TEST_CUSTOMERS_FOUND },
        });
      }
    } else {
      yield put({ type: GET_TEST_CUSTOMERS_FAILURE, payload: { error: response.error || ERROR_MESSAGES.FAILED_TO_FETCH_TEST_CUSTOMERS } });
    }
  } catch (error) {
    yield put({ type: GET_TEST_CUSTOMERS_FAILURE, payload: { error: error.message } });
  }
}

export function* fetchTestGroupsSaga() {
  try {
    const response = yield call(Api.fetchTestGroups);
    if (response?.entity) {
      yield put({ type: GET_TEST_GROUPS_SUCCESS, payload: { groups: response?.entity?.userGroups } });
    } else {
      yield put({ type: GET_TEST_GROUPS_FAILURE, payload: { error: response.error || ERROR_MESSAGES.FAILED_TO_FETCH_TEST_GROUPS } });
    }
  } catch (error) {
    yield put({ type: GET_TEST_GROUPS_FAILURE, payload: { error: error.message } });
  }
}

export function* createMessageMetaSaga(action) {
  try {
    const { payload, messageMetaConfigId, callback } = action;
    let response;
    if (messageMetaConfigId) {
      response = yield call(Api.updateTestMessageMeta, { data: payload, messageMetaConfigId });
    } else {
      response = yield call(Api.createTestMessageMeta, payload);
    }
    if (!response.errors) {
      yield put({ type: CREATE_MESSAGE_META_SUCCESS, payload: { response } });
      callback(response);
    } else {
      yield put({ type: CREATE_MESSAGE_META_FAILURE, payload: { error: response.errors || ERROR_MESSAGES.FAILED_TO_CREATE_MESSAGE_META } });
    }
  } catch (error) {
    yield put({ type: CREATE_MESSAGE_META_FAILURE, payload: { error } });
  }
}

export function* getPrefilledValuesSaga(action) {
  try {
    const response = yield call(Api.updateEmailPreview, action.payload);
    if (response?.data) {
      yield put({ type: GET_PREFILLED_VALUES_SUCCESS, payload: { values: response?.data?.resolvedTagValues } });
    } else {
      // Pass all errors from API response to state
      yield put({
        type: GET_PREFILLED_VALUES_FAILURE,
        payload: {
          error: response.error || ERROR_MESSAGES.FAILED_TO_FETCH_PREFILLED_VALUES,
          errors: response?.errors || [], // Pass all errors array from API response
        },
      });
    }
  } catch (error) {
    // Keep catch block simple - just pass error message
    yield put({
      type: GET_PREFILLED_VALUES_FAILURE,
      payload: {
        error: error.message || error || ERROR_MESSAGES.NETWORK_ERROR,
        errors: [], // No errors array in catch block
      },
    });
  }
}

// Watcher Sagas
export function* watchSearchCustomers() {
  yield takeLatest(SEARCH_CUSTOMERS_REQUESTED, searchCustomersSaga);
}

export function* watchExtractTags() {
  yield takeLatest(EXTRACT_TAGS_REQUESTED, extractTagsSaga);
}

export function* watchUpdatePreview() {
  yield takeLatest(UPDATE_PREVIEW_REQUESTED, updatePreviewSaga);
}

export function* watchSendTestMessage() {
  yield takeLatest(SEND_TEST_MESSAGE_REQUESTED, sendTestMessageSaga);
}

export function* watchFetchTestCustomers() {
  yield takeLatest(GET_TEST_CUSTOMERS_REQUESTED, fetchTestCustomersSaga);
}

export function* watchFetchTestGroups() {
  yield takeLatest(GET_TEST_GROUPS_REQUESTED, fetchTestGroupsSaga);
}

export function* watchCreateMessageMeta() {
  yield takeLatest(CREATE_MESSAGE_META_REQUESTED, createMessageMetaSaga);
}

export function* watchGetPrefilledValues() {
  yield takeLatest(GET_PREFILLED_VALUES_REQUESTED, getPrefilledValuesSaga);
}

export function* getSenderDetailsSaga(action) {
  const { channel, orgUnitId } = action.payload || {};
  if (!channel) return;
  try {
    const response = yield call(Api.getSenderDetails, channel, orgUnitId ?? -1);
    if (response?.errors?.length) {
      yield put({
        type: GET_SENDER_DETAILS_FAILURE,
        payload: { channel, error: response.errors },
      });
      return;
    }
    const parsed = parseSenderDetailsResponse(channel, response);
    yield put({
      type: GET_SENDER_DETAILS_SUCCESS,
      payload: { channel, domains: parsed.domains || [] },
    });
  } catch (error) {
    yield put({
      type: GET_SENDER_DETAILS_FAILURE,
      payload: { channel, error: error.message || error },
    });
  }
}

export function* getWeCrmAccountsSaga(action) {
  const { sourceName } = action.payload || {};
  try {
    const result = yield call(Api.fetchWeCrmAccounts, sourceName || CHANNELS.WHATSAPP);
    const accounts = get(result, 'response') || get(result, 'entity') || (result?.success ? result.response : null) || [];
    const list = Array.isArray(accounts) ? accounts : (accounts && accounts.data) || [];
    yield put({
      type: GET_WECRM_ACCOUNTS_SUCCESS,
      payload: { accounts: list },
    });
  } catch (error) {
    yield put({
      type: GET_WECRM_ACCOUNTS_FAILURE,
      payload: { error: error.message || error },
    });
  }
}

export function* watchGetSenderDetails() {
  yield takeLatest(GET_SENDER_DETAILS_REQUESTED, getSenderDetailsSaga);
}

export function* watchGetWeCrmAccounts() {
  yield takeLatest(GET_WECRM_ACCOUNTS_REQUESTED, getWeCrmAccountsSaga);
}

// Root saga
export function* commonTestAndPreviewSaga() {
  yield all([
    watchSearchCustomers(),
    watchExtractTags(),
    watchUpdatePreview(),
    watchSendTestMessage(),
    watchFetchTestCustomers(),
    watchFetchTestGroups(),
    watchCreateMessageMeta(),
    watchGetPrefilledValues(),
    watchGetSenderDetails(),
    watchGetWeCrmAccounts(),
  ]);
}
