<template>
  <v-flex>
    <v-card-title class="text-xs-center">
      <div v-if="error && String(error).trim() != '{}'" class="alert alert-error v-content">
        <i class="uiIconError"></i> {{ error }}
      </div>
    </v-card-title>
    <div class="ml-5 mr-5">
      <h4 v-show="!selectedTeam">
        <span>Total budget: <strong>{{ computedTotalBudget }} {{ symbol }}</strong></span>
        <template v-if="rewardType === 'FIXED'">
          ({{ eligibleUsersCount }} eligible users)
        </template>
      </h4>
      <h4 v-show="!selectedTeam">
        <span>Configured budget: <strong>{{ configuredBudget }} {{ symbol }}</strong></span>
        <template v-if="rewardType === 'FIXED_PER_MEMBER'">
          ({{ budgetPerMember }} {{ symbol }} per eligible user with {{ eligibleUsersCount }} eligible users)
        </template>
      </h4>
      <h4 v-show="!selectedTeam">
        Sent tokens: <strong>{{ sentTotalBudget }} {{ symbol }}</strong>
      </h4>
    </div>
    <v-container>
      <v-layout>
        <v-flex md4 xs12>
          <v-switch v-model="displayDisabledUsers" label="Display disabled users" />
        </v-flex>
      </v-layout>
      <v-flex>
        <v-text-field
          v-model="search"
          append-icon="search"
          label="Search in name, pools, wallet address"
          single-line
          hide-details />
      </v-flex>
    </v-container>
    <v-data-table
      v-model="selectedIdentitiesList"
      :headers="identitiesHeaders"
      :items="filteredIdentitiesList"
      :loading="loading"
      :sortable="true"
      item-key="address"
      class="elevation-1 mr-3 mb-2"
      select-all
      disable-initial-sort
      hide-actions>
      <template slot="items" slot-scope="props">
        <tr :active="props.selected">
          <td>
            <v-checkbox
              v-if="props.item.address && props.item.points && props.item.enabled && !props.item.disabled && props.item.points >= threshold && (!props.item.status || props.item.status === 'error')"
              :input-value="props.selected"
              hide-details
              @click="props.selected = !props.selected" />
          </td>
          <td>
            <v-avatar size="36px">
              <img :src="props.item.avatar" onerror="this.src = '/eXoSkin/skin/images/system/SpaceAvtDefault.png'">
            </v-avatar>
          </td>
          <td class="text-xs-left">
            <profile-chip
              :address="props.item.address"
              :profile-id="props.item.id"
              :profile-technical-id="props.item.technicalId"
              :space-id="props.item.spaceId"
              :profile-type="props.item.type"
              :display-name="props.item.name"
              :enabled="props.item.enabled && !props.item.disabled"
              :disapproved="props.item.disapproved"
              :deleted-user="props.item.deletedUser"
              :disabled-user="props.item.disabledUser"
              :avatar="props.item.avatar"
              display-no-address />
          </td>
          <td class="text-xs-left">
            <ul v-if="props.item.gamificationTeams && props.item.gamificationTeams.length">
              <li v-for="team in props.item.gamificationTeams" :key="team.id">
                {{ team.name }}
              </li>
            </ul>
            <div v-else>
              -
            </div>
          </td>
          <td>
            <a
              v-if="props.item.hash"
              href="javascript:void(0);"
              target="_blank"
              title="Open transaction in wallet"
              @click="$emit('open-wallet-transaction', props.item)">
              Open in wallet
            </a> <span v-else>
              -
            </span>
          </td>
          <td>
            <template v-if="!props.item.status">
              <v-icon
                v-if="!props.item.address"
                color="warning"
                title="No address">
                warning
              </v-icon>
              <v-icon
                v-else-if="!props.item.points || props.item.points < threshold"
                :title="`No enough points, minimum: ${threshold} points`"
                color="warning">
                warning
              </v-icon>
              <div v-else>
                -
              </div>
            </template>
            <v-progress-circular
              v-else-if="props.item.status === 'pending'"
              color="primary"
              indeterminate
              size="20" />
            <v-icon
              v-else
              :color="props.item.status === 'success' ? 'success' : 'error'"
              :title="props.item.status === 'success' ? 'Successfully proceeded' : props.item.status === 'pending' ? 'Transaction in progress' : 'Transaction error'"
              v-text="props.item.status === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle'" />
          </td>
          <td>
            <v-text-field
              v-if="props.item.address && props.item.points && props.item.enabled && !props.item.disabled && props.item.points >= threshold && (!props.item.status || props.item.status === 'error')"
              v-model.number="props.item.tokensToSend"
              type="number"
              class="input-text-center"
              @change="refreshIndex++" />
            <template v-else-if="props.item.status === 'success' || props.item.status === 'pending'">
              <span>{{ toFixed(props.item.tokensSent) }} {{ symbol }}</span>
            </template>
            <template
              v-else>
              -
            </template>
          </td>
          <td>
            {{ props.item.points }}
          </td>
        </tr>
      </template>
      <template slot="footer">
        <td :colspan="identitiesHeaders.length - 1">
          <strong>
            Total
          </strong>
        </td>
        <td>
          <strong>
            {{ totalTokens }} {{ symbol }}
          </strong>
        </td>
        <td>
          <strong>
            {{ totalPoints }}
          </strong>
        </td>
      </template>
    </v-data-table>

    <send-reward-modal
      :account="walletAddress"
      :contract-details="contractDetails"
      :recipients="recipients"
      :period-type="periodType"
      :start-date-in-seconds="startDateInSeconds"
      :end-date-in-seconds="endDateInSeconds"
      :wallet-reward-type="walletRewardType"
      :default-transaction-label="defaultRewardLabelTemplate"
      :default-transaction-message="defaultRewardMessageTemplate"
      reward-count-field="points"
      @sent="newPendingTransaction"
      @error="error = $event" />
  </v-flex>
</template>

<script>
import SendRewardModal from './WalletAdminSendRewardModal.vue';
import ProfileChip from '../ProfileChip.vue';

import {getPeriodRewardTransactions} from '../../WalletRewardServices.js';
import {watchTransactionStatus} from '../../WalletUtils.js';

export default {
  components: {
    SendRewardModal,
    ProfileChip,
  },
  props: {
    wallets: {
      type: Array,
      default: function() {
        return [];
      },
    },
    walletRewardType: {
      type: String,
      default: function() {
        return null;
      },
    },
    walletAddress: {
      type: String,
      default: function() {
        return null;
      },
    },
    loading: {
      type: Boolean,
      default: function() {
        return false;
      },
    },
    identitiesList: {
      type: Array,
      default: function() {
        return [];
      },
    },
    contractDetails: {
      type: Object,
      default: function() {
        return null;
      },
    },
    threshold: {
      type: Number,
      default: function() {
        return 0;
      },
    },
    periodType: {
      type: String,
      default: function() {
        return null;
      },
    },
    startDateInSeconds: {
      type: Number,
      default: function() {
        return 0;
      },
    },
    endDateInSeconds: {
      type: Number,
      default: function() {
        return 0;
      },
    },
    rewardType: {
      type: String,
      default: function() {
        return null;
      },
    },
    totalBudget: {
      type: Number,
      default: function() {
        return 0;
      },
    },
    budgetPerMember: {
      type: Number,
      default: function() {
        return 0;
      },
    },
    sentTotalBudget: {
      type: Number,
      default: function() {
        return 0;
      },
    },
    computedTotalBudget: {
      type: Number,
      default: function() {
        return 0;
      },
    },
  },
  data() {
    return {
      search: '',
      displayDisabledUsers: false,
      defaultRewardLabelTemplate: '{rewardCount} gamification points earned for period: {startDate} to {endDate}',
      defaultRewardMessageTemplate: 'You have earned {amount} {symbol} in reward for your {rewardCount} gamification points {earned in pool_label} for period: {startDate} to {endDate}',
      refreshIndex: 1,
      selectedIdentitiesList: [],
      identitiesHeaders: [
        {
          text: '',
          align: 'right',
          sortable: false,
          value: 'avatar',
          width: '36px',
        },
        {
          text: 'Name',
          align: 'left',
          sortable: true,
          value: 'name',
        },
        {
          text: 'Pools',
          align: 'center',
          sortable: false,
          value: 'gamificationTeams',
        },
        {
          text: 'Transaction',
          align: 'center',
          sortable: true,
          value: 'hash',
        },
        {
          text: 'Status',
          align: 'center',
          sortable: true,
          value: 'status',
        },
        {
          text: 'Tokens',
          align: 'center',
          sortable: true,
          value: 'tokensToSend',
          width: '80px',
        },
        {
          text: 'Points',
          align: 'center',
          sortable: true,
          value: 'points',
        },
      ],
    };
  },
  computed: {
    symbol() {
      return this.contractDetails && this.contractDetails.symbol ? this.contractDetails.symbol : '';
    },
    eligibleUsersCount() {
      return this.wallets ? this.wallets.filter(wallet => wallet.enabled && !wallet.disabled).length : 0;
    },
    configuredBudget() {
      if (this.rewardType === 'FIXED') {
        return this.totalBudget;
      } else if (this.rewardType === 'FIXED_PER_MEMBER') {
        return this.budgetPerMember * this.eligibleUsersCount;
      }
      return 0;
    },
    recipients() {
      return this.selectedIdentitiesList ? this.selectedIdentitiesList.filter((item) => item.address && item.points && item.enabled && !item.disabled && item.points >= this.threshold && item.tokensToSend && (!item.status || item.status === 'error')) : [];
    },
    validRecipients() {
      return this.identitiesList ? this.identitiesList.filter((item) => item.address && item.enabled && !item.disabled && item.points >= this.threshold) : [];
    },
    filteredIdentitiesList() {
      return this.refreshIndex && this.identitiesList ? this.identitiesList.filter((wallet) => (this.displayDisabledUsers || !wallet.disabled) && this.filterItemFromList(wallet, this.search)) : [];
    },
    selectableRecipients() {
      return this.validRecipients.filter((item) => !item.status || item.status === 'error');
    },
    totalPoints() {
      if (this.filteredIdentitiesList) {
        let result = 0;
        this.filteredIdentitiesList.forEach((wallet) => {
          result += Number(wallet.points);
        });
        return result;
      } else {
        return 0;
      }
    },
    totalTokens() {
      if (this.filteredIdentitiesList) {
        let result = 0;
        this.filteredIdentitiesList.forEach((wallet) => {
          result += wallet.tokensSent ? (wallet.tokensSent ? Number(wallet.tokensSent) : 0) : (wallet.tokensToSend && wallet.tokensToSend > 0 ? Number(wallet.tokensToSend) : 0);
        });
        return this.toFixed(result);
      } else {
        return 0;
      }
    },
  },
  watch: {
    refreshIndex() {
      this.$forceUpdate();
    },
  },
  methods: {
    filterItemFromList(wallet, searchText) {
      if (!searchText || !searchText.length) {
        return true;
      }
      searchText = searchText.trim().toLowerCase();
      const name = wallet.name.toLowerCase();
      if (name.indexOf(searchText) > -1) {
        return true;
      }
      const address = wallet.address.toLowerCase();
      if (address.indexOf(searchText) > -1) {
        return true;
      }
      if (searchText === '-' && (!wallet.gamificationTeams || !wallet.gamificationTeams.length)) {
        return true;
      }
      const teams =
        wallet.gamificationTeams && wallet.gamificationTeams.length
          ? wallet.gamificationTeams
              .map((team) => team.name)
              .join(',')
              .toLowerCase()
          : '';
      return teams.indexOf(searchText) > -1;
    },
    newPendingTransaction(transaction) {
      if (!transaction || !transaction.to) {
        return;
      }
      this.$emit('pending', transaction);
      this.refreshWalletTransactionStatus(transaction);
    },
    refreshWalletTransactionStatus(transaction) {
      if (transaction && transaction.to) {
        const resultWalletIndex = this.selectedIdentitiesList.findIndex((resultWallet) => resultWallet.address && resultWallet.address.toLowerCase() === transaction.to.toLowerCase());
        const resultWallet = this.selectedIdentitiesList[resultWalletIndex];
        if (resultWallet) {
          if(transaction.contractAmount) {
            this.$set(resultWallet, 'tokensSent', transaction.contractAmount);
            this.$set(resultWallet, 'hash', transaction.hash);
            this.$set(resultWallet, 'status', 'pending');

            this.$emit('pending', transaction);

            this.selectedIdentitiesList.splice(resultWalletIndex, 1);
          }
          const thiss = this;
          watchTransactionStatus(transaction.hash, (receipt) => {
            thiss.$set(resultWallet, 'status', receipt && receipt.status ? 'success' : 'error');
            this.$emit('success', transaction, receipt);
          });
        }
      } else {
        getPeriodRewardTransactions(window.walletSettings.defaultNetworkId, this.periodType, this.startDateInSeconds, this.walletRewardType).then((resultTransactions) => {
          if (resultTransactions) {
            resultTransactions.forEach((resultTransaction) => {
              if (resultTransaction) {
                const resultWallet = this.identitiesList.find((resultWallet) => resultWallet.type === resultTransaction.receiverType && (resultWallet.id === resultTransaction.receiverId || resultWallet.identityId === resultTransaction.receiverIdentityId));
                if (resultWallet) {
                  this.$set(resultWallet, 'tokensSent', resultTransaction.tokensAmountSent ? Number(resultTransaction.tokensAmountSent) : 0);
                  this.$set(resultWallet, 'hash', resultTransaction.hash);
                  this.$set(resultWallet, 'status', 'pending');
                  this.$emit('pending', resultTransaction);

                  const thiss = this;
                  watchTransactionStatus(resultTransaction.hash, (receipt) => {
                    thiss.$set(resultWallet, 'status', receipt && receipt.status ? 'success' : 'error');
                    this.$emit('success', resultTransaction, receipt);
                  });
                } else {
                  console.warn("Can't find wallet of a sent result token transaction, resultTransaction=", resultTransaction);
                }
              }
            });
            this.$forceUpdate();
          }
        });
      }
    },
  },
};
</script>
