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

import { gameDirectoryPageTransition } from 'mweb/common/actions/pages/gameDirectory';
import { gamesDataGetPage } from 'mweb/common/actions/data/games';
import GameList from 'mweb/common/components/gameList';
import {
  gameDirectoryIsLoading,
  statusSuccess,
  gameList,
  RootState,
} from 'mweb/common/reducers/root';
import { GameDetails } from 'mweb/common/reducers/data/games';
import InitialLoadWrapper, {
  InitialLoadWrapperProps,
} from 'mweb/common/components/initialLoadWrapper';
import {
  ErrorStatableOwnProps,
  ErrorStateWrapper,
} from 'mweb/common/components/errors/errorStateWrapper';
import { withLatencyTracker } from 'mweb/common/latency/withLatencyTracker';
import { BranchUpsellExperiment } from 'mweb/common/components/branchUpsell';
import { ClientOnly } from 'mweb/common/containers/clientOnly';
import { BranchJourneyType } from 'branch-io';

const messages = defineMessages({
  gameDirectory: {
    id: 'game-directory--title',
    defaultMessage: 'All Games - Twitch',
  },
});

export interface GameDirectoryStateProps {
  games: GameDetails[];
  isLoading: boolean;
}

export interface GameDirectoryDispatchProps {
  transition: () => void;
  getNextPage: () => void;
}

export interface GameDirectoryOwnProps extends RouteComponentProps<void> {}

export interface GameDirectoryProps
  extends GameDirectoryStateProps,
    GameDirectoryDispatchProps,
    GameDirectoryOwnProps {
  intl: InjectedIntl;
}

class GameDirectory extends React.Component<GameDirectoryProps, {}> {
  static displayName: string = 'GameDirectory';

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

  componentDidMount(): void {
    this.props.transition();
  }

  render(): JSX.Element {
    return (
      <div>
        <Helmet>
          <title>{this.props.intl.formatMessage(messages.gameDirectory)}</title>
        </Helmet>
        <GameList
          games={this.props.games}
          getNextPage={this.props.getNextPage}
        />
        <ClientOnly>
          <BranchUpsellExperiment
            delaySecondsUntilUpsell={5}
            journey={{
              type: BranchJourneyType.MainDir,
            }}
          />
        </ClientOnly>
      </div>
    );
  }
}

interface GameDirectoryMapStateProps
  extends GameDirectoryStateProps,
    InitialLoadWrapperProps {}

function mapStateToProps(
  state: RootState,
): GameDirectoryMapStateProps & ErrorStatableOwnProps {
  return {
    games: gameList(state),
    isLoading: gameDirectoryIsLoading(state),
    internalError: !statusSuccess(state),
  };
}

function mapDispatchToProps(
  dispatch: Dispatch<RootState>,
): GameDirectoryDispatchProps {
  return bindActionCreators(
    {
      transition: gameDirectoryPageTransition,
      getNextPage: gamesDataGetPage,
    },
    dispatch,
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(
  injectIntl(
    ErrorStateWrapper(InitialLoadWrapper(withLatencyTracker(GameDirectory))),
  ),
) as React.ComponentClass<GameDirectoryOwnProps>;
