import { logger } from 'tachyon-logger';
import { Dispatch } from 'redux';

import { navigationUpdateLocation } from 'mweb/common/actions/navigation';
import {
  fetchLiveToVODStatus,
  GO_TO_VOD_STATUS,
} from 'mweb/common/fetch/liveToVODStatus';
import { Location } from 'mweb/common/reducers/app';
import { RootState } from 'mweb/common/reducers/root';
import { channelsDataFetchChannel } from 'mweb/common/actions/data/channels';
import { vodsDataLoadVOD } from 'mweb/common/actions/data/vods';

export const CHANNEL_VIEWER_PAGE_CHANNEL_UPDATED_ACTION_TYPE =
  'CHANNEL_VIEWER_PAGE_UPDATE_CHANNEL_ACTION_TYPE';
export interface ChannelViewPageChannelUpdatedAction {
  type: typeof CHANNEL_VIEWER_PAGE_CHANNEL_UPDATED_ACTION_TYPE;
  payload: {
    channel: string;
  };
}

export interface LiveToVODParams {
  stream_id: string | undefined;
}

export const CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_PARAMS_CAPTURED_ACTION_TYPE =
  'CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_PARAMS_CAPTURED_ACTION_TYPE';
export interface ChannelViewPageLiveToVODParamsCapturedAction {
  type: typeof CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_PARAMS_CAPTURED_ACTION_TYPE;
  payload: LiveToVODParams;
}

export const CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_REDIRECTED_ACTION_TYPE =
  'CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_REDIRECTED_ACTION_TYPE';
export interface ChannelViewerPageLiveToVODRedirectedAction {
  type: typeof CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_REDIRECTED_ACTION_TYPE;
  payload: {
    channel: string;
    channelID: string;
    streamID: string;
    vodID: string;
  };
}

export const CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_STREAM_ID_CLEARED_ACTION_TYPE =
  'CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_STREAM_ID_CLEARED_ACTION_TYPE';
export interface ChannelViewerPageLiveToVODStreamIDClearedAction {
  type: typeof CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_STREAM_ID_CLEARED_ACTION_TYPE;
  payload: {
    channel: string;
    channelID: string;
    streamID: string;
  };
}

export type ChannelViewerPageAction =
  | ChannelViewPageChannelUpdatedAction
  | ChannelViewPageLiveToVODParamsCapturedAction
  | ChannelViewerPageLiveToVODRedirectedAction
  | ChannelViewerPageLiveToVODStreamIDClearedAction;

export function channelViewerPageTransition(
  channel: string,
): (dispatch: Dispatch<RootState>) => Promise<void> {
  return async dispatch => {
    dispatch(channelViewerPageUpdateChannel(channel));
    await dispatch(channelsDataFetchChannel(channel));
    dispatch(navigationUpdateLocation(Location.Channel));
  };
}

export function channelViewerPageUpdateChannel(
  channel: string,
): ChannelViewPageChannelUpdatedAction {
  return {
    type: CHANNEL_VIEWER_PAGE_CHANNEL_UPDATED_ACTION_TYPE,
    payload: {
      channel,
    },
  };
}

export function channelViewerPageCaptureLiveToVODParams(
  params: LiveToVODParams,
): ChannelViewPageLiveToVODParamsCapturedAction {
  return {
    type: CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_PARAMS_CAPTURED_ACTION_TYPE,
    payload: params,
  };
}

export function channelViewerCheckLiveToVODStatus(
  channelID: string,
  streamID: string,
): (dispatch: Dispatch<RootState>) => Promise<void> {
  return async dispatch => {
    const liveToVOD = await fetchLiveToVODStatus(channelID, streamID);
    const channel = liveToVOD.channel;
    if (liveToVOD.status === GO_TO_VOD_STATUS) {
      const vodID = liveToVOD.vod.id;
      logger.info(`Redirecting from channel ${channel} to vod ${vodID}`);
      // while LTV remains on REST, give the data loader function the proper shape
      dispatch(vodsDataLoadVOD({ vod: liveToVOD.vod, channel: undefined }));
      dispatch(
        channelViewerPageRedirectLiveToVOD(channel, channelID, streamID, vodID),
      );
    } else {
      logger.info(`Target stream for channel ${channel} is still live`);
      dispatch(
        channelViewerPageClearLiveToVODStreamID(channel, channelID, streamID),
      );
    }
  };
}

export function channelViewerPageRedirectLiveToVOD(
  channel: string,
  channelID: string,
  streamID: string,
  vodID: string,
): ChannelViewerPageLiveToVODRedirectedAction {
  return {
    type: CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_REDIRECTED_ACTION_TYPE,
    payload: {
      channel,
      channelID,
      streamID,
      vodID,
    },
  };
}

export function channelViewerPageClearLiveToVODStreamID(
  channel: string,
  channelID: string,
  streamID: string,
): ChannelViewerPageLiveToVODStreamIDClearedAction {
  return {
    type: CHANNEL_VIEWER_PAGE_LIVE_TO_VOD_STREAM_ID_CLEARED_ACTION_TYPE,
    payload: {
      channel,
      channelID,
      streamID,
    },
  };
}
