import React, { useCallback, useEffect } from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import { withReducer } from '../../app/core/with-reducer';
import { withEpics } from '../../app/core/with-epics';
import { fp as _ } from '../../common/utils/fp';
import { Markets } from '../components/markets';
import reducer, { ACTION } from '../reducer';
import * as epics from '../epics';
import { withErrorBoundary } from '../../common/hoc/with-error-boundary';
import {
  makeRefreshSelector,
  makeActiveTabSelector,
  makeDateRangeOptionsSelector,
  makeDateRangeSelector,
  selectOwnTab,
  makeOfflineSelector,
  makeSearchSelector,
  makeVisibilitySelector,
  makeAllMarketsSelector,
  makeItemsExtendedSelector,
  makeLoadedSelector,
} from '../selectors';
import { makeTrackDataSelector } from '../../track/selectors';
import { MODULE_NAME } from '../constants';
import { withNavigationSync } from '../../common/hoc/with-navigation-sync';
import { PAGES, updatePageMeta } from '../../analytics';
import { ContextMarkets } from '../contexts';
import { TData } from '../../track/types';
import {
  TActiveTab,
  TRootMarketsState,
  TVisibility,
  TCards,
  TState,
  TRoute,
} from '../types';
import { TDateRangeOption, TRangeEntity } from '../../common/types';
import { useNavKeyMap } from '../../common/hooks/use-nav-key-map';
import { ROUTES } from '../../app/constants';
import { Router } from '../../common/utils/navigation-service';
import { withStreamLatestDate } from '../../common/hoc/with-stream-latest-date';

type TStructured = {
  refreshing: boolean;
  trackData: TData | {};
  activeTab?: TActiveTab;
  dateRange?: TRangeEntity;
  dateRangeOptions: TDateRangeOption[];
  marketTab: TActiveTab;
  offline: boolean;
  search: string;
  visibility: TVisibility;
  cards: TCards;
  cardsAll: TCards;
  loaded: TState['loaded'];
};

type TConnected = TStructured & {
  flush: () => void;
  preSetDateRange: () => void;
  setActiveTab: (tab: TActiveTab) => void;
  route: TRoute;
  refresh: () => void;
  setSearch: (str: string) => void;
};

type TPropsExternal = {};

const mapStateToProps = createStructuredSelector<
  TRootMarketsState,
  TStructured
>({
  refreshing: makeRefreshSelector(),
  trackData: makeTrackDataSelector(),
  activeTab: makeActiveTabSelector(),
  dateRange: makeDateRangeSelector(),
  dateRangeOptions: makeDateRangeOptionsSelector(),
  loaded: makeLoadedSelector(),
  // @ts-ignore
  marketTab: selectOwnTab,
  offline: makeOfflineSelector(),
  search: makeSearchSelector(),
  visibility: makeVisibilitySelector(),
  cards: makeItemsExtendedSelector(),
  cardsAll: makeAllMarketsSelector(),
  //†prop
});
const mapDispatchToProps = {
  flush: ACTION.flush,
  refresh: ACTION.refresh,
  preSetDateRange: ACTION.preSetDateRange,
  setActiveTab: ACTION.setActiveTab,
  setSearch: ACTION.setSearch,
  //†action
};

// Uncomment to write componentDidMount hook
const Connected: React.FC<TConnected> = ({
  flush,
  marketTab,
  preSetDateRange,
  setActiveTab,
  ...rest
}) => {
  const { trackData, cards, cardsAll, visibility, activeTab, route } = rest;

  useNavKeyMap({ page: ROUTES.markets, route });

  useEffect(() => {
    // wait children initialization
    setTimeout(() => preSetDateRange());

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

  useEffect(() => {
    setTimeout(() => {
      const marketTab = _.path('params.marketTab', route);
      setActiveTab(marketTab!);
    });
  }, [marketTab]);

  useEffect(() => {
    updatePageMeta({
      page: PAGES.Markets.page,
      source_track_id: _.path('id', trackData),
      source_track_name: _.path('name', trackData),
      source_track_isrc: _.path('isrc', trackData),
    });
  }, []);

  const selectTabWithRouter = useCallback((tab: TState['activeTab']) => {
    Router.goTo(ROUTES.markets, {
      marketTab: tab,
    });
  }, []);

  return (
    <ContextMarkets.Provider
      value={{
        visibility,
        cards: activeTab === 'top' ? cards : cardsAll,
        activeTab,
      }}
    >
      <Markets
        {...rest}
        preSetDateRange={preSetDateRange}
        setActiveTab={selectTabWithRouter}
      />
    </ContextMarkets.Provider>
  );
};

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