<template>
  <div class="account-new">
    <h1 class="title is-1" v-t="'account.create'"></h1>
    <form @submit.prevent="submitAccount">
      <div class="columns is-multiline">
        <div class="column is-half">
          <h3 class="subtitle is-3">Nom</h3>
          <div class="field">
            <div class="control">
              <input type="text" class="input" maxlength="30" v-model="name" required />
            </div>
            <p
              class="help is-primary"
            >{{ $tc('validation.max_char', 30 - name.length, { max: 30 - name.length }) }}</p>
          </div>
        </div>
        <div class="column is-half">
          <h3 class="subtitle is-3" v-t="'account.main_currency'"></h3>
          <div class="control">
            <div class="select is-fullwidth">
              <select name="main-currency" id="main-currency" v-model="mainCurrency">
                <option
                  v-for="(cur, k) in currencies"
                  :key="k"
                  :value="cur"
                >{{ cur.name }} {{ cur.symbol }}</option>
              </select>
            </div>
          </div>
        </div>
        <div class="column is-half">
          <h3 class="subtitle is-3">Compte privé / public</h3>
          <div class="field">
            <input
              id="is-public"
              type="checkbox"
              name="is-public"
              class="switch"
              v-model="isPublic"
            />
            <label for="is-public">Compte {{ isPublic ? 'public' : 'privé' }}</label>
            <p class="help is-danger" v-if="isPublic" v-t="'account.publicInformation'"></p>
            <p class="help is-primary" v-else v-t="'account.privateInformation'"></p>
          </div>
        </div>
        <div class="column is-half">
          <color-picker v-model="color" />
        </div>
        <div class="column is-half">
          <account-user-new v-model="users" />
        </div>
        <div class="column is-half">
          <h3 class="subtitle is-3 title-currency" @click="toggleCurrencyShow">
            <div class="icon-container">
              <awe-icon icon="chevron-right" :rotation="currencyShow ? 90 : undefined" />
            </div>
            {{ $tc('account.used_currencies', accountCurrencies.length, { count: accountCurrencies.length }) }}
          </h3>
          <transition name="fade">
            <div class="currency-list" v-if="currencyShow">
              <div class="field">
                <div class="columns is-multiline">
                  <div class="column is-half" v-for="(currency, k) in currencies" :key="k">
                    <input
                      class="is-checkradio is-block is-medium"
                      type="checkbox"
                      :name="`cur-${currency.code}`"
                      :id="`cur-${currency.code}`"
                      v-model="accountCurrencies"
                      :value="currency"
                      :disabled="currency.code === mainCurrency.code"
                    />
                    <label
                      :for="`cur-${currency.code}`"
                    >{{ currency.name }} ({{ currency.symbol || currency.code }})</label>
                  </div>
                </div>
              </div>
            </div>
          </transition>
        </div>
      </div>
      <div class="columns is-centered">
        <div class="column is-half">
          <button type="submit" class="button is-primary is-fullwidth is-large">
            <awe-icon icon="check" />
          </button>
        </div>
      </div>
    </form>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import { Getter } from 'vuex-class'
import currencies from '@/data/currencies'
import IAccount from '@/models/IAccount'
import ICurrency from '@/models/ICurrency'
import accountService from '@/services/AccountService'
import IUser from '@/models/IUser'
import notif from '@/utils/notif'
import { slug } from '@/utils'

@Component({
  components: {
    'color-picker': () => import('@/components/ColorPicker.vue'),
    'account-user-new': () => import('@/components/AccountUserNew.vue')
  }
})
export default class AccountNew extends Vue {
  @Getter
  public user!: IUser | null
  public name: string = ''
  public currencies: ICurrency[] = currencies
  public mainCurrency: ICurrency = currencies[0]
  public accountCurrencies: ICurrency[] = [currencies[0]]
  public color: string | null = null
  public users: IUser[] = []
  public currencyShow: boolean = false
  public isPublic: boolean = false

  public mounted(): void {
    if (this.user && !this.user.alias) {
      this.user.alias = this.user.userId
    }
  }

  public toggleCurrencyShow(): void {
    this.currencyShow = !this.currencyShow
  }

  public validate(users: IUser[]): boolean {
    if (!this.name) {
      notif.error('Le nom doit être rempli.')
      return false
    }
    const aliases: string[] = users.map((user: IUser) =>
      user.alias ? user.alias.toLowerCase() : ''
    )
    if (aliases.length === 0) {
      notif.error('Au moins une personne doit être ajoutée au compte.')
      return false
    }
    if (aliases.length !== new Set(aliases).size) {
      notif.error('Les alias doivent être uniques.')
      return false
    }

    if (this.user) {
      const userIds: string[] = users.map((user: IUser) => user.userId)
      if (userIds.length !== new Set(userIds).size) {
        notif.error('Les identifiants doivent être uniques.')
        return false
      }
    }

    return true
  }

  public async submitAccount(): Promise<void> {
    let users: IUser[] = this.user ? [this.user, ...this.users] : this.users
    if (!this.validate(users)) {
      return
    }
    users = users.map((u: IUser) => ({
      userId: u.userId,
      email: u.email,
      slugEmail: u.slugEmail,
      premium: u.premium,
      alias: u.alias,
      firstname: u.firstname,
      lastname: u.lastname
    }))
    const userIds: string[] = users.map((u: IUser) => slug(u.userId))
    const newAccount: IAccount = {
      name: this.name,
      admin: this.user
        ? {
            userId: this.user.userId,
            email: this.user.email,
            slugEmail: this.user.slugEmail,
            premium: this.user.premium,
            alias: this.user.alias,
            firstname: this.user.firstname,
            lastname: this.user.lastname
          }
        : null,
      color: this.color,
      users,
      userIds,
      mainCurrency: this.mainCurrency,
      currencies: this.accountCurrencies,
      isPublic: this.isPublic
    }
    const response: PouchDB.Core.Response = await accountService.add(newAccount)
    if (response.ok) {
      this.$router.push({ name: 'account', params: { id: response.id } })
    } else {
      // tslint:disable-next-line:no-console
      console.warn(response)
      notif.error(`Une erreur s'est produite à la création d'un compte.`)
    }
  }

  @Watch('mainCurrency', { immediate: true })
  public onMainCurrencyChange(
    currency: ICurrency,
    oldCurrency: ICurrency
  ): void {
    if (oldCurrency) {
      this.accountCurrencies = this.accountCurrencies.filter(
        (c: ICurrency) => c.code !== oldCurrency.code
      )
    }
    const cur: ICurrency | undefined = this.currencies.find(
      (c: ICurrency) => c.code === currency.code
    )
    if (cur) {
      const already: ICurrency | undefined = this.accountCurrencies.find(
        (c: ICurrency) => c.code === cur.code
      )
      if (!already) {
        this.accountCurrencies.push(cur)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
@import '~bulma-switch';

h3 {
  max-width: 400px;
  margin: auto;
}
.icon-container {
  float: left;

  svg {
    transition: transform 0.3s cubic-bezier(0.55, 0, 0.1, 1);
  }
}
.title-currency {
  &:hover {
    cursor: pointer;
  }
}
.currency-list {
  margin-top: 10px;
  max-height: 50vh;
  overflow-y: auto;
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s cubic-bezier(0.55, 0, 0.1, 1),
    transform 0.3s cubic-bezier(0.55, 0, 0.1, 1);
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
  transform: translateY(-50px);
}
</style>

