/** Contains the base fields for a contact reuse **/
import _ from 'lodash';
import { ImagePicker, MailComposer, Permissions } from 'expo';
import React, { Component } from 'react';
import { Alert, Dimensions, Image, Linking, Modal, ScrollView, Share, Text, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native';
import { Button, Icon } from 'react-native-elements';
import ModalDropdown from 'react-native-modal-dropdown';
import { connect } from 'react-redux';
import { contactUpdate, profileToggleDisabled, profileSave, profileUpdate, socialRemoveFriend } from '../actions';
import { PROFILE_FORM, CONTACT_FORM, SOCIAL_FORM } from './FormTypes';
import { Confirm, Spacer } from './common';
import colors from '../config/colors.json';
import privateKeys from '../../private_keys.json';
import { strings } from '../locales/i18n';

const GREEN_CHECK_IMAGE = require('../../assets/GreenCheck.png');

const SCREEN_WIDTH = Dimensions.get('window').width;
const DEV_LINKING_BASE_URL = privateKeys.deepLinking.devBaseUrl;
const TAGFER_BASE_URL = privateKeys.deepLinking.tagferBaseUrl;
const profileKebabOptions = [
  strings('profile.kebabOptions_shareQR'),
  strings('profile.kebabOptions_shareLink'),
  strings('profile.kebabOptions_edit'),
  strings('profile.kebabOptions_duplicate'),
  strings('profile.kebabOptions_disable')
];
const friendKebabOptions = [
  strings('profile.kebabOptions_shareQR'),
  strings('profile.kebabOptions_shareLink'),
  // strings('profile.kebabOptions_unfollow'),
  strings('profile.kebabOptions_merge'),
  strings('profile.kebabOptions_remove'),
  strings('profile.kebabOptions_report')
];
let profileNames = [];
let copyFromIndex = 0;
let copyToIndex = 0;

class ProfileAvatar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      cameraRollStatus: '',
      isDuplicateModalVisible: false,
      isDisableModaleVisible: false,
      isRemoveModalVisible: false
    };
    this.setCameraRollStatus();
  }

  /**
  * Component Will Mount
  **/
  componentWillMount() {
    this.populateKebabLastOption();
    profileNames = [];
    for (let i = 0; i < this.props.profiles.length; i++) {
      profileNames.push(this.props.profiles[i].profileName);
    }
  }

  /**
  * Copies the profile data from the copyFromIndex to the copyToIndex profile
  **/
  onDuplicateButtonPress() {
    if (copyFromIndex === copyToIndex) {
      return;
    }

    const {
      profileBizCardImg,
      profileAvatarImg,
      firstName,
      lastName,
      fullName,
      headline,
      location,
      primaryPhone,
      secondaryPhone,
      extension,
      titleAndCompany,
      about,
      howIHelp,
      whatINeed,
      experience,
      education,
      workPhone,
      fax,
      profileEmail,
      website,
      street,
      address2,
      city,
      region,
      postalCode,
      country,
      keywords,
      referralId,
      isDisabled,
    } = this.props.profiles[copyFromIndex];

    const { profileName, uid } = this.props.profiles[copyToIndex];

    this.props.profileSave({
      profileBizCardImg,
      profileAvatarImg,
      firstName,
      lastName,
      fullName,
      headline,
      location,
      primaryPhone,
      secondaryPhone,
      extension,
      titleAndCompany,
      about,
      howIHelp,
      whatINeed,
      experience,
      education,
      workPhone,
      fax,
      profileEmail,
      website,
      street,
      address2,
      city,
      region,
      postalCode,
      country,
      keywords,
      referralId,
      profileName,
      isDisabled,
      uid // DON'T DELETE THIS PROPERTY WHEN UPDATING LIST
    });
    this.setState({ isDuplicateModalVisible: false });
  }

  /**
  * Sends user to the gallery to upload image from device
  **/
  onPickImageButtonPress = async () => {
    if (this.state.cameraRollStatus !== 'granted') {
      await Permissions.askAsync(Permissions.CAMERA_ROLL)
      .then((data) => {
        if (data.status !== 'granted') {
          Alert.alert(strings('common.error.permissionDenied_cameraRoll'));
          Linking.openURL('app-settings:');
          return;
        }
      }).catch(err => console.error('askAsync camera roll error ', err));
      this.setCameraRollStatus();
    }

    const result = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      aspect: [3.5, 2],
      base64: true,
      mediaTypes: ImagePicker.MediaTypeOptions.Images
    });

    if (!result.cancelled) {
      this.processImage(result.uri);
    }
  };

  /**
  * Opens the camera for the user to take a new photo
  **/
  onTakePhotoButtonPress = async () => {
    const result = await ImagePicker.launchCameraAsync({
      allowsEditing: true,
      aspect: [4, 3],
      base64: true
    });

    if (!result.cancelled) {
      this.processImage(result.uri);
    }
  };

  /**
  * Disables the profile
  **/
  onDisableAccept() {
    this.toggleProfileEnabled();
    this.setState({ isDisableModaleVisible: false });
  }

  /**
  * Closes the modal
  **/
  onDisableDecline() {
    this.setState({ isDisableModaleVisible: false });
  }

  /**
  * Removes the friend upon button press
  **/
  onRemoveAccept() {
    const { myFriendId, userId, otherFriendId } = this.props.navigation.state.params;
    this.props.socialRemoveFriend({ myFriendId, userId, otherFriendId });
    this.setState({ isRemoveModalVisible: false });
    this.props.navigation.goBack();
    this.props.friendsFetch();
  }

  /**
  * Prevents friend removal and closes modal upon button press
  **/
  onRemoveDecline() {
    this.setState({ isRemoveModalVisible: false });
  }

  /**
  * Gets the current permission state of the app for camera roll/photos
  **/
  setCameraRollStatus = async () => {
    const { status } = await Permissions.getAsync(Permissions.CAMERA_ROLL);
    this.setState({ cameraRollStatus: status });
  }

  /**
  * Toggles whether or not the profile is enabled
  **/
  async toggleProfileEnabled() {
    this.props.profileToggleDisabled({ isDisabled: !this.props.isDisabled, uid: this.props.uid });
    await this.props.profileUpdate({ prop: 'isDisabled', value: !this.props.isDisabled });
    this.populateKebabLastOption();
  }

  /**
  * Takes the chosen image in base64 and saves the base64
  **/
  processImage = async (uri) => {
    if (this.props.formType === CONTACT_FORM) {
      this.props.contactUpdate({ prop: 'contactAvatarImg', value: uri });
    } else if (this.props.formType === PROFILE_FORM) {
      this.props.profileUpdate({ prop: 'profileAvatarImg', value: uri });
    } else if (this.props.formType === SOCIAL_FORM) {
      this.props.profileUpdate({ prop: 'socialAvatarImg', value: uri });
    }
  }

  /**
  * Populates last option of the kebab menu based on disabled or not
  **/
  populateKebabLastOption() {
    profileKebabOptions.pop();
    profileKebabOptions.push(this.props.isDisabled ? strings('profile.kebabOptions_enable') : strings('profile.kebabOptions_disable'));
  }

  /**
  * Performs an action based on the option selected from the kebab menu
  **/
  async processProfileKebabSelection(idx) {
    const { profileAvatarImg, fullName, titleAndCompany, tagferId, uid } = this.props;
    switch (idx) {
      case '0':
        this.props.profileUpdate({ prop: 'success', value: false });
        this.props.profileUpdate({ prop: 'loading', value: false });
        this.props.navigation.navigate('shareProfileQRCodeScreen', { profileAvatarImg, fullName, titleAndCompany, tagferId, uid });
        break;

      case '1':
        this.props.profileUpdate({ prop: 'success', value: false });
        this.props.profileUpdate({ prop: 'loading', value: false });
        this.shareLink(tagferId, uid);
        break;

      case '2':
        this.props.profileUpdate({ prop: 'success', value: false });
        this.props.profileUpdate({ prop: 'loading', value: false });
        this.props.navigation.navigate('profileEdit');
        break;

      case '3':
        this.props.profileUpdate({ prop: 'success', value: false });
        this.props.profileUpdate({ prop: 'loading', value: false });
        this.setState({ isDuplicateModalVisible: true });
        break;

      case '4':
        if (this.props.isDisabled) {
          this.toggleProfileEnabled();
        } else {
          this.setState({ isDisableModaleVisible: true });
        }
        break;

      default:
        break;
    }
  }

  /**
  * Performs an action based on the option selected from the kebab menu
  **/
  async processSocialKebabSelection(idx) {
    const { profileAvatarImg, fullName, titleAndCompany, otherTagferId, otherUserId, otherProfileId, myFriendId } = this.props.navigation.state.params;
    switch (idx) {
      case '0':
        this.props.profileUpdate({ prop: 'success', value: false });
        this.props.profileUpdate({ prop: 'loading', value: false });
        this.props.navigation.navigate('shareProfileQRCodeScreen', { profileAvatarImg, fullName, titleAndCompany, otherTagferId, otherUserId });
        break;

      case '1':
        this.props.profileUpdate({ prop: 'success', value: false });
        this.props.profileUpdate({ prop: 'loading', value: false });
        this.shareLink(otherTagferId, otherUserId);
        break;

      case '2':
        this.props.navigation.navigate('socialMergeScreen', { fullName, titleAndCompany, otherTagferId, otherUserId, myFriendId });
        break;

      case '3':
        this.setState({ isRemoveModalVisible: !this.state.isRemoveModalVisible });
        break;

      case '4':
        MailComposer.composeAsync({
          recipients: ['abuse@tagfer.com'],
          subject: strings('common.forms.reportContact_emailHeader'),
          body: strings('common.forms.reportContact_emailMessage', { otherTagferId, otherProfileId })
        });
        break;

      default:
        break;
    }
  }

  /**
  * Opens the normal hardware process for sharing something via social, sms, etc
  * uid - the uid for the profile to be shared
  **/
  shareLink(tagferId, uid) {
    Share.share(
      {
        message: strings('common.linking.shareProfile_body', { tagferId, DEV_LINKING_BASE_URL, uid }),
        title: strings('common.linking.shareProfile_title'),
        url: `${TAGFER_BASE_URL}${tagferId}/${uid}`
      },
      {
        tintColor: 0x056ecf,
        excludedActivityTypes: [
          'com.apple.UIKit.activity.PostToWeibo',
          'com.apple.UIKit.activity.Print',
          'com.apple.UIKit.activity.CopyToPasteboard',
          'com.apple.UIKit.activity.AssignToContact',
          'com.apple.UIKit.activity.SaveToCameraRoll',
          'com.apple.UIKit.activity.AddToReadingList',
          'com.apple.UIKit.activity.PostToFlickr',
          'com.apple.UIKit.activity.PostToVimeo',
          'com.apple.UIKit.activity.PostToTencentWeibo',
          'com.apple.UIKit.activity.AirDrop',
          'com.apple.UIKit.activity.OpenInIBooks',
          'com.apple.UIKit.activity.MarkupAsPDF',
          'com.apple.reminders.RemindersEditorExtension', //Reminders
          'com.apple.mobilenotes.SharingExtension', // Notes
          'com.apple.mobileslideshow.StreamShareService', // iCloud Photo Sharing - This also does nothing :{

          // Not supported
          'com.linkedin.LinkedIn.ShareExtension', //LinkedIn
          'pinterest.ShareExtension', //Pinterest
          'com.google.GooglePlus.ShareExtension', //Google +
          'com.tumblr.tumblr.Share-With-Tumblr', //Tumblr
          'wefwef.YammerShare', //Yammer
          'com.hootsuite.hootsuite.HootsuiteShareExt', //HootSuite
          'net.naan.TwitterFonPro.ShareExtension-Pro', //Echofon
          'net.whatsapp.WhatsApp.ShareExtension' //WhatsApp
        ]
      }
    );
  }

  /**
  * Renders the avatar cirle on profiles
  **/
  renderAvatarPhoto() {
    let base64 = '';
    if (this.props.formType === CONTACT_FORM) {
      base64 = this.props.contactAvatarImg;
    } else if (this.props.formType === PROFILE_FORM) {
      base64 = this.props.profileAvatarImg;
    } else if (this.props.formType === SOCIAL_FORM) {
      base64 = this.props.socialAvatarImg;
    }
    if (base64) {
      if (this.props.isEditMode) {
        return (
          <View style={styles.avatarEditStyle}>
            <Image
              source={{ uri: base64 }}
              style={styles.avatarStyle}
            />
            {this.renderPhotoButtons()}
          </View>
        );
      }
      // Not edit mode but has avatar image
      return (
        <View>
          <Image
            source={{ uri: base64 }}
            style={styles.avatarStyle}
          />
        </View>
      );
    }

    // No profile Image
    if (this.props.isEditMode) {
      return (
        <View style={styles.noAvatarEditStyle}>
          <Icon
            name='account-circle'
            size={150}
            color={colors.lightTeal}
          />
          {this.renderPhotoButtons()}
        </View>
      );
    }
    return (
      <View>
        <Icon
          name='account-circle'
          size={150}
          color={colors.lightTeal}
        />
      </View>
    );
  }

  /**
  * Renders the photo buttons
  **/
  renderPhotoButtons() {
    if (this.props.formType === SOCIAL_FORM) {
      return <View style={styles.buttonContainerStyle} />;
    }
    return (
      <View style={styles.buttonContainerStyle}>
        <TouchableOpacity
          onPress={this.onPickImageButtonPress.bind(this)}
          disabled={this.props.loading}
        >
          <Text style={styles.textButtonStyle}>{strings('common.buttons.uploadImage')}</Text>
        </TouchableOpacity>

        <Text style={styles.photoButtonsOrTextStyle}>{strings('profile.or')}</Text>

        <TouchableOpacity
          onPress={this.onTakePhotoButtonPress.bind(this)}
          disabled={this.props.loading}
        >
          <Text style={styles.textButtonStyle}>{strings('common.buttons.takePhoto')}</Text>
        </TouchableOpacity>
      </View>
    );
  }

  /**
  * Adds an icon on the right of the profile row if it is the selected profile
  **/
  renderHightlightedIcon(highlighted) {
    return (
      <Image
        style={styles.highlightedImageStyle}
        mode='stretch'
        source={highlighted ? GREEN_CHECK_IMAGE : null}
      />
    );
  }

  /**
  * Adds an icon to the left of the profile name in the profile row
  **/
  renderLeftIcon(rowID) {
    const base64 = this.props.profiles[rowID].profileAvatarImg;

    if (base64) {
      return (
        <View style={styles.leftIconStyle}>
          <Image
            source={{ uri: base64 }}
            style={styles.avatarSmallImageStyle}
          />
          <Text style={[styles.modalDropdownDropdownTextStyle, { color: this.props.profiles[rowID].isDisabled ? colors.lightGrey : colors.black }]}>
            {profileNames[rowID]}
          </Text>
        </View>
      );
    }

    return (
      <View style={styles.leftIconStyle}>
        <Icon
          name={'account-circle'}
          size={30}
          color={colors.middleGrey}
        />
        <Text style={[styles.modalDropdownDropdownTextStyle, { color: this.props.profiles[rowID].isDisabled ? colors.lightGrey : colors.black }]}>
          {profileNames[rowID]}
        </Text>
      </View>
    );
  }

  /**
  * Used for custom styling of the modal dropdown
  **/
  renderDuplicateModalDropdownRow(rowData, rowID, highlighted) {
    return (
      <View style={{ backgroundColor: this.props.profiles[rowID].isDisabled ? colors.offWhite : colors.white }}>
        <View style={styles.modalDropdownDropdownViewStyle}>
          {this.renderLeftIcon(rowID)}

          {this.renderHightlightedIcon(highlighted)}
        </View>
      </View>
    );
  }

  /**
  * Renders the kebab menu
  **/
  renderKebab() {
    if (!this.props.isEditMode) {
      if (this.props.formType === PROFILE_FORM) {
        return (
          <View style={styles.kebabViewStyle}>
            <ModalDropdown
              style={styles.modalDropdownStyle}
              dropdownStyle={styles.profileModalDropsdownDropdownStyle}
              dropdownTextStyle={styles.modalDropsdownDropdownTextStyle}
              options={profileKebabOptions}
              onSelect={(idx) => this.processProfileKebabSelection(idx)}
            >
              <Icon
                name={'more-vert'}
                size={40}
                containerStyle={{ paddingLeft: 10, paddingTop: 10 }}
              />
            </ModalDropdown>
          </View>
        );
      } else if (this.props.formType === SOCIAL_FORM) {
        return (
          <View style={styles.kebabViewStyle}>
            <ModalDropdown
              style={styles.modalDropdownStyle}
              dropdownStyle={styles.socialModalDropdownDropdownStyle}
              dropdownTextStyle={styles.modalDropsdownDropdownTextStyle}
              options={friendKebabOptions}
              onSelect={(idx) => this.processSocialKebabSelection(idx)}
            >
              <Icon
                name={'more-vert'}
                size={40}
                containerStyle={{ paddingLeft: 10, paddingTop: 10 }}
              />
            </ModalDropdown>
          </View>
        );
      }
    }
  }

  /**
  * Render method
  **/
  render() {
    const name = `${this.props.fullName}`;

    return (
      <View>
        <View style={styles.avatarViewStyle}>
          {this.renderAvatarPhoto()}
        </View>
        {this.renderKebab()}

        <Modal
          transparent
          animationType="slide"
          visible={this.state.isDuplicateModalVisible}
          onRequestClose={() => {}}
        >
          <TouchableOpacity
            style={styles.modalOpacityStyle}
            activeOpacity={1}
            onPressOut={() => this.setState({ isDuplicateModalVisible: false })}
          >
            <ScrollView
              directionalLockEnabled
              centerContent
              contentContainerStyle={styles.modalScrollViewStyle}
            >
              <TouchableWithoutFeedback>
                <View>
                  <View style={styles.duplicateMainViewStyle}>
                    <View />
                    <View>
                      <Spacer />
                      <Text style={styles.leftAlignedTextStyle}>{strings('profile.duplicateScreen_duplicateBasicInfo')}</Text>
                      <Spacer />
                      <Text style={styles.leftAlignedTextStyle}>{strings('profile.duplicateScreen_duplicateFrom')}</Text>
                      <Spacer />
                      <ModalDropdown
                        style={styles.duplicateModalDropdownStyle}
                        dropdownStyle={styles.modalDropdownDropdownStyle}
                        options={profileNames}
                        renderRow={this.renderDuplicateModalDropdownRow.bind(this)}
                        onSelect={(idx) => {
                          copyFromIndex = idx;
                        }}
                      />
                    </View>

                    <View>
                      <Spacer />
                      <Text style={styles.leftAlignedTextStyle}>{strings('profile.duplicateScreen_duplicateTo')}</Text>
                      <Spacer />
                      <ModalDropdown
                        style={styles.duplicateModalDropdownStyle}
                        dropdownStyle={styles.modalDropdownDropdownStyle}
                        options={profileNames}
                        renderRow={this.renderDuplicateModalDropdownRow.bind(this)}
                        onSelect={(idx) => {
                          copyToIndex = idx;
                        }}
                      />
                    </View>

                    <Button
                      onPress={() => this.onDuplicateButtonPress()}
                      title={strings('common.buttons.duplicate')}
                      buttonStyle={styles.buttonStyle}
                      fontWeight="bold"
                      fontSize={25}
                    />
                    <Spacer />
                  </View>
                </View>
              </TouchableWithoutFeedback>
            </ScrollView>
          </TouchableOpacity>
        </Modal>

        <Confirm
          visible={this.state.isDisableModaleVisible}
          onAccept={this.onDisableAccept.bind(this)}
          onDecline={this.onDisableDecline.bind(this)}
        >
          {strings('profile.kebabOptions_disableInfo')}
        </Confirm>

        <Confirm
          visible={this.state.isRemoveModalVisible}
          onAccept={this.onRemoveAccept.bind(this)}
          onDecline={this.onRemoveDecline.bind(this)}
        >
          {strings('common.modal.confirm_delete', { name })}
        </Confirm>
      </View>
    );
  }
}

const styles = {
  buttonContainerStyle: {
    flex: 2,
    marginTop: 15,
    flexDirection: 'column',
    justifyContent: 'center'
  },
  textButtonStyle: {
    fontSize: 20,
    fontWeight: 'bold',
    color: colors.labelBlue,
    marginTop: 5,
    marginBottom: 5,
    marginLeft: 15
  },
  photoButtonsOrTextStyle: {
    fontSize: 20,
    fontWeight: 'bold',
    color: colors.lightGrey,
    marginTop: 5,
    marginBottom: 5,
    marginLeft: 15
  },
  kebabViewStyle: {
    position: 'absolute'
  },
  modalDropdownStyle: {
    alignSelf: 'center',
  },
  profileModalDropsdownDropdownStyle: {
    width: SCREEN_WIDTH * 0.6,
    height: 215,
    borderColor: colors.lightgrey,
    borderWidth: 1,
    marginLeft: 40,
    marginTop: -30
  },
  socialModalDropdownDropdownStyle: {
    width: SCREEN_WIDTH * 0.6,
    height: 210,
    borderColor: colors.lightgrey,
    borderWidth: 1,
    marginLeft: 40,
    marginTop: -30
  },
  modalDropsdownDropdownTextStyle: {
    fontSize: 18
  },
  modalTextStyle: {
    flex: 1,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    lineHeight: 40
  },
  avatarViewStyle: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 10
  },
  avatarEditStyle: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginLeft: 25
  },
  noAvatarEditStyle: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginLeft: 10
  },
  avatarStyle: {
    width: 125,
    height: 125,
    borderWidth: 1,
    borderRadius: 60,
    marginTop: 15
  },
  modalOpacityStyle: {
    backgroundColor: colors.modalTransparency,
    position: 'relative',
    flex: 1,
    justifyContent: 'center'
  },
  modalScrollViewStyle: {
    backgroundColor: colors.white,
  },
  modalCardStyle: {
    justifyContent: 'center'
  },
  duplicateMainViewStyle: {
    backgroundColor: colors.white,
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    alignItems: 'flex-start',
    paddingRight: 10
  },
  leftAlignedTextStyle: {
    textAlign: 'left',
    marginLeft: 20,
    marginRight: 20,
    fontSize: 15
  },
  duplicateModalDropdownStyle: {
    marginLeft: 20
  },
  modalDropdownDropdownViewStyle: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    height: 40,
    paddingLeft: 10
  },
  leftIconStyle: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'flex-start'
  },
  modalDropdownDropdownStyle: {
    width: SCREEN_WIDTH,
    borderColor: colors.lightGrey,
    borderWidth: 1,
    marginLeft: -10
  },
  modalDropdownDropdownTextStyle: {
    fontSize: 18,
    marginLeft: 10
  },
  highlightedImageStyle: {
    width: 30,
    height: 30,
    borderRadius: 15,
    marginRight: 10
  },
  avatarSmallImageStyle: {
    width: 30,
    height: 30,
    borderWidth: 1,
    borderRadius: 15
  },
  buttonStyle: {
    width: SCREEN_WIDTH * 0.9,
    marginTop: 15,
    marginBottom: 30,
    borderRadius: 5,
    backgroundColor: colors.buttonBlue
  }
};

/**
* Map State To Props
**/
const mapStateToProps = (state) => {
  // converts Profile objects into profile arrays
  const profiles = _.map(state.profiles, (val, uid) => {
      return { ...val, uid };
  });

  const {
    contactAvatarImg,
  } = state.contactForm;

  const {
    socialAvatarImg
  } = state.socialContacts;

  const {
    isDisabled,
    profileAvatarImg,
    uid
  } = state.profileForm;

  return {
    profiles,
    contactAvatarImg,
    socialAvatarImg,
    isDisabled,
    profileAvatarImg,
    uid
  };
};

export default connect(mapStateToProps, {
  contactUpdate, profileToggleDisabled, profileSave, profileUpdate, socialRemoveFriend
})(ProfileAvatar);
