import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import { Undefinable } from 'tsdef';
import { withReducer } from '../../app/core/with-reducer';
import { withEpics } from '../../app/core/with-epics';
import { fp as _ } from '../../common/utils/fp';
import { YoutubePerformance } from '../components';
import reducer, { ACTION } from '../reducer';
import * as epics from '../epics';
import { withErrorBoundary } from '../../common/hoc/with-error-boundary';
import {
  makeMarketsSelector,
  makePerformanceVisibilitySelector,
  makeViewsExtendedSelector,
  makeViewsVisibilitySelector,
  makePerformanceExtendedSelector,
  makeYoutubeParamsSelector,
  makeViewsSelector,
  makePerformanceSelector,
} from '../selectors';
import {
  TConvertedPerformance,
  TConvertedViews,
  TMarkets,
  TRootYoutubePerformanceState,
  TSetMarkets,
  TState,
} from '../types';
import {
  ContextHeader,
  ContextPerformance,
  ContextPills,
  ContextViews,
} from '../contexts';
import { composeContexts } from '../../common/utils/react-better-context';
import {
  makeRefreshSelector,
  makeVisibilityConfigSelector,
} from '../../youtube/selectors';
import { makeVisibilityConfigSelector as makeVisibilityYoutubeListSelector } from '../../youtube-list/selectors';
import { TState as TYoutubeState } from '../../youtube/types';
import { TEntityVisibility, TRouteParams } from '../../common/types';
import { ROUTE_PARAMS } from '../../app/constants';

type TStructured = {
  globalRefresh: TYoutubeState['refresh'];
  youtubeVisibility: TEntityVisibility;
  youtubeListVisibility: TEntityVisibility;
  markets: TMarkets;
  views: TState['views'];
  viewsEntity: TConvertedViews;
  viewsVisibility: TEntityVisibility;
  performance: TState['performance'];
  performanceEntity: TConvertedPerformance;
  performanceVisibility: TEntityVisibility;
  youtubeParams: Undefinable<TRouteParams>;
};
type TConnected = TStructured & {
  setMarkets: TSetMarkets;
  getViews: () => void;
  getPerformance: () => void;
};
type TPropsExternal = {};

const mapStateToProps = createStructuredSelector<
  TRootYoutubePerformanceState,
  TStructured
>({
  globalRefresh: makeRefreshSelector(),
  youtubeVisibility: makeVisibilityConfigSelector(),
  youtubeListVisibility: makeVisibilityYoutubeListSelector(),
  markets: makeMarketsSelector(),
  views: makeViewsSelector(),
  viewsEntity: makeViewsExtendedSelector(),
  viewsVisibility: makeViewsVisibilitySelector(),
  performance: makePerformanceSelector(),
  performanceEntity: makePerformanceExtendedSelector(),
  performanceVisibility: makePerformanceVisibilitySelector(),
  youtubeParams: makeYoutubeParamsSelector(),
  //†prop
});
const mapDispatchToProps = {
  setActiveTab: ACTION.setActiveTab,
  setMarkets: ACTION.setMarkets,
  getViews: ACTION.getViews,
  getPerformance: ACTION.getPerformance,
  //†action
};

const Connected: React.FC<TConnected> = ({
  youtubeVisibility,
  youtubeListVisibility,
  ...rest
}) => {
  const {
    markets,
    setMarkets,
    views,
    viewsEntity,
    viewsVisibility,
    performance,
    performanceEntity,
    performanceVisibility,
    youtubeParams,
  } = rest;

  if (youtubeVisibility.offline) return null;

  useEffect(() => {
    setMarkets({
      owner:
        (youtubeParams![ROUTE_PARAMS.marketCodeYoutube] as string) || 'all',
    });
  }, []);

  const { globalRefresh } = rest;

  return composeContexts(
    [
      [
        ContextHeader,
        {
          loading: youtubeVisibility.skeleton,
          youtubeListLoading: youtubeListVisibility.skeleton,
          refresh: globalRefresh,
          youtubeParams,
        },
      ],
      [
        ContextPills,
        {
          markets,
          loading: youtubeVisibility.skeleton,
          youtubeListLoading: youtubeListVisibility.skeleton,
          refresh: globalRefresh,
          youtubeParams,
        },
      ],
      [
        ContextViews,
        {
          views,
          viewsEntity,
          visibility: viewsVisibility,
          loading: youtubeVisibility.skeleton,
          refresh: globalRefresh,
        },
      ],
      [
        ContextPerformance,
        {
          performance,
          performanceEntity,
          visibility: performanceVisibility,
          loading: youtubeVisibility.skeleton,
          refresh: globalRefresh,
        },
      ],
    ],
    <YoutubePerformance />
  );
};

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