import { expectSaga } from 'redux-saga-test-plan';
import { call, put } from 'redux-saga/effects';
import { throwError } from 'redux-saga-test-plan/providers';
import * as Api from '../../../../services/api'; 
import {v2MobilePushEditSagas} from '../sagas';
import * as types from '../constants'; 
import * as sagas from '../sagas'; 

describe('Mobile Push Template Sagas', () => {
  describe('editTemplate Saga', () => {
    const template = { message: "Retuen",id: 1, name: 'Updated Template' };

    it.concurrent('handles successful template edit', () => {
      const fakeResponse = {
        response: template,
        status: { code: 200 }
      };

      return expectSaga(sagas.editTemplate, template)
        .provide([
          [call(Api.createMobilePushTemplate, template), fakeResponse]
        ])
        .put({
          type: types.EDIT_TEMPLATE_SUCCESS,
          data: fakeResponse.response,
          statusCode: 200,
          errorMsg: undefined
        })
        .run();
    });
    it.concurrent('handles successful template edit', () => {
        const fakeResponse = {
          response: template,
          status: { code: 500 }
        };
  
        return expectSaga(sagas.editTemplate, template)
          .provide([
            [call(Api.createMobilePushTemplate, template), fakeResponse]
          ])
          .put({
            type: types.EDIT_TEMPLATE_SUCCESS,
            data: fakeResponse.response,
            statusCode: 500,
            errorMsg: undefined
          })
          .run();
      });
    it.concurrent('handles failure in editing a template', () => {
      const error = new Error('Edit failed');

      return expectSaga(sagas.editTemplate, template)
        .provide([
          [call(Api.createMobilePushTemplate, template), throwError(error)]
        ])
        .put({
          type: types.EDIT_TEMPLATE_FAILURE,
          error,
          errorMsg: undefined
        })
        .run();
    });
  });

  describe('getTemplateDetails Saga', () => {
    const id = '123';

    it.concurrent('handles fetching template details successfully', () => {
      const fakeResponse = {
        response: { id: 123, name: 'Detailed Template' }
      };

      return expectSaga(sagas.getTemplateDetails, id)
        .provide([
          [call(Api.getTemplateDetails, id), fakeResponse]
        ])
        .put({
          type: types.GET_TEMPLATE_DETAILS_SUCCESS,
          data: fakeResponse.response
        })
        .run();
    });

    it.concurrent('handles failure in fetching template details', () => {
      const error = new Error('Fetch failed');

      return expectSaga(sagas.getTemplateDetails, id)
        .provide([
          [call(Api.getTemplateDetails, id), throwError(error)]
        ])
        .put({
          type: types.GET_TEMPLATE_DETAILS_FAILURE,
          error
        })
        .run();
    });
  });

  describe('uploadAsset Saga', () => {
    const file = new Blob();
    const assetType = 'image';
    const fileParams = { param1: 'value1' };
    const mode = 'strict';

    it.concurrent('handles successful asset upload', () => {
      const fakeResponse = {
        response: { asset: { id: 1, url: 'http://example.com/asset.jpg' } },
        status: { code: 200 }
      };

      return expectSaga(sagas.uploadAsset, file, assetType, fileParams, mode)
        .provide([
          [call(Api.uploadFile, file, assetType, fileParams, mode), fakeResponse]
        ])
        .put({
          type: types.UPLOAD_ASSET_SUCCESS,
          data: fakeResponse.response.asset,
          statusCode: 200
        })
        .run();
    });

    it.concurrent('handles failure in asset upload', () => {
      const error = new Error('Failed to upload asset');

      return expectSaga(sagas.uploadAsset, file, assetType, fileParams, mode)
        .provide([
          [call(Api.uploadFile, file, assetType, fileParams, mode), throwError(error)]
        ])
        .put({
          type: types.UPLOAD_ASSET_FAILURE,
          error
        })
        .run();
    });
  });

  describe('getIosCtas Saga', () => {
    const licenseCode = 'ABC123';

    it.concurrent('handles fetching iOS CTAs successfully', () => {
      const fakeResponse = {
        response: { metaEntities: { data: [{ id: 1, name: 'CTA One' }] } },
        status: { code: 200 }
      };

      return expectSaga(sagas.getIosCtas, licenseCode)
        .provide([
          [call(Api.getIosCtas, licenseCode), fakeResponse]
        ])
        .put({
          type: types.GET_IOS_CTAS_SUCCESS,
          data: fakeResponse.response.metaEntities.data,
          statusCode: 200
        })
        .run();
    });

    it.concurrent('handles failure in fetching iOS CTAs', () => {
      const error = new Error('Fetch failed');

      return expectSaga(sagas.getIosCtas, licenseCode)
        .provide([
          [call(Api.getIosCtas, licenseCode), throwError(error)]
        ])
        .put({
          type: types.GET_IOS_CTAS_FAILURE,
          error
        })
        .run();
    });
  });

  describe('getMobilepushTemplatesList Saga', () => {
    const params = { channel: 'mobilepush', queryParams: { sort: 'asc' } };

    it.concurrent('handles fetching mobile push templates list successfully', () => {
      const fakeResponse = {
        response: {
          templates: [{ id: 1, name: 'Template One' }],
          mapped: { id: 2, name: 'Mapped Template' }
        }
      };

      return expectSaga(sagas.getMobilepushTemplatesList, params)
        .provide([
          [call(Api.getAllTemplates, { channel: params.channel, queryParams: params.queryParams }), fakeResponse]
        ])
        .put({
          type: types.GET_MOBILEPUSH_TEMPLATES_LIST_SUCCESS,
          data: fakeResponse.response.templates,
          templateData: fakeResponse.response.mapped
        })
        .run();
    });

    it.concurrent('handles failure in fetching mobile push templates list', () => {
      const error = new Error('Fetch failed');

      return expectSaga(sagas.getMobilepushTemplatesList, params)
        .provide([
          [call(Api.getAllTemplates, { channel: params.channel, queryParams: params.queryParams }), throwError(error)]
        ])
        .put({
          type: types.GET_MOBILEPUSH_TEMPLATES_LIST_FAILURE,
          error
        })
        .run();
    });
  });

  describe('fetchWeCrmAccounts Saga', () => {
    const action = { source: 'CRM' };

    it.concurrent('handles successful fetching of WeCRM accounts', () => {
      const fakeResponse = {
        response: [{ id: 1, name: 'Account One' }]
      };

      return expectSaga(sagas.fetchWeCrmAccounts, action)
        .provide([
          [call(Api.fetchWeCrmAccounts, action.source), fakeResponse]
        ])
        .put({
          type: types.GET_WECRM_ACCOUNTS_SUCCESS,
          data: fakeResponse.response
        })
        .run();
    });

    it.concurrent('handles failure in fetching WeCRM accounts', () => {
      const error = new Error('Fetch failed');

      return expectSaga(sagas.fetchWeCrmAccounts, action)
        .provide([
          [call(Api.fetchWeCrmAccounts, action.source), throwError(error)]
        ])
        .put({
          type: types.GET_WECRM_ACCOUNTS_FAILURE,
          data: error
        })
        .run();
    });
  });



  // Test combined saga
  describe('Combined editMPushSaga', () => {
    it.concurrent('should initialize all mobile push-related watcher sagas without error', () => {
      return expectSaga(v2MobilePushEditSagas)
        .run();
    });
  });
});