import {
  call, put, takeLatest, all,
} from 'redux-saga/effects';
import isEmpty from 'lodash/isEmpty';
import get from 'lodash/get';
import * as Api from '../../services/api';
import { pollAssetStatus } from '../../sagas/assetPolling';
import { createPollingConfig } from '../../utils/asyncAssetUpload';
import { ASSET_STATUS } from '../../utils/assetStatusConstants';
import {
  TEMPLATE_CREATE_REQUEST,
  TEMPLATE_CREATE_SUCCESS,
  TEMPLATE_CREATE_FAILURE,
  WHATSAPP,
  GET_TEMPLATE_DETAILS_REQUEST,
  GET_TEMPLATE_DETAILS_SUCCESS,
  GET_TEMPLATE_DETAILS_FAILURE,
  UPLOAD_WHATSAPP_ASSET_REQUEST,
  UPLOAD_WHATSAPP_ASSET_SUCCESS,
  UPLOAD_WHATSAPP_ASSET_FAILURE,
  UPLOAD_WHATSAPP_ASSET_PROCESSING,
  UPLOAD_WHATSAPP_ASSET_COMPLETED,
  UPLOAD_WHATSAPP_ASSET_FAILED,
  UPLOAD_WHATSAPP_ASSET_TIMEOUT,
  URL_META_TAGS_REQUEST,
  URL_META_TAGS_SUCCESS,
  URL_META_TAGS_FAILURE,
} from './constants';

export function* uploadWhatsappAsset(params) {
  try {
    const result = yield call(Api.uploadFile, params);
    const responseData = result.response || {};
    const statusCode = result?.status?.code || result?.statusCode || 200;
    
    if (statusCode === 202 || responseData?.processingStatus === ASSET_STATUS.PROCESSING) {
      // Async flow - extract assetId first before dispatching any actions
      const assetId = responseData.assetId || responseData.asset?._id;
      const templateType = params.templateType; // Index for reducer state key (e.g., 0)
      // Get asset type from params, fallback to asset response, then default to 'image'
      const assetType = params.assetType || responseData.asset?.type?.toLowerCase() || 'image';
      
      if (assetId) {
        // Only dispatch processing action and start polling when we have a valid assetId
        yield put({
          type: UPLOAD_WHATSAPP_ASSET_PROCESSING,
          payload: {
            assetId,
            asset: responseData.asset,
            processingStatus: ASSET_STATUS.PROCESSING
          }
        });
        
        // P4.4: Start polling using centralized saga with generic polling config
        const actionTypes = {
          COMPLETED: UPLOAD_WHATSAPP_ASSET_COMPLETED,
          FAILED: UPLOAD_WHATSAPP_ASSET_FAILED,
          TIMEOUT: UPLOAD_WHATSAPP_ASSET_TIMEOUT,
        };
        const pollingConfig = createPollingConfig(assetType, assetId, actionTypes, templateType);
        yield call(pollAssetStatus, pollingConfig);
      } else {
        // No assetId returned - dispatch failure to prevent UI from being stuck in processing state
        const errorMessage = 'Asset upload initiated but no asset ID was returned from the server. Unable to track processing status.';
        yield put({
          type: UPLOAD_WHATSAPP_ASSET_FAILED,
          payload: {
            assetId: undefined,
            error: errorMessage,
          },
          templateType,
        });
      }
    } else {
      // Sync flow (201) - existing behavior unchanged
      yield put({
        type: UPLOAD_WHATSAPP_ASSET_SUCCESS,
        data: responseData.asset,
        statusCode,
        templateType: params.templateType,
      });
    }
  } catch (error) {
    yield put({ type: UPLOAD_WHATSAPP_ASSET_FAILURE, error });
  }
}
function* watchUploadWhatsappAsset() {
  yield takeLatest(
    UPLOAD_WHATSAPP_ASSET_REQUEST,
    uploadWhatsappAsset,
  );
}

export function* sendForApprovalCreate({ payload, callback, gupshupMediaFile }) {
  let errorMsg;
  try {
    const result = yield call(Api.createWhatsappTemplate, { payload, gupshupMediaFile });
    if (result?.status?.code && result.status.code >= 400) {
      const { message, status } = result || {};
      const errorMessageObj = get(message?.error, 'errorMessage', {});
      if (!isEmpty(errorMessageObj)) {
        try {
          // If the errorMessageObj is plain JS and JSON.parse fails, catch block will assign the error msg
          const parsedErrorMsgObj = JSON.parse(errorMessageObj);
          errorMsg = parsedErrorMsgObj?.error?.message;
        } catch (error) {
          errorMsg = message;
        }
      } else {
        errorMsg = message || status.code;
      }
      throw errorMsg;
    }
    yield put({
      type: TEMPLATE_CREATE_SUCCESS,
      data: result.response,
      statusCode: result.status ? result.status.code : '',
      errorMsg
    });
    if (callback) {
      callback(result.response);
    }
  } catch (error) {
    yield put({
      type: TEMPLATE_CREATE_FAILURE,
      error,
      errorMsg
    });
    if (callback) {
      callback(null, errorMsg);
    }
  }
}

function* watchCreateTemplate() {
  yield takeLatest(
    TEMPLATE_CREATE_REQUEST,
    sendForApprovalCreate,
  );
}

// FOR EDIT
export function* getTemplateDetails({ id }) {
  try {
    const result = yield call(Api.getTemplateDetails, {
      id,
      channel: WHATSAPP,
    });
    yield put({
      type: GET_TEMPLATE_DETAILS_SUCCESS,
      data: result.response,
    });
  } catch (error) {
    yield put({ type: GET_TEMPLATE_DETAILS_FAILURE, error });
  }
}

//For getMetaTags
export function* getMetaTagsDetails({ previewUrl, callBack }) {
  try {
    const result = yield call(Api.getMetaTags, {
      previewUrl,
    });
    if (result?.success) {
      yield put({
        type: URL_META_TAGS_SUCCESS,
        data: result?.response
      });
    } else {
      if (callBack) {
        callBack({errorMessage: result?.message});
      }
      yield put({
        type: URL_META_TAGS_FAILURE,
        error: result?.message,
      });
    }
  } catch (error) {
    if (callBack) {
      callBack({errorMessage: error});
    }
    yield put({ type: URL_META_TAGS_FAILURE, error });
  }
}

function* watchGetTemplateDetails() {
  yield takeLatest(
    GET_TEMPLATE_DETAILS_REQUEST,
    getTemplateDetails,
  );
}

export function* watchGetMetaTagsDetails() {
  yield takeLatest(
    URL_META_TAGS_REQUEST,
    getMetaTagsDetails,
  );
}

export default [
  watchCreateTemplate,
  watchGetTemplateDetails,
  watchUploadWhatsappAsset,
  watchGetMetaTagsDetails,
];

export function* v2WhatsappSagas() {
  yield all([
    watchCreateTemplate(),
    watchGetTemplateDetails(),
    watchUploadWhatsappAsset(),
    watchGetMetaTagsDetails(),
  ]);
}