import expect from 'expect';
import fetchMock from 'fetch-mock';

import createTestStore from 'mtest/helpers/createTestStore';
import {
  CHANNEL,
  CHANNEL_DATA_PAYLOAD,
  mockChannel,
} from 'mtest/fetchMocks/channel';
import {
  CHANNEL as LTV_CHANNEL,
  CHANNEL_ID as LTV_CHANNEL_ID,
  STREAM_ID as LTV_STREAM_ID,
  PARSED_LTV_VOD,
  mockOnlineChannelWithTargetStream,
  mockOfflineChannelWithTargetVOD,
} from 'mtest/fetchMocks/liveToVODStatus';

import {
  CHANNEL_VIEWER_PAGE_CHANNEL_UPDATED_ACTION_TYPE,
  CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_PARAMS_CAPTURED_ACTION_TYPE,
  CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_REDIRECTED_ACTION_TYPE,
  CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_STREAM_ID_CLEARED_ACTION_TYPE,
  channelViewerPageTransition,
  channelViewerPageUpdateChannel,
  channelViewerPageCaptureLiveToVODParams,
  channelViewerCheckLiveToVODStatus,
} from 'mweb/common/actions/pages/channelViewer';
import { channelsDataLoadChannel } from 'mweb/common/actions/data/channels';
import { vodsDataLoadVOD } from 'mweb/common/actions/data/vods';
import { navigationUpdatedLocationActionBuilder } from 'mweb/common/actions/navigation';
import { Location } from 'mweb/common/reducers/app';
import {
  trackingPageViewTrackedActionBuilder,
  trackingClearTrackingParams,
} from 'mweb/common/actions/tracking';

describe('channelViewer actions', () => {
  afterEach(() => {
    expect(fetchMock.done()).toEqual(true);
    fetchMock.restore();
  });

  describe('channelViewerPageTransition', () => {
    it('updates location after loading data', () => {
      const store = createTestStore();
      mockChannel();

      return store.dispatch(channelViewerPageTransition(CHANNEL)).then(() => {
        const actions = store.getActions();
        expect(actions.shift()).toEqual(
          channelViewerPageUpdateChannel(CHANNEL),
        );
        expect(actions.shift()).toEqual(
          channelsDataLoadChannel(CHANNEL_DATA_PAYLOAD),
        );
        expect(actions.shift()).toEqual(
          navigationUpdatedLocationActionBuilder(Location.Channel),
        );
        expect(actions.shift()).toEqual(trackingPageViewTrackedActionBuilder());
        expect(actions.shift()).toEqual(trackingClearTrackingParams());
      });
    });
  });

  describe('channelViewerPageUpdateChannel', () => {
    it('creates the proper payload', () => {
      expect(channelViewerPageUpdateChannel(CHANNEL)).toEqual({
        type: CHANNEL_VIEWER_PAGE_CHANNEL_UPDATED_ACTION_TYPE,
        payload: {
          channel: CHANNEL,
        },
      });
    });
  });

  describe('channelViewerPageCaptureLiveToVODParam', () => {
    it('creates the proper payload', () => {
      expect(
        channelViewerPageCaptureLiveToVODParams({ stream_id: '1234' }),
      ).toEqual({
        type: CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_PARAMS_CAPTURED_ACTION_TYPE,
        payload: {
          stream_id: '1234',
        },
      });
    });
  });

  describe('channelViewerCheckLiveToVODStatus', () => {
    it('signals to redirect when stream is offline', () => {
      const store = createTestStore();
      mockOfflineChannelWithTargetVOD();

      return store
        .dispatch(
          channelViewerCheckLiveToVODStatus(LTV_CHANNEL_ID, LTV_STREAM_ID),
        )
        .then(() => {
          const actions = store.getActions();
          expect(actions.shift()).toEqual(
            vodsDataLoadVOD({ vod: PARSED_LTV_VOD, channel: undefined }),
          );
          expect(actions.shift()).toEqual({
            type: CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_REDIRECTED_ACTION_TYPE,
            payload: {
              channel: LTV_CHANNEL,
              channelID: LTV_CHANNEL_ID,
              streamID: LTV_STREAM_ID,
              vodID: PARSED_LTV_VOD.id,
            },
          });
        });
    });

    it('signals that target stream is still online', () => {
      const store = createTestStore();
      mockOnlineChannelWithTargetStream();

      return store
        .dispatch(
          channelViewerCheckLiveToVODStatus(LTV_CHANNEL_ID, LTV_STREAM_ID),
        )
        .then(() => {
          const actions = store.getActions();
          expect(actions.shift()).toEqual({
            type: CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_STREAM_ID_CLEARED_ACTION_TYPE,
            payload: {
              channel: LTV_CHANNEL,
              channelID: LTV_CHANNEL_ID,
              streamID: LTV_STREAM_ID,
            },
          });
        });
    });
  });
});
