<template>
  <div v-if="transaction">
    <h4 class="subtitle is-4">{{ transaction.date | fulldate }}</h4>
    <nav class="breadcrumb" aria-label="breadcrumbs" v-if="account">
      <ul>
        <li>
          <router-link
            :to="{ name: 'account', params: { id: account._id }, hash: `#${transaction._id}` }"
          >{{ account.name }}</router-link>
        </li>
        <li class="is-active" v-if="transaction.tag && transaction.tag !== noTag">
          <a href="#" @click.prevent>{{ transactionTagLabel[transaction.tag].label }}</a>
        </li>
        <li class="is-active">
          <a href="#" @click.prevent>{{ transaction.name }}</a>
        </li>
      </ul>
    </nav>
    <div class="resume">
      Dépense payée par
      <span class="pay-by">{{ transaction.payBy }}</span>
      pour
      <span v-if="payForLabel.length > 1">{{ payForLabel.join(', ') }}</span>
      <span v-else>{{ payForLabel[0] }}</span>
      d'une somme de
      <span
        class="numeric"
      >{{ transaction.amount | money(transaction.mainCurrency) }}</span>.
    </div>
    <div v-if="transaction.exchange" class="exchange">
      <div v-if="currencies.length">
        <hr />
        <h2 class="subtitle is-2">Taux d'échange à date</h2>
        <div class="columns is-centered">
          <div class="column">
            <table class="table is-fullwidth is-striped is-bordered">
              <caption>
                <span class="numeric">{{ transaction.amount | money(transaction.mainCurrency) }}</span>
              </caption>
              <tbody>
                <tr v-for="(currency, k) in currencies" :key="k">
                  <td
                    class="numeric"
                  >{{ (transaction.amount * transaction.exchange.rates[currency.code]) | moneypad(currency) }}</td>
                </tr>
              </tbody>
            </table>
          </div>
          <div class="column">
            <table class="table is-fullwidth is-striped is-bordered">
              <caption>
                <span class="numeric">{{ 1 | money(transaction.mainCurrency) }}</span>
              </caption>
              <tbody>
                <tr v-for="(currency, k) in currencies" :key="k">
                  <td
                    class="numeric"
                  >{{ ( transaction.exchange.rates[currency.code]) | moneypad(currency) }}</td>
                </tr>
              </tbody>
            </table>
          </div>
          <div class="column">
            <table class="table is-hoverable is-fullwidth is-striped is-bordered">
              <caption>{{ $tc('transaction.money', currencies.length) }}</caption>
              <tbody>
                <tr v-for="(currency, k) in currencies" :key="k">
                  <td>{{ 1 | money(currency) }}</td>
                  <td
                    class="numeric"
                  >{{ (1 / transaction.exchange.rates[currency.code]) | moneypad(transaction.mainCurrency) }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
    <div v-else>
      <online-view @online="retrieveExchange" />Le taux d'échange n'a pas pu être récupéré.
    </div>
    <div class="buttons is-centered" v-if="!account.archive">
      <router-link
        v-if="canModify"
        tag="button"
        class="button"
        :to="{ name: 'transaction-update', params: { id } }"
      >modifier</router-link>
      <confirm-button class="is-danger" @confirm="removeTransaction">supprimer</confirm-button>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { Getter } from 'vuex-class'
import TransactionType from '@/enums/TransactionType'
import bus, { SYNC } from '@/utils/bus-event'
import notif from '@/utils/notif'
import TransactionTag, { TransactionTagLabel } from '@/enums/TransactionTag'
import accountService from '@/services/AccountService'
import exchangeService from '@/services/ExchangeService'
import transactionService from '@/services/TransactionService'
import IAccount from '@/models/IAccount'
import ICurrency from '@/models/ICurrency'
import ITransaction from '@/models/ITransaction'
import IUser from '@/models/IUser'
import ISplit from '@/models/ISplit'

@Component({
  components: {
    'online-view': () => import('@/components/OnlineView.vue'),
    'confirm-button': () => import('@/components/ConfirmButton.vue')
  }
})
export default class TransactionItem extends Vue {
  @Getter
  public user!: IUser | null
  @Prop({ type: String, required: true })
  public id!: string
  public transaction: ITransaction | null = null
  public account: IAccount | null = null
  public noTag: string = TransactionTag.None
  public transactionTagLabel: typeof TransactionTagLabel = TransactionTagLabel
  public removing: boolean = false

  public created(): void {
    this.getData()
    bus.$on(SYNC, this.getData)
  }

  public beforeDestroy(): void {
    bus.$off(SYNC, this.getData)
  }

  public async getData(docIds?: string[]): Promise<void> {
    if (docIds && !docIds.find((i: string) => i === this.id)) {
      return
    }
    try {
      if (this.removing) {
        return
      }
      this.transaction = await transactionService.get(this.id)
      if (this.transaction) {
        this.account = await accountService.get(this.accountId)
      } else {
        if (this.accountId) {
          this.$router.push({ name: 'account', params: { id: this.accountId } })
          notif.error('Transaction supprimée.')
        } else {
          this.$router.push({ name: 'home' })
          notif.error('Compte inexistant.')
        }
      }
    } catch (error) {
      // tslint:disable-next-line
      console.warn({ error })
      this.$router.push({ name: 'home' })
    }
  }

  public async removeTransaction(): Promise<void> {
    if (!this.transaction) {
      return
    }
    this.removing = true
    const ok: boolean = await transactionService.remove(this.id)
    if (ok) {
      if (this.accountId) {
        this.$router.push({
          name: 'account',
          params: {
            id: this.accountId
          }
        })
      } else {
        this.$router.push({ name: 'home' })
      }
    }
    this.removing = false
  }

  public async retrieveExchange(): Promise<void> {
    if (this.transaction && !this.transaction.exchange) {
      this.transaction.exchange = await exchangeService.get(
        this.transaction.mainCurrency.code,
        this.transaction.date
      )
      await transactionService.save(this.transaction)
    }
  }

  public get accountId(): string {
    return (this.transaction && this.transaction.accountId) || ''
  }

  public get canModify(): boolean {
    if (!this.transaction) {
      return false
    }
    return (
      (this.transaction.transactionType === TransactionType.normal &&
        this.isAdmin) ||
      this.transaction.payBy === this.userAlias
    )
  }

  public get userAlias(): string | undefined {
    if (!this.account || !this.user) {
      return ''
    }
    const user = this.user
    return this.account.users
      .map((u: IUser) => u.slugEmail)
      .find((email: string | undefined) => email === user.slugEmail)
  }

  public get isAdmin(): boolean {
    if (!this.account || !this.user) {
      return true
    }
    return (
      !this.account.admin ||
      this.account.admin.slugEmail === this.user.slugEmail
    )
  }

  public get payForLabel(): string[] {
    if (!this.transaction) {
      return []
    }
    return this.transaction.payFor.map((p: ISplit) => {
      const part =
        p.weight > 1
          ? `(${p.weight} ${this.$tc('transaction.weight', p.weight)})`
          : ''
      return `${p.alias} ${part}`.trim()
    })
  }

  public get currencies(): ICurrency[] {
    if (!this.transaction || !this.transaction.exchange) {
      return []
    }
    const transaction = this.transaction
    const exchange = transaction.exchange
    return transaction.currencies.filter(
      (currency: ICurrency) => exchange && currency.code !== exchange.base
    )
  }
}
</script>

<style scoped>
p.resume {
  font-size: 18pt;
  margin: 15px 0;
}
table.table {
  margin: 15px auto 0;
  max-width: 350px;
}
.main-cell {
  vertical-align: middle;
}
.buttons {
  margin-top: 15px;
}
.pay-by {
  font-weight: bold;
}
.numeric {
  text-align: right;
}
</style>
