import React 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 { TrackNmf } from '../components';
import reducer from '../reducer';
import * as epics from '../epics';
import { withErrorBoundary } from '../../common/hoc/with-error-boundary';
import {
  makeNmfDataSelector,
  makeVisibilityNMfDataSelector,
  makeHhDataSelector,
  makeVisibilityHhDataSelector,
} from '../selectors';
import { TRootTrackNmfState, TState } from '../types';
import { ContextNmfData, ContextHhData } from '../contexts';
import { composeContexts } from '../../common/utils/react-better-context';
import { makeLastStreamDateSelector } from '../../common/selectors/stream-latest-date/stream-latest-date-selectors';
import {
  makeRefreshSelector,
  makeErrorGlobalSelector,
  makeTrackSelector,
} from '../../track/selectors';
import { TState as TTrackState } from '../../track/types';
import { TEntityVisibility } from '../../common/types';

type TStructured = {
  nmfData: TState['nmfData'];
  hhData: TState['hhData'];
  nmfDataVisibility: TEntityVisibility;
  hhDataVisibility: TEntityVisibility;
  lastStreamDate: Undefinable<string>;
  track: TTrackState['track'];
  trackRefresh: TTrackState['refresh'];
  globalError: boolean;
};
type TConnected = TStructured & {};
type TPropsExternal = {};

const mapStateToProps = createStructuredSelector<
  TRootTrackNmfState,
  TStructured
>({
  nmfData: makeNmfDataSelector(),
  hhData: makeHhDataSelector(),
  nmfDataVisibility: makeVisibilityNMfDataSelector(),
  hhDataVisibility: makeVisibilityHhDataSelector(),
  lastStreamDate: makeLastStreamDateSelector(),
  track: makeTrackSelector(),
  trackRefresh: makeRefreshSelector(),
  globalError: makeErrorGlobalSelector(),
  //†prop
});
const mapDispatchToProps = {
  //†action
};

const Connected: React.FC<TConnected> = ({ globalError, ...rest }) => {
  if (globalError) return null;

  const {
    nmfData,
    hhData,
    track,
    trackRefresh,
    nmfDataVisibility,
    hhDataVisibility,
  } = rest;

  return composeContexts(
    [
      [
        ContextNmfData,
        {
          entity: nmfData,
          visibility: nmfDataVisibility,
          loading: track.loading,
          refresh: trackRefresh,
          track,
        },
      ],
      [
        ContextHhData,
        {
          entity: hhData,
          visibility: hhDataVisibility,
          loading: track.loading,
          refresh: trackRefresh,
          track,
        },
      ],
    ],
    <TrackNmf />
  );
};

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