<template>
  <v-flex id="walletMetamaskSetup">
    <div v-if="!metamaskEnabled" class="alert alert-info">
      <i class="uiIconInfo"></i>
      <span v-if="walletAddress">Current wallet is in readonly mode.</span>
      <br v-if="walletAddress"/>
      <span>Please install or enable Metamask extension in your browser</span>
      <br />
      <button class="btn" @click.stop="installInstructionDialog = true">
        See help
      </button>
      <div>Or</div>
      <button class="btn" @click.stop="disableMetamaskUsage">
        Switch to use browser wallet
      </button>

      <v-dialog v-model="installInstructionDialog" content-class="uiPopup with-overflow" width="500px" max-width="100wv" @keydown.esc="installInstructionDialog = false">
        <v-card>
          <div class="popupHeader ClearFix">
            <a class="uiIconClose pull-right" aria-hidden="true" @click="installInstructionDialog = false"></a>
            <span class="PopupTitle popupTitle">Enable wallet application</span>
          </div>
          <v-card-text>
            To access your wallet you 'll need to:
            <ol type="1">
              <li>Install/enable <a target="about:blank" href="https://metamask.io/">Metamask</a> in your browser</li>
              <li>Follow setup instructions on Metamask browser plugin</li>
              <li>Connect to Metamask account</li>
              <li v-if="networkLabel && networkLabel.length">Switch Metamask network to <strong>{{ networkLabel }}</strong></li>
              <li>Associate the automatically generated account address from Metamask to your profile (a box will be displayed automaticatty once you enable Metamask on browser)</li>
            </ol>
          </v-card-text>
          <v-card-actions>
            <v-spacer></v-spacer>
            <button class="btn" @click="installInstructionDialog = false">
              Close
            </button>
            <v-spacer></v-spacer>
          </v-card-actions>
        </v-card>
      </v-dialog>
    </div>
    <div v-else-if="!metamaskConnected" class="alert alert-warning">
      <i class="uiIconWarning"></i>
      Please connect to Metamask
    </div>
    <div v-else-if="errorMessage" class="alert alert-error">
      <i class="uiIconError"></i>
      {{ errorMessage }}
    </div>
    <div v-else-if="displaySpaceMetamaskEnableHelp" class="alert alert-info">
      <i class="uiIconInfo"></i>
      Please enable/install Metamask to be able to add a new space account
    </div>
    <div v-else-if="displayNotSameNetworkWarning" class="alert alert-warning">
      <i class="uiIconWarning"></i>
      Please switch Metamask to <strong>{{ networkLabel }}</strong>
    </div>
    <div v-else-if="isAdministration && isPrincipalContractAdmin" class="alert alert-info">
      <i class="uiIconInfo"></i>
      <span>You are using <code>Admin</code> address in metamask</span>
    </div>
    <div v-else-if="isAdministration && !isPrincipalContractAdmin" class="alert alert-warning">
      <i class="uiIconWarning"></i>
      Attention: you are using an account different from<code>Admin</code> account
    </div>
    <div v-else-if="newAddressDetected">
      <div v-if="associatedWalletAddress" class="alert alert-warning">
        <i class="uiIconWarning"></i>
        <span v-if="isAdministration">Attention: you are using a different metamask account from your associated address {{ associatedWalletAddress }}</span>
        <span v-else>Please switch metamask to {{ associatedWalletAddress }} account to be able to send transactions</span>
      </div>
      <br />
      <div v-if="displayAddressAssociationBox" class="alert alert-info">
        <i class="uiIconInfo"></i>
        <span>A new wallet has been detected on Metamask!</span>
        <br />
        <button class="btn" @click.stop="addressAssociationDialog = true">
          See details
        </button>
        <v-dialog v-model="addressAssociationDialog" content-class="uiPopup with-overflow" width="500px" max-width="100wv" @keydown.esc="addressAssociationDialog = false">
          <v-card>
            <div class="popupHeader ClearFix">
              <a class="uiIconClose pull-right" aria-hidden="true" @click="addressAssociationDialog = false"></a>
              <span class="PopupTitle popupTitle">Configure your wallet address</span>
            </div>
            <v-card-text>
              <div v-if="currentAccountAlreadyInUse">
                Currently selected account in Metamask is already in use, you can't use it in this wallet.
              </div>
              <div v-else-if="displaySpaceAccountAssociationHelp">
                Would you like to use the current address <wallet-address :value="detectedMetamaskAccount" /> in Space Wallet ?
              </div>
              <div v-else-if="displayUserAccountAssociationHelp">
                Would you like to use the current address <wallet-address :value="detectedMetamaskAccount" /> in your Wallet ?
              </div>
              <div v-else-if="displayUserAccountChangeHelp">
                Would you like to replace your wallet address <wallet-address :value="associatedWalletAddress" /> by the current address <wallet-address :value="detectedMetamaskAccount" /> ?
              </div>
            </v-card-text>
      
            <v-card-actions v-if="displayAccountHelpActions" class="text-xs-center">
              <v-spacer></v-spacer>
              <button class="btn btn-primary mr-2" @click="saveNewAddressInWallet()">
                Yes
              </button>
              <button class="btn" @click="addressAssociationDialog = false">
                No
              </button>
              <v-spacer></v-spacer>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </div>
    </div>
  </v-flex>
</template>

<script>
import WalletAddress from './WalletAddress.vue';
import * as constants from '../WalletConstants.js';

import {setDraggable, disableMetamask} from '../WalletUtils.js';
import {searchFullName, searchUserOrSpaceObject, saveNewAddress} from '../WalletAddressRegistry.js';

export default {
  components: {
    WalletAddress
  },
  props: {
    isSpace: {
      type: Boolean,
      default: function() {
        return false;
      }
    },
    isSpaceAdministrator: {
      type: Boolean,
      default: function() {
        return false;
      }
    },
    loading: {
      type: Boolean,
      default: function() {
        return false;
      }
    },
    isAdministration: {
      type: Boolean,
      default: function() {
        return false;
      }
    },
    walletAddress: {
      type: String,
      default: function() {
        return null;
      }
    },
    refreshIndex: {
      type: Number,
      default: function() {
        return 0;
      }
    }
  },
  data() {
    return {
      addressAssociationDialog: false,
      installInstructionDialog: false,
      networkLabel: null,
      principalContractAdminAddress: null,
      sameConfiguredNetwork: true,
      associatedWalletAddress: null,
      detectedMetamaskAccount: null,
      currentAccountAlreadyInUse: false,
      metamaskEnabled: false,
      metamaskConnected: false
    };
  },
  computed: {
    displayNotSameNetworkWarning() {
      return this.refreshIndex && !this.sameConfiguredNetwork && (!this.isSpace || !this.associatedWalletAddress);
    },
    isPrincipalContractAdmin() {
      return this.principalContractAdminAddress && this.detectedMetamaskAccount && this.principalContractAdminAddress.toLowerCase() === this.detectedMetamaskAccount.toLowerCase();
    },
    displaySpaceAccountAssociationHelp() {
      return this.refreshIndex && this.isSpace && this.sameConfiguredNetwork && !this.associatedWalletAddress && this.detectedMetamaskAccount;
    },
    displayUserAccountAssociationHelp() {
      return this.refreshIndex && !this.isSpace && this.sameConfiguredNetwork && !this.associatedWalletAddress && this.detectedMetamaskAccount;
    },
    displayAddressAssociationBox() {
      // Display dialog association only when it's not a space or the space doesn't have an associated address yet
      return this.refreshIndex && !this.isAdministration && (!this.isSpace || !this.associatedWalletAddress);
    },
    displayUserAccountChangeHelp() {
      return this.refreshIndex && !this.isSpace && this.sameConfiguredNetwork && this.associatedWalletAddress && this.detectedMetamaskAccount;
    },
    displayAccountHelpActions() {
      return this.refreshIndex && this.sameConfiguredNetwork && !this.currentAccountAlreadyInUse && (this.displayUserAccountChangeHelp || this.displayUserAccountAssociationHelp || this.displaySpaceAccountAssociationHelp);
    },
    displaySpaceMetamaskEnableHelp() {
      return this.refreshIndex && this.isSpace && !this.associatedWalletAddress && !this.detectedMetamaskAccount;
    },
    newAddressDetected() {
      return this.refreshIndex
        && this.sameConfiguredNetwork
        && this.detectedMetamaskAccount
        && this.associatedWalletAddress !== this.detectedMetamaskAccount
        && (!this.isSpace || this.isSpaceAdministrator);
    }
  },
  created() {
    this.init();
    this.$nextTick(() => {
      setDraggable();
    });
  },
  methods: {
    init() {
      if (!window.walletSettings) {
        return;
      }

      this.metamaskEnabled = window.web3 && window.web3.currentProvider;
      this.metamaskConnected = this.metamaskEnabled && window.walletSettings.metamaskConnected;

      this.associatedWalletAddress = window.walletSettings.userPreferences.walletAddress;

      this.addressAssociationDialog = false;
      this.installInstructionDialog = false;
      this.networkLabel = null;
      this.sameConfiguredNetwork = true;
      this.detectedMetamaskAccount = null;
      this.currentAccountAlreadyInUse = false;
      this.principalContractAdminAddress = window.walletSettings.principalContractAdminAddress;

      if (this.metamaskEnabled && this.metamaskConnected) {
        this.detectedMetamaskAccount = window.walletSettings.detectedMetamaskAccount;

        this.sameConfiguredNetwork = window.walletSettings.defaultNetworkId === window.walletSettings.currentNetworkId;
        this.networkLabel = constants.NETWORK_NAMES[window.walletSettings.defaultNetworkId];
        if (!this.networkLabel) {
          this.networkLabel = window.walletSettings.providerURL;
        }

        // compute detected account associated user/space
        if (this.detectedMetamaskAccount !== this.associatedWalletAddress) {
          return this.initAccount();
        }
      }
    },
    initAccount() {
      return searchFullName(this.detectedMetamaskAccount)
        .then((item, error) => {
          if (error) {
            throw error;
          }
          this.currentAccountAlreadyInUse = item && item.id && item.id.length;
          return item;
        })
        .catch(e => {
          console.debug("searchAddress method - error", e);
        });
    },
    saveNewAddressInWallet() {
      return saveNewAddress(
        this.isSpace ? eXo.env.portal.spaceGroup : eXo.env.portal.userName,
        this.isSpace ? 'space' : 'user',
        this.detectedMetamaskAccount)
        .then((resp, error) => {
          if (error) {
            throw error;
          }
          if (resp && resp.ok) {
            this.$emit("refresh");
            this.init();
          } else {
            this.errorMessage = 'Error saving new Wallet address';
          }
        })
        .catch(e => {
          console.debug("saveNewAddress method - error", e);
          this.$emit("error", `Error saving new Wallet address: ${e}`);
        });
    },
    disableMetamaskUsage() {
      disableMetamask(this.isSpace);
      this.$emit("refresh");
    }
  }
};
</script>