import React, { useCallback } 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 { Notifications } from '../components/notifications';
import { ACTION } from '../reducer';
// import * as epics from '../epics';
import {
  makeRefreshSelector,
  makeNotificationSettingsKeySelector,
  makeNotificationsSelector,
  makeVisibilitySelector,
} from '../selectors';
import { useNavigationFlush } from '../../common/hooks/use-navigation-flush';
import { withErrorBoundary } from '../../common/hoc/with-error-boundary';
import { withNavigationSync } from '../../common/hoc/with-navigation-sync';
import { useNavKeyMap } from '../../common/hooks/use-nav-key-map';
import { ROUTES } from '../../app/constants';
import { TRootNotificationsState, TRoute, TState, TVisibility } from '../types';
import { ACTION as NOTIFICATION_SETTINGS_ACTION } from '../../notification-settings/reducer';
import { TState as TNotificationSettingsState } from '../../notification-settings/types';
import { makeNotificationSettingsSelector } from '../../notification-settings/selectors';
import { NEntityInfinite } from '../../common/types';
import { FETCH_TYPE } from '../../common/constants';
import {
  // useRenderRecursionBug,
  useSentryRenderRecursionDetector,
} from '../../common/utils/debuggers/sentry-logger';
import { composeContexts } from '../../common/utils/react-better-context';
import { ContextHeader } from '../contexts';
import TEntityConfig = NEntityInfinite.TEntityConfig;

type TStructured = {
  refreshing: TState['refresh'];
  notificationSettings: TNotificationSettingsState['notificationSettings'];
  notificationSettingsKeySelector: boolean;
  visibility: TVisibility;
  notifications: TState['notifications'];
};

type TConnected = TStructured & {
  getNotificationSettings: () => void;
  flush: () => void;
  refresh: () => void;
  navigation: NavigationProp<ParamListBase>;
  route: TRoute;
  getNotifications: NEntityInfinite.TEntityInfiniteGet;
  markAsRead: () => void;
  setConfig: (config: TEntityConfig) => void;
};

type TPropsExternal = {};

const mapStateToProps = createStructuredSelector<
  TRootNotificationsState,
  TStructured
>({
  // prop1: makeSelector(),
  refreshing: makeRefreshSelector(),
  notificationSettings: makeNotificationSettingsSelector(),
  notificationSettingsKeySelector: makeNotificationSettingsKeySelector(),
  visibility: makeVisibilitySelector(),
  notifications: makeNotificationsSelector(),
  //†prop
});
const mapDispatchToProps = {
  // action1: ACTION.action1,
  flush: ACTION.flush,
  refresh: ACTION.refresh,
  getNotificationSettings: NOTIFICATION_SETTINGS_ACTION.getNotificationSettings,
  getNotifications: ACTION.getNotifications,
  markAsRead: ACTION.markAsRead,
  setConfig: ACTION.setConfig,
  //†action
};

// Uncomment to write componentDidMount hook
const Connected: React.FC<TConnected> = ({
  getNotificationSettings,
  getNotifications,
  flush,
  markAsRead,
  navigation,
  route,
  notifications,
  visibility,
  ...rest
}) => {
  useNavKeyMap({ page: ROUTES.notifications, route });

  const getData = useCallback((type: FETCH_TYPE) => {
    getNotifications(null, type);
  }, []);

  useSentryRenderRecursionDetector('notifications');

  useNavigationFlush({
    getData: () => {
      getNotificationSettings();
      getData(FETCH_TYPE.force);
    },
    flush: () => {
      markAsRead();
      flush();
    },
    navigation,
    route,
  });

  return composeContexts(
    [
      [
        ContextHeader,
        {
          getNotifications,
          notifications,
          visibility,
        },
      ],
    ],
    <Notifications
      {...rest}
      getData={getData}
      notifications={notifications}
      visibility={visibility}
    />
  );
};

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