<template>
  <v-dialog
    v-model="show"
    content-class="uiPopup with-overflow not-draggable"
    classe="walletSettingsModal"
    width="700px"
    max-width="100vw"
    persistent
    @keydown.esc="show = false">
    <v-card class="elevation-12">
      <div class="popupHeader ClearFix">
        <a
          class="uiIconClose pull-right"
          aria-hidden="true"
          @click="show = false"></a> <span class="PopupTitle popupTitle">
            Preferences
          </span>
      </div>
      <v-card-text v-if="loading || appLoading" class="text-xs-center">
        <v-progress-circular
          color="primary"
          class="mb-2"
          indeterminate />
      </v-card-text>
      <v-card-text v-show="!loading && !appLoading">
        <div v-if="error && !loading" class="alert alert-error v-content">
          <i class="uiIconError"></i>{{ error }}
        </div>
        <v-flex>
          <v-tabs
            ref="settingsTabs"
            v-model="selectedTab"
            class="pl-3 pr-3">
            <v-tabs-slider />
            <v-tab v-if="!isSpace">
              Display
            </v-tab>
            <v-tab v-if="walletAddress">
              Security
            </v-tab>
            <v-tab v-if="!isSpace">
              Advanced
            </v-tab>
            <v-tab v-if="walletAddress">
              Details
            </v-tab>
          </v-tabs>
          <v-tabs-items v-model="selectedTab">
            <v-tab-item v-if="!isSpace">
              <v-card>
                <v-card-text>
                  <v-combobox
                    v-model="selectedCurrency"
                    :items="currencies"
                    label="Select fiat currency used to display ether amounts conversion" />
                  <v-combobox
                    v-model="selectedOverviewAccounts"
                    :items="accountsList"
                    label="List of currencies to use (by order)"
                    placeholder="List of contracts, ether and fiat to use in wallet application (by order)"
                    multiple
                    deletable-chips
                    chips />
                </v-card-text>
              </v-card>
            </v-tab-item>
            <v-tab-item v-if="walletAddress">
              <v-card>
                <v-card-text>
                  <div>
                    <h4>
                      Account type
                      <information-bubble>
                        <v-btn class="inlineIconButton" icon>
                          <i class="uiIconInformation"></i>
                        </v-btn>
                        <template slot="content">
                          <ul>
                            <li>
                              <strong>
                                Connect with browser (recommended):
                              </strong> <p>
                                Your wallet credentials are stored securely <strong>
                                  only
                                </strong> in your current browser's local storage
                              </p>
                            </li>
                            <li>
                              <strong>
                                Connect with Metamask:
                              </strong> <p>
                                <a href="https://metamask.io" target="_blank">
                                  MetaMask
                                </a> is a browser extension that can manage multiple identities
                              </p>
                            </li>
                          </ul>
                        </template>
                      </information-bubble>
                    </h4>
                    <v-radio-group v-model="accountType" @change="changeAccountType">
                      <v-radio label="Connect with browser (recommended)" value="1" />
                      <v-radio label="Connect with Metamask (advanced users)" value="2" />
                    </v-radio-group>
                  </div>

                  <div v-if="displayWalletResetOption" class="mb-3">
                    <h4>
                      Password
                      <information-bubble v-if="autoGeneratedPassword">
                        <v-btn class="inlineIconButton alert" icon>
                          <i class="uiIconWarning"></i>
                        </v-btn>
                        <template slot="content">
                          Your wallet has no password. You can set a password to better protect your funds.
                        </template>
                      </information-bubble>
                    </h4>
                    <wallet-reset-modal
                      button-label="Reset wallet password"
                      display-remember-me
                      @reseted="
                        $emit('settings-changed');
                        refreshFromSettings();
                      " />
                  </div>
                  <div v-if="displayWalletResetOption">
                    <h4>
                      Backup
                      <information-bubble v-if="!backedUp">
                        <v-btn class="inlineIconButton alert" icon>
                          <i class="uiIconWarning"></i>
                        </v-btn>
                        <template slot="content">
                          Your wallet is not backed up yet. You may loose access to your funds permanently!
                        </template>
                      </information-bubble>
                    </h4>
                    <wallet-backup-modal
                      ref="walletBackupModal"
                      :display-complete-message="false"
                      @copied="
                        $emit('copied');
                        refreshFromSettings();
                      " />
                    <wallet-import-key-modal
                      :is-space="isSpace"
                      :wallet-address="walletAddress"
                      class="ml-3"
                      @configured="
                        $emit('settings-changed');
                        refreshFromSettings();
                      " />
                  </div>
                </v-card-text>
              </v-card>
            </v-tab-item>
            <v-tab-item v-if="!isSpace">
              <v-card>
                <v-card-text>
                  <div v-if="!isSpace">
                    <span>
                      Maximum transaction fee
                    </span>
                    <v-slider
                      v-model="defaultGas"
                      :label="`${defaultGas}${defaulGasPriceFiat ? ' (' + defaulGasPriceFiat + ' ' + fiatSymbol + ')' : ''}`"
                      :max="200000"
                      :min="35000"
                      :step="1000"
                      type="number" />
                  </div>
                  <div>
                    <v-switch
                      v-if="!isSpace"
                      v-model="enableDelegation"
                      label="Enable token delegation operations" />
                  </div>
                </v-card-text>
              </v-card>
            </v-tab-item>
            <v-tab-item v-if="walletAddress">
              <v-card>
                <v-card-text>
                  <qr-code
                    ref="qrCode"
                    :to="walletAddress"
                    title="Address QR Code"
                    information="You can send this Wallet address or QR code to other users to send you ether and tokens" />

                  <div class="text-xs-center">
                    <wallet-address :value="walletAddress" />
                  </div>
                </v-card-text>
              </v-card>
            </v-tab-item>
          </v-tabs-items>
        </v-flex>
      </v-card-text>
      <v-card-actions>
        <v-spacer />
        <button
          v-if="!isSpace && selectedTab !== 1 && selectedTab !== 3"
          :disabled="loading"
          :loading="loading"
          class="btn btn-primary mr-1"
          @click="savePreferences">
          Save
        </button> <button
          :disabled="loading"
          :loading="loading"
          class="btn"
          @click="show = false">
          Close
        </button>
        <v-spacer />
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
import QrCode from './QRCode.vue';
import WalletAddress from './WalletAddress.vue';
import WalletResetModal from './WalletResetModal.vue';
import WalletBackupModal from './WalletBackupModal.vue';
import WalletImportKeyModal from './WalletImportKeyModal.vue';
import InformationBubble from './InformationBubble.vue';

import {setDraggable, gasToFiat, enableMetamask, disableMetamask} from '../WalletUtils.js';
import {FIAT_CURRENCIES} from '../WalletConstants.js';

export default {
  components: {
    InformationBubble,
    QrCode,
    WalletResetModal,
    WalletBackupModal,
    WalletImportKeyModal,
    WalletAddress,
  },
  props: {
    title: {
      type: String,
      default: function() {
        return null;
      },
    },
    appLoading: {
      type: Boolean,
      default: function() {
        return false;
      },
    },
    isSpace: {
      type: Boolean,
      default: function() {
        return false;
      },
    },
    open: {
      type: Boolean,
      default: function() {
        return false;
      },
    },
    displayResetOption: {
      type: Boolean,
      default: function() {
        return false;
      },
    },
    fiatSymbol: {
      type: String,
      default: function() {
        return null;
      },
    },
    overviewAccounts: {
      type: Array,
      default: function() {
        return [];
      },
    },
    principalAccountAddress: {
      type: String,
      default: function() {
        return null;
      },
    },
    accountsDetails: {
      type: Object,
      default: function() {
        return {};
      },
    },
  },
  data() {
    return {
      loading: false,
      show: false,
      error: null,
      walletAddress: null,
      selectedTab: 0,
      selectedCurrency: FIAT_CURRENCIES['usd'],
      currencies: [],
      defaultGas: 0,
      accountType: 0,
      enableDelegation: true,
      autoGeneratedPassword: false,
      backedUp: false,
      defaulGasPriceFiat: 0,
      selectedOverviewAccounts: [],
      selectedPrincipalAccount: null,
      etherAccount: {text: 'Ether', value: 'ether', disabled: false},
      fiatAccount: {text: 'Fiat ($, €...)', value: 'fiat', disabled: false},
      accountsList: [],
    };
  },
  computed: {
    displayWalletResetOption() {
      return this.displayResetOption && !this.useMetamaskChoice;
    },
    useMetamaskChoice() {
      return this.accountType === '2';
    },
  },
  watch: {
    walletAddress() {
      if (this.walletAddress) {
        this.$nextTick(() => {
          this.$refs.qrCode.computeCanvas();
        });
      }
    },
    appLoading() {
      if (!this.appLoading) {
        this.refreshFromSettings();
      }
    },
    open() {
      if (this.open) {
        this.error = null;
        this.walletAddress = window.walletSettings.userPreferences.walletAddress;
        this.defaultGas = window.walletSettings.userPreferences.defaultGas ? window.walletSettings.userPreferences.defaultGas : 35000;
        this.defaulGasPriceFiat = this.defaulGasPriceFiat || gasToFiat(this.defaultGas, window.walletSettings.maxGasPriceEther);
        this.accountType = window.walletSettings.userPreferences.useMetamask ? '2' : '1';
        this.enableDelegation = window.walletSettings.userPreferences.enableDelegation;
        this.refreshFromSettings();
        if (window.walletSettings.userPreferences.currency) {
          this.selectedCurrency = FIAT_CURRENCIES[window.walletSettings.userPreferences.currency];
        }

        this.accountsList = [];
        this.selectedOverviewAccounts = [];
        this.selectedPrincipalAccount = null;

        this.accountsList.push(Object.assign({}, this.etherAccount), Object.assign({}, this.fiatAccount));
        if (this.accountsDetails) {
          Object.keys(this.accountsDetails).forEach((key) => {
            const accountDetails = this.accountsDetails[key];
            if (accountDetails.isContract) {
              this.accountsList.push({text: accountDetails.name, value: accountDetails.address, disabled: false});
            }
          });
        }

        this.overviewAccounts.forEach((selectedValue) => {
          const selectedObject = this.getOverviewAccountObject(selectedValue);
          if (selectedObject) {
            this.selectedOverviewAccounts.push(selectedObject);
          }
        });

        this.selectedPrincipalAccount = this.getOverviewAccountObject(this.principalAccountAddress);

        // Workaround to display slider on first popin open
        this.$refs.settingsTabs.callSlider();

        this.show = true;
        this.$nextTick(() => {
          setDraggable();
        });
      }
    },
    selectedPrincipalAccount() {
      if (this.selectedPrincipalAccount) {
        this.selectedOverviewAccounts.forEach((account) => {
          account.disabled = false;
        });

        this.accountsList.forEach((account, index) => {
          if (this.selectedPrincipalAccount.value === account.value) {
            account.disabled = true;
            const accountIndex = this.selectedOverviewAccounts.findIndex((foundSelectedAccount) => foundSelectedAccount.value === account.value);
            if (accountIndex >= 0) {
              this.selectedOverviewAccounts.splice(accountIndex, 1);
            }
            this.selectedOverviewAccounts.unshift(account);
          } else {
            account.disabled = false;
          }
        });
        this.$forceUpdate();
      }
    },
    show() {
      if (!this.show) {
        this.$emit('close');
      }
    },
    defaultGas() {
      this.defaulGasPriceFiat = gasToFiat(this.defaultGas, window.walletSettings.maxGasPriceEther);
    },
  },
  created() {
    Object.keys(FIAT_CURRENCIES).forEach((key) => this.currencies.push(FIAT_CURRENCIES[key]));
  },
  methods: {
    refreshFromSettings() {
      this.autoGeneratedPassword = window.walletSettings.userPreferences.autoGenerated;
      this.backedUp = window.walletSettings.userPreferences.backedUp;
    },
    savePreferences() {
      try {
        if (!this.isSpace) {
          this.loading = true;
          fetch('/portal/rest/wallet/api/account/savePreferences', {
            method: 'POST',
            headers: {
              Accept: 'application/json',
              'Content-Type': 'application/json',
            },
            credentials: 'include',
            body: JSON.stringify({
              defaultGas: this.defaultGas,
              currency: this.selectedCurrency.value,
              principalAccount: this.selectedPrincipalAccount ? this.selectedPrincipalAccount.value : null,
              overviewAccounts: this.selectedOverviewAccounts ? this.selectedOverviewAccounts.map((item) => item.value) : null,
              enableDelegation: this.enableDelegation,
            }),
          })
            .then((resp) => {
              if (resp && resp.ok) {
                window.walletSettings.userPreferences.defaultGas = this.defaultGas;
                window.walletSettings.userPreferences.currency = this.selectedCurrency.value;

                this.$emit('settings-changed', {
                  defaultGas: this.defaultGas,
                  currency: this.selectedCurrency.value,
                });
                this.show = false;
              } else {
                this.error = 'Error saving preferences';
              }
              this.loading = false;
            })
            .catch((e) => {
              console.debug('savePreferences method - error', e);
              this.error = `Error while proceeding: ${e}`;
              this.loading = false;
            });
        }
      } catch (e) {
        console.debug('savePreferences method - error', e);
        this.loading = false;
        this.error = `Error while proceeding: ${e}`;
        this.$emit('end-loading');
      }
    },
    changeAccountType() {
      if (this.useMetamaskChoice) {
        enableMetamask(this.isSpace);
      } else {
        disableMetamask(this.isSpace);
      }
      this.$emit('settings-changed');
    },
    getOverviewAccountObject(selectedValue) {
      if (selectedValue === 'fiat') {
        return Object.assign({}, this.fiatAccount);
      } else if (selectedValue === 'ether') {
        return Object.assign({}, this.etherAccount);
      } else if (this.accountsList && this.accountsList.length) {
        const selectedContractAddress = this.accountsList.findIndex((contract) => contract.value === selectedValue);
        if (selectedContractAddress >= 0) {
          const contract = this.accountsList[selectedContractAddress];
          if (!contract.error) {
            return {text: contract.text, value: contract.value, disabled: false};
          }
        }
      }
    },
  },
};
</script>
