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 {v2LineContainerSagas} from '../sagas';
import * as types from '../constants'; 
import * as sagas from '../sagas'; 

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

    it('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('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('Combined v2LineContainerSagas', () => {
    it('should initialize all v2LineContainerSagas watcher sagas without error', () => {
      return expectSaga(v2LineContainerSagas)
        .run();
    });
  });
});

describe('Line Template Sagas', () => {

  describe('createTemplate Saga', () => {
    const template = { name: 'New Template' };
    const callback = jest.fn();

    it('handles successful template creation', () => {
      const fakeResponse = {
        status: { code: 200 },
        response: { id: 1, name: 'New Template' },
        message: 'Success'
      };

      return expectSaga(sagas.createTemplate, { template, callback })
        .provide([
          [call(Api.createLineTemplate, template), fakeResponse]
        ])
        .put({
          type: types.CREATE_TEMPLATE_SUCCESS,
          data: fakeResponse.response,
          statusCode: 200,
          errorMsg: undefined
        })
        .run()
        .then(() => {
          expect(callback).toHaveBeenCalledWith(fakeResponse.response);
        });
    });

    it('handles template creation failure due to API error', () => {
      const error = 'API Error';
      const fakeResponse = {
        status: { code: 400 },
        message: error
      };

      return expectSaga(sagas.createTemplate, { template, callback })
        .provide([
          [call(Api.createLineTemplate, template), throwError(new Error(error))]
        ])
        .put({
          type: types.CREATE_TEMPLATE_FAILURE,
          error: new Error(error),
          errorMsg: undefined,
        })
        .run()
        .then(() => {
          expect(callback).toHaveBeenCalledWith(null, undefined);
        });
    });
  });

  describe('uploadAsset Saga', () => {
    const file = new Blob(['file contents'], { type: 'text/plain' });
    const assetType = 'image';
    const fileParams = { templateType: 'basic' };

    it('handles asset upload successfully', () => {
      const fakeResponse = {
        status: { code: 200 },
        response: { asset: 'image-url' }
      };

      return expectSaga(sagas.uploadAsset, file, assetType, fileParams)
        .provide([
          [call(Api.uploadFile, file, assetType, fileParams), fakeResponse]
        ])
        .put({
          type: types.UPLOAD_ASSET_SUCCESS,
          data: 'image-url',
          statusCode: 200,
          templateType: undefined
        })
        .run();
    });

    it('handles asset upload failure', () => {
      const error = new Error('Upload failed');

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

  describe('editTemplate Saga', () => {
    const template = { name: 'Updated Template' };
    const callback = jest.fn();

    it('handles successful template edit', () => {
      const fakeResponse = {
        status: { code: 200 },
        response: { id: 1, name: 'Updated Template' },
        message: 'Success'
      };

      return expectSaga(sagas.editTemplate, { template, callback })
        .provide([
          [call(Api.createLineTemplate, template), fakeResponse]
        ])
        .put({
          type: types.EDIT_TEMPLATE_SUCCESS,
          data: fakeResponse.response,
          statusCode: 200,
          errorMsg: undefined
        })
        .run()
        .then(() => {
          expect(callback).toHaveBeenCalledWith(fakeResponse.response);
        });
    });

    it('handles template edit failure due to API error', () => {
      const error = 'API Error';
      const fakeResponse = {
        status: { code: 400 },
        message: error
      };

      return expectSaga(sagas.editTemplate, { template, callback })
        .provide([
          [call(Api.createLineTemplate, template), throwError(new Error(error))]
        ])
        .put({
          type: types.EDIT_TEMPLATE_FAILURE,
          error: new Error(error),
          errorMsg: undefined
        })
        .run()
        .then(() => {
          expect(callback).toHaveBeenCalledWith(null, undefined);
        });
    });
  });

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

    it('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('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();
    });
  });
  
  // Additional sagas like getLineTemplatesList can be added following the same structure.
});