text: // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
  // See LICENSE.txt for license information.
  
  import {batchActions} from 'redux-batched-actions';
  
  import {NavigationTypes, ViewTypes} from '@constants';
  import {analytics} from '@init/analytics.ts';
  import {ChannelTypes, GeneralTypes, TeamTypes} from '@mm-redux/action_types';
  import {fetchMyChannelsAndMembers, getChannelAndMyMember} from '@mm-redux/actions/channels';
  import {getDataRetentionPolicy} from '@mm-redux/actions/general';
  import {receivedNewPost} from '@mm-redux/actions/posts';
  import {getMyTeams, getMyTeamMembers} from '@mm-redux/actions/teams';
  import {Client4} from '@mm-redux/client';
  import {General} from '@mm-redux/constants';
  import EventEmitter from '@mm-redux/utils/event_emitter';
  import initialState from '@store/initial_state';
  import {getStateForReset} from '@store/utils';
  
  import {markAsViewedAndReadBatch} from './channel';
  
  export function startDataCleanup() {
      return async (dispatch, getState) => {
          dispatch({
              type: ViewTypes.DATA_CLEANUP,
              payload: getState(),
          });
      };
  }
  
  export function loadConfigAndLicense() {
      return async (dispatch, getState) => {
          const {currentUserId} = getState().entities.users;
  
          try {
              const [config, license] = await Promise.all([
                  Client4.getClientConfigOld(),
                  Client4.getClientLicenseOld(),
              ]);
  
              const actions = [{
                  type: GeneralTypes.CLIENT_CONFIG_RECEIVED,
                  data: config,
              }, {
                  type: GeneralTypes.CLIENT_LICENSE_RECEIVED,
                  data: license,
              }];
  
              if (currentUserId) {
                  if (config.DataRetentionEnableMessageDeletion && config.DataRetentionEnableMessageDeletion === 'true' &&
                      license.IsLicensed === 'true' && license.DataRetention === 'true') {
                      dispatch(getDataRetentionPolicy());
                  } else {
                      actions.push({type: GeneralTypes.RECEIVED_DATA_RETENTION_POLICY, data: {}});
                  }
              }
  
              dispatch(batchActions(actions, 'BATCH_LOAD_CONFIG_AND_LICENSE'));
  
              return {config, license};
          } catch (error) {
              return {error};
          }
      };
  }
  
  export function loadFromPushNotification(notification) {
      return async (dispatch, getState) => {
          const state = getState();
          const {payload} = notification;
          const {currentTeamId, teams, myMembers: myTeamMembers} = state.entities.teams;
          const {channels} = state.entities.channels;
  
          let channelId = '';
          let teamId = currentTeamId;
          if (payload) {
              channelId = payload.channel_id;
  
              // when the notification does not have a team id is because its from a DM or GM
              teamId = payload.team_id || currentTeamId;
          }
  
          // load any missing data
          const loading = [];
  
          if (teamId && (!teams[teamId] || !myTeamMembers[teamId])) {
              loading.push(dispatch(getMyTeams()));
              loading.push(dispatch(getMyTeamMembers()));
          }
  
          if (channelId && !channels[channelId]) {
              loading.push(dispatch(fetchMyChannelsAndMembers(teamId)));
          }
  
          if (loading.length > 0) {
              await Promise.all(loading);
          }
  
          dispatch(handleSelectTeamAndChannel(teamId, channelId));
  
          return {data: true};
      };
  }
  
  export function handleSelectTeamAndChannel(teamId, channelId) {
      return async (dispatch, getState) => {
          const dt = Date.now();
          await dispatch(getChannelAndMyMember(channelId));
  
          const state = getState();
          const {channels, currentChannelId, myMembers} = state.entities.channels;
          const {currentTeamId} = state.entities.teams;
          const channel = channels[channelId];
          const member = myMembers[channelId];
          const actions = markAsViewedAndReadBatch(state, channelId);
  
          // when the notification is from a team other than the current team
          if (teamId !== currentTeamId) {
              actions.push({type: TeamTypes.SELECT_TEAM, data: teamId});
          }
  
          if (channel && currentChannelId !== channelId) {
              actions.push({
                  type: ChannelTypes.SELECT_CHANNEL,
                  data: channelId,
                  extra: {
                      channel,
                      member,
                      teamId: channel.team_id || currentTeamId,
                  },
              });
          }
  
          if (actions.length) {
              dispatch(batchActions(actions, 'BATCH_SELECT_TEAM_AND_CHANNEL'));
          }
  
          // eslint-disable-next-line no-console
          console.log('channel switch from push notification to', channel?.display_name || channel?.id, (Date.now() - dt), 'ms');
      };
  }
  
  export function purgeOfflineStore() {
      return (dispatch, getState) => {
          const currentState = getState();
  
          dispatch({
              type: General.OFFLINE_STORE_PURGE,
              data: getStateForReset(initialState, currentState),
          });
  
          EventEmitter.emit(NavigationTypes.RESTART_APP);
      };
  }
  
  // A non-optimistic version of the createPost action in app/mm-redux with the file handling
  // removed since it's not needed.
  export function createPostForNotificationReply(post) {
      return async (dispatch, getState) => {
          const state = getState();
          const currentUserId = state.entities.users.currentUserId;
  
          const timestamp = Date.now();
          const pendingPostId = post.pending_post_id || `${currentUserId}:${timestamp}`;
  
          const newPost = {
              ...post,
              pending_post_id: pendingPostId,
              create_at: timestamp,
              update_at: timestamp,
          };
  
          try {
              const data = await Client4.createPost({...newPost, create_at: 0});
              dispatch(receivedNewPost(data));
  
              return {data};
          } catch (error) {
              return {error};
          }
      };
  }
  
  export function recordLoadTime(screenName, category) {
      return async (dispatch, getState) => {
          const {currentUserId} = getState().entities.users;
  
          analytics.recordTime(screenName, category, currentUserId);
      };
  }
  
  export function setDeepLinkURL(url) {
      return {
          type: ViewTypes.SET_DEEP_LINK_URL,
          url,
      };
  }
  
  export default {
      loadConfigAndLicense,
      loadFromPushNotification,
      purgeOfflineStore,
  };
  