import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import Helmet from 'react-helmet';
import { RouteComponentProps } from 'react-router-dom';

import { VODVideoPlayer } from 'mweb/common/components/videoPlayer/vod';
import InfoBox from 'mweb/common/components/infoBox';
import { DiscoverMore } from 'mweb/common/components/discoverMore';
import { SwitchToDesktop } from 'mweb/common/components/switchToDesktop';
import {
  statusNotFound,
  statusInternalError,
  RootState,
  getCurrentVODForVODViewer,
} from 'mweb/common/reducers/root';
import { getChannelDetails } from 'mweb/common/selectors/data/channels';
import { navigationDeclineMobileWebExperience } from 'mweb/common/actions/navigation';
import { vodViewerPageTransition } from 'mweb/common/actions/pages/vodViewer';
import getQueryParamsFromHistoryLocation from 'mweb/common/utils/getQueryParamsFromHistoryLocation';
import {
  ErrorStatableOwnProps,
  ErrorStateWrapper,
} from 'mweb/common/components/errors/errorStateWrapper';
import { withLatencyTracker } from 'mweb/common/latency/withLatencyTracker';
import { ClientOnly } from 'mweb/common/containers/clientOnly';
import { BranchUpsellExperiment } from 'mweb/common/components/branchUpsell';
import { BranchTimedTrackerExperiment } from 'mweb/common/components/branchTimedTracker';
import { BranchJourneyType, BranchEvent } from 'branch-io';

export interface VODViewerStateProps {
  channelName: string | undefined;
  channelDisplayName: string | undefined;
  logoUrl: string | undefined;
  vodTitle: string | undefined;
  sessionID: string;
  game: string | undefined;
}

export interface VODViewerDispatchProps {
  transitionToTargetVOD: (vodID: string) => void;
  switchToDesktop: React.EventHandler<React.MouseEvent<HTMLAnchorElement>>;
}

export interface VODViewerMatchParams {
  vodID: string;
}

export interface VODViewerOwnProps
  extends RouteComponentProps<VODViewerMatchParams> {}

export interface VODViewerProps
  extends VODViewerStateProps,
    VODViewerDispatchProps,
    VODViewerOwnProps {}

export class VODViewer extends React.Component<VODViewerProps, {}> {
  static displayName: string = 'VODViewer';

  isInteractive(): boolean {
    return !!this.props.channelDisplayName;
  }

  componentDidMount(): void {
    this.props.transitionToTargetVOD(this.props.match.params.vodID);
  }

  componentDidUpdate(prevProps: VODViewerProps): void {
    if (this.props.match.params.vodID !== prevProps.match.params.vodID) {
      this.props.transitionToTargetVOD(this.props.match.params.vodID);
    }
  }

  getInitialOffset(): string | undefined {
    return getQueryParamsFromHistoryLocation(this.props.location).t;
  }

  get player(): JSX.Element {
    return (
      <VODVideoPlayer
        vodID={this.props.match.params.vodID}
        vodInitialOffset={this.getInitialOffset()}
        sessionID={this.props.sessionID}
      />
    );
  }

  render(): JSX.Element {
    return (
      <div className="channel-view page">
        <Helmet>
          <title>
            {`${this.props.channelDisplayName ||
              this.props.channelName ||
              ''} Twitch`.trim()}
          </title>
        </Helmet>
        {this.player}
        <InfoBox
          channelName={this.props.channelName}
          channelDisplayName={this.props.channelDisplayName}
          logoUrl={this.props.logoUrl}
          vodTitle={this.props.vodTitle}
        />
        <div>
          <DiscoverMore game={this.props.game} />
          <SwitchToDesktop switchToDesktop={this.props.switchToDesktop} />
        </div>
        <ClientOnly>
          <BranchUpsellExperiment
            delaySecondsUntilUpsell={120}
            journey={{
              type: BranchJourneyType.Vod,
              channel: this.props.channelDisplayName || this.props.channelName,
            }}
          />
          <BranchTimedTrackerExperiment
            delaySecondsUntilTrack={5 * 60}
            event={BranchEvent.FiveMinutePlay}
          />
        </ClientOnly>
      </div>
    );
  }
}

function mapStateToProps(
  state: RootState,
): VODViewerStateProps & ErrorStatableOwnProps {
  const vod = getCurrentVODForVODViewer(state);
  const channel = vod && getChannelDetails(state, vod.channel);
  return {
    channelName: channel && channel.name,
    channelDisplayName: channel && channel.displayName,
    logoUrl: channel && channel.logoURL,
    game: vod && vod.game,
    vodTitle: vod && vod.title,
    sessionID: state.device.sessionID,
    notFound: statusNotFound(state),
    internalError: statusInternalError(state),
  };
}

function mapDispatchToProps(
  dispatch: Dispatch<RootState>,
): VODViewerDispatchProps {
  return bindActionCreators(
    {
      transitionToTargetVOD: vodViewerPageTransition,
      switchToDesktop: navigationDeclineMobileWebExperience,
    },
    dispatch,
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(
  ErrorStateWrapper(withLatencyTracker(VODViewer)),
) as React.ComponentClass<VODViewerOwnProps>;
