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 { PlaylistPerformance } from '../components';
import reducer, { ACTION } from '../reducer';
import * as epics from '../epics';
import { withErrorBoundary } from '../../common/hoc/with-error-boundary';
import {
  makeGraphsSelector,
  makePerformanceVisibilitySelector,
  makeVisibilityFollowersInfoSelector,
  makeVisibilityFollowersSelector,
  makeVisibilityStreamsInfoSelector,
  makeVisibilityStreamsSelector,
  makeRangeSelector,
  makeVisibilityListenersSelector,
  makeVisibilityListenersInfoSelector,
  makeVisibilityStreamsPerListenerSelector,
} from '../selectors';
import { TEntityVisibility, TRouteParams, TVendor } from '../../common/types';
import {
  TAllEntitiesVisibility,
  TGraphCard,
  TNavProps,
  TRootPlaylistPerformanceState,
  TState,
} from '../types';
import { ContextPlaylistPerformance } from '../contexts';
// import { TState as TPlaylistState } from '../../playlist/types';
// import { makePlaylistSelector } from '../../playlist/selectors';
// import { makeLastStreamDateSelector } from '../../common/selectors/stream-latest-date/stream-latest-date-selectors';
import { makeLatestDateSwitchSelector } from '../../playlist/selectors';
import { makeRoutingParamsSelector } from '../../common/selectors';
import { ROUTE_PARAMS } from '../../app/constants';
import {
  getNotificationSideEffectCooldown,
  NOTIFICATION_COOLDOWN_VARIANT,
} from '../../common/utils/notification-service';

type TStructured = {
  visibilityStreams: TEntityVisibility;
  visibilityStreamsInfo: TEntityVisibility;
  visibilityFollowers: TEntityVisibility;
  visibilityFollowersInfo: TEntityVisibility;
  visibilityListeners: TEntityVisibility;
  visibilityListenersInfo: TEntityVisibility;
  visibilityStreamsPerListener: TEntityVisibility;
  visibilityAll: TAllEntitiesVisibility;
  graphs: TGraphCard[];
  // playlist: TPlaylistState['playlist'];
  streamLatestDateValue: string | undefined;
  range: TState['range'];
  routingParams: Undefinable<TRouteParams>;
};
type TConnected = TStructured & {
  // getStreams: () => void;
  // getFollowers: () => void;
  // getStreamsInfo: () => void;
  // getFollowersInfo: () => void;
  flush: () => void;
  // refresh: () => void;
  setRange: (range: TState['range']) => void;
} & TNavProps;
type TPropsExternal = {};

const mapStateToProps = createStructuredSelector<
  TRootPlaylistPerformanceState,
  TStructured
>({
  visibilityStreams: makeVisibilityStreamsSelector(),
  visibilityStreamsInfo: makeVisibilityStreamsInfoSelector(),
  visibilityFollowers: makeVisibilityFollowersSelector(),
  visibilityFollowersInfo: makeVisibilityFollowersInfoSelector(),
  visibilityListeners: makeVisibilityListenersSelector(),
  visibilityListenersInfo: makeVisibilityListenersInfoSelector(),
  visibilityStreamsPerListener: makeVisibilityStreamsPerListenerSelector(),
  visibilityAll: makePerformanceVisibilitySelector(),
  graphs: makeGraphsSelector(),
  // playlist: makePlaylistSelector(),
  streamLatestDateValue: makeLatestDateSwitchSelector(),
  range: makeRangeSelector(),
  routingParams: makeRoutingParamsSelector(),
  //†prop
});
const mapDispatchToProps = {
  getStreams: ACTION.getStreams,
  getFollowers: ACTION.getFollowers,
  getStreamsInfo: ACTION.getStreamsInfo,
  getFollowersInfo: ACTION.getFollowersInfo,
  flush: ACTION.flush,
  refresh: ACTION.refresh,
  setRange: ACTION.setRange,
  //†action
};

const Connected: React.FC<TConnected> = ({
  visibilityStreams,
  visibilityStreamsInfo,
  visibilityFollowers,
  visibilityFollowersInfo,
  visibilityListeners,
  visibilityListenersInfo,
  visibilityStreamsPerListener,
  visibilityAll,
  flush,
  graphs,
  routingParams,
  streamLatestDateValue,
  range,
  setRange,
}) => {
  useEffect(() => {
    return () => {
      if (
        getNotificationSideEffectCooldown() ===
        NOTIFICATION_COOLDOWN_VARIANT.playlist
      )
        return;
      flush();
    };
  }, []);

  const visibility = {
    streams: visibilityStreams,
    streamsInfo: visibilityStreamsInfo,
    followers: visibilityFollowers,
    followersInfo: visibilityFollowersInfo,
    listeners: visibilityListeners,
    listenersInfo: visibilityListenersInfo,
    streamsPerListener: visibilityStreamsPerListener,
    all: visibilityAll,
  };

  return (
    <ContextPlaylistPerformance.Provider
      value={{
        visibility,
        graphs,
      }}
    >
      <PlaylistPerformance
        visibility={visibility}
        market={
          _.path(ROUTE_PARAMS.playlistrootMarket, routingParams) as string
        }
        playlistVendor={
          _.path(ROUTE_PARAMS.playlistrootVendor, routingParams) as TVendor
        }
        streamLatestDate={streamLatestDateValue}
        range={range}
        setRange={setRange}
        routingParams={routingParams}
      />
    </ContextPlaylistPerformance.Provider>
  );
};

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