text: // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
  // See LICENSE.txt for license information.
  
  import PropTypes from 'prop-types';
  import React from 'react';
  import {intlShape} from 'react-intl';
  
  import {Text} from 'react-native';
  
  import AtMention from '@components/at_mention';
  import FormattedText from '@components/formatted_text';
  import {General} from '@mm-redux/constants';
  import {t} from '@utils/i18n';
  import {concatStyles} from '@utils/theme';
  
  export default class PostAddChannelMember extends React.PureComponent {
      static propTypes = {
          actions: PropTypes.shape({
              addChannelMember: PropTypes.func.isRequired,
              removePost: PropTypes.func.isRequired,
              sendAddToChannelEphemeralPost: PropTypes.func.isRequired,
          }).isRequired,
          baseTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
          currentUser: PropTypes.object.isRequired,
          channelType: PropTypes.string,
          post: PropTypes.object.isRequired,
          postId: PropTypes.string.isRequired,
          userIds: PropTypes.array.isRequired,
          usernames: PropTypes.array.isRequired,
          noGroupsUsernames: PropTypes.array,
          onPostPress: PropTypes.func,
          textStyles: PropTypes.object,
      };
  
      static defaultProps = {
          usernames: [],
      };
  
      static contextTypes = {
          intl: intlShape,
      };
  
      computeTextStyle = (baseStyle, context) => {
          return concatStyles(baseStyle, context.map((type) => this.props.textStyles[type]));
      }
  
      handleAddChannelMember = () => {
          const {
              actions,
              currentUser,
              post,
              userIds,
              usernames,
          } = this.props;
  
          const {formatMessage} = this.context.intl;
  
          if (post && post.channel_id) {
              userIds.forEach((userId, index) => {
                  actions.addChannelMember(post.channel_id, userId);
  
                  if (post.root_id) {
                      const message = formatMessage(
                          {
                              id: 'api.channel.add_member.added',
                              defaultMessage: '{addedUsername} added to the channel by {username}.',
                          },
                          {
                              username: currentUser.username,
                              addedUsername: usernames[index],
                          },
                      );
  
                      actions.sendAddToChannelEphemeralPost(currentUser, usernames[index], message, post.channel_id, post.root_id);
                  }
              });
  
              actions.removePost(post);
          }
      }
  
      generateAtMentions(usernames = [], textStyles) {
          if (usernames.length === 1) {
              return (
                  <AtMention
                      mentionStyle={this.props.textStyles.mention}
                      mentionName={usernames[0]}
                      onPostPress={this.props.onPostPress}
                  />
              );
          } else if (usernames.length > 1) {
              function andSeparator(key) {
                  return (
                      <FormattedText
                          key={key}
                          id={'post_body.check_for_out_of_channel_mentions.link.and'}
                          defaultMessage={' and '}
                          style={textStyles}
                      />
                  );
              }
  
              function commaSeparator(key) {
                  return <Text key={key}>{', '}</Text>;
              }
  
              return (
                  <Text>
                      {
                          usernames.map((username) => {
                              return (
                                  <AtMention
                                      key={username}
                                      mentionStyle={this.props.textStyles.mention}
                                      mentionName={username}
                                      onPostPress={this.props.onPostPress}
                                  />
                              );
                          }).reduce((acc, el, idx, arr) => {
                              if (idx === 0) {
                                  return [el];
                              } else if (idx === arr.length - 1) {
                                  return [...acc, andSeparator(idx), el];
                              }
  
                              return [...acc, commaSeparator(idx), el];
                          }, [])
                      }
                  </Text>
              );
          }
  
          return '';
      }
  
      render() {
          const {channelType, baseTextStyle, postId, usernames, noGroupsUsernames} = this.props;
  
          if (!postId || !channelType) {
              return null;
          }
  
          let linkId;
          let linkText;
          if (channelType === General.PRIVATE_CHANNEL) {
              linkId = t('post_body.check_for_out_of_channel_mentions.link.private');
              linkText = 'add them to this private channel';
          } else if (channelType === General.OPEN_CHANNEL) {
              linkId = t('post_body.check_for_out_of_channel_mentions.link.public');
              linkText = 'add them to the channel';
          }
  
          let outOfChannelMessageID;
          let outOfChannelMessageText;
          const outOfChannelAtMentions = this.generateAtMentions(usernames, baseTextStyle);
          if (usernames.length === 1) {
              outOfChannelMessageID = t('post_body.check_for_out_of_channel_mentions.message.one');
              outOfChannelMessageText = 'was mentioned but is not in the channel. Would you like to ';
          } else if (usernames.length > 1) {
              outOfChannelMessageID = t('post_body.check_for_out_of_channel_mentions.message.multiple');
              outOfChannelMessageText = 'were mentioned but they are not in the channel. Would you like to ';
          }
  
          let outOfGroupsMessageID;
          let outOfGroupsMessageText;
          const outOfGroupsAtMentions = this.generateAtMentions(noGroupsUsernames, baseTextStyle);
          if (noGroupsUsernames?.length) {
              outOfGroupsMessageID = t('post_body.check_for_out_of_channel_groups_mentions.message');
              outOfGroupsMessageText = 'did not get notified by this mention because they are not in the channel. They are also not a member of the groups linked to this channel.';
          }
  
          let outOfChannelMessage = null;
          if (usernames.length) {
              outOfChannelMessage = (
                  <Text>
                      {outOfChannelAtMentions}
                      {' '}
                      <FormattedText
                          id={outOfChannelMessageID}
                          defaultMessage={outOfChannelMessageText}
                          style={baseTextStyle}
                      />
                      <Text
                          style={this.props.textStyles.link}
                          id='add_channel_member_link'
                          onPress={this.handleAddChannelMember}
                      >
                          <FormattedText
                              id={linkId}
                              defaultMessage={linkText}
                          />
                      </Text>
                      <FormattedText
                          id={'post_body.check_for_out_of_channel_mentions.message_last'}
                          defaultMessage={'? They will have access to all message history.'}
                          style={baseTextStyle}
                      />
                  </Text>
              );
          }
  
          let outOfGroupsMessage = null;
          if (noGroupsUsernames?.length) {
              outOfGroupsMessage = (
                  <Text>
                      {outOfGroupsAtMentions}
                      {' '}
                      <FormattedText
                          id={outOfGroupsMessageID}
                          defaultMessage={outOfGroupsMessageText}
                          style={baseTextStyle}
                      />
                  </Text>
              );
          }
  
          return (
              <>
                  {outOfChannelMessage}
                  {outOfGroupsMessage}
              </>
          );
      }
  }
  