import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import { NavigationProp, ParamListBase } from '@react-navigation/native';
import { withReducer } from '../../app/core/with-reducer';
import { withEpics } from '../../app/core/with-epics';
import { fp as _ } from '../../common/utils/fp';
import { Youtube } from '../components';
import reducer, { ACTION } from '../reducer';
import * as epics from '../epics';
import { withErrorBoundary } from '../../common/hoc/with-error-boundary';
import { withNavigationSync } from '../../common/hoc/with-navigation-sync';
import {
  makeVisibilityConfigSelector,
  makeRefreshSelector,
  makeDataSelector,
  makeVisibilityAllVideosConfigSelector,
  makeWavePositionSelector,
} from '../selectors';
import {
  TNavParams,
  TRootYoutubeState,
  TState,
  TRoute,
  TAllVideosVisibility,
} from '../types';
import { TEntityVisibility } from '../../common/types';
import {
  makeTrackDataSelector,
  makeTrackVisibilitySelector,
} from '../../track/selectors';
import { TData as TTrackData } from '../../track/types';
import { composeContexts } from '../../common/utils/react-better-context';
import {
  ContextTrackData,
  ContextVisibilityTrack,
  ContextVideoData,
  ContextVisibility,
  ContextAllVideo,
} from '../contexts';
import { useNavKeyMap } from '../../common/hooks/use-nav-key-map';
import { ROUTES } from '../../app/constants';
import { TState as TDemographicsState } from '../../youtube-demographics/types';
import { TConvertedViews } from '../../youtube-performance/types';
import { makeDemographicsDataSelector } from '../../youtube-demographics/selectors';
import { makeVisibilityConfigSelector as makeVisibilityYoutubeListSelector } from '../../youtube-list/selectors';
import { makeViewsExtendedSelector } from '../../youtube-performance/selectors';

type TPropsExternal = {};
type TStructured = {
  visibility: TEntityVisibility;
  visibilityAllVideos: TAllVideosVisibility;
  visibilityTrack: TEntityVisibility;
  youtubeListVisibility: TEntityVisibility;
  refreshing: boolean;
  data: TState['data'];
  trackData: TTrackData | {};
  demographics: TDemographicsState['demographics'];
  viewsEntity: TConvertedViews;
  wavePosition: number;
};
type TConnected = TPropsExternal &
  TStructured & {
    getData: (data: TNavParams) => void;
    flush: () => void;
    refresh: () => void;
    navigation: NavigationProp<ParamListBase>;
    route: TRoute;
  };

const mapStateToProps = createStructuredSelector<
  TRootYoutubeState,
  TStructured
>({
  visibility: makeVisibilityConfigSelector(),
  visibilityAllVideos: makeVisibilityAllVideosConfigSelector(),
  visibilityTrack: makeTrackVisibilitySelector(),
  youtubeListVisibility: makeVisibilityYoutubeListSelector(),
  refreshing: makeRefreshSelector(),
  data: makeDataSelector(),
  trackData: makeTrackDataSelector(),
  demographics: makeDemographicsDataSelector(),
  viewsEntity: makeViewsExtendedSelector(),
  wavePosition: makeWavePositionSelector(),
  //†prop
});
const mapDispatchToProps = {
  getData: ACTION.getData,
  flush: ACTION.flush,
  refresh: ACTION.refresh,
  //†action
};

const Connected: React.FC<TConnected> = ({
  getData,
  flush,
  route,
  youtubeListVisibility,
  ...rest
}) => {
  useNavKeyMap({ page: ROUTES.youtube, route });

  const { youtubeVariant, youtubeVideoId, youtubeVideoTotal } = route.params;
  const { trackData, refreshing } = rest;

  useEffect(() => {
    setTimeout(() => {
      getData(route.params);
    }, 0);

    return () => flush();
  }, [youtubeVideoId]);

  return composeContexts(
    [
      [ContextTrackData, { ...trackData }],
      [ContextVideoData, { data: rest.data }],
      [ContextVisibility, { visibility: rest.visibility }],
      [ContextVisibilityTrack, { visibility: rest.visibilityTrack }],
      [
        ContextAllVideo,
        {
          total: youtubeVideoTotal,
          youtubeVariant,
          youtubeListLoading: youtubeListVisibility.skeleton,
          refreshing,
        },
      ],
    ],
    <Youtube {...rest} youtubeVariant={youtubeVariant} />
  );
};

export default compose(
  _.hoistStatics(Youtube),
  withReducer('youtube', reducer),
  withEpics('youtube', epics),
  withErrorBoundary('youtube'),
  withNavigationSync(),
  connect(
    mapStateToProps,
    mapDispatchToProps
  )
)(Connected) as React.FC<TPropsExternal>;
