<template>
  <div class="account-setting no-margin">
    <div class="columns is-centered">
      <div class="column is-one-third">
        <color-picker v-model="account.color" @color-change="save" />
      </div>
    </div>
    <hr />
    <div>
      <h3 class="subtitle is-3" v-t="'account.users'"></h3>
      <div class="columns is-multiline is-centered">
        <div class="column">
          {{ account.users.map((u) => getUserInfo(u)).join(', ') }}
        </div>
      </div>
      <h3 class="subtitle is-3">Ajouter des amis</h3>
      <div class="columns is-centered">
        <div class="column is-one-third">
          <account-user-new
            v-model="newUsers"
            :default-user="false"
            :show-title="false"
          />
        </div>
      </div>
      <div class="columns is-centered" v-if="newUsers.length">
        <div class="column is-one-third">
          <button
            @click="saveUsers"
            class="button is-primary is-fullwidth is-large"
          >
            <awe-icon icon="check" />
          </button>
        </div>
      </div>
    </div>
    <hr />
    <div class="columns is-centered">
      <div class="column is-one-third" v-if="isMultiUser">
        <account-share :account="account" :can-close="false" />
      </div>
      <div class="column is-one-third">
        <article class="message is-primary is-medium">
          <div class="message-header">
            <p>Actions</p>
          </div>
          <div class="buttons action-buttons is-centered">
            <confirm-button
              v-if="account.archive"
              class="is-warning"
              @confirm="active"
            >
              <span v-t="'account.open'"></span>
            </confirm-button>
            <confirm-button v-else class="is-warning" @confirm="archive">
              <span v-t="'account.close'"></span>
            </confirm-button>
            <confirm-button class="is-danger" @confirm="remove">
              <span v-t="'account.delete'"></span>
            </confirm-button>
          </div>
        </article>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { Getter } from 'vuex-class'
import BaseAccount from '@/base-components/BaseAccount'
import { confirmation } from '@/utils'
import bus, { SYNC } from '@/utils/bus-event'
import IAccount from '@/models/IAccount'
import IUser from '@/models/IUser'
import accountService from '@/services/AccountService'
import queueNotifService from '@/services/QueueNotifService'

@Component({
  components: {
    'confirm-button': () => import('@/components/ConfirmButton.vue'),
    'color-picker': () => import('@/components/ColorPicker.vue'),
    'account-share': () => import('@/components/AccountShare.vue'),
    'account-user-new': () => import('@/components/AccountUserNew.vue')
  }
})
export default class AccountSetting extends Vue {
  @Getter
  public user!: IUser | null
  @Prop({ type: Object, required: true })
  public account!: IAccount
  public removing: boolean = false
  public newUsers: IUser[] = []

  public async active(): Promise<void> {
    const ok: boolean = await accountService.active(this.account._id || '')
    if (ok) {
      this.$router.push({ name: 'home' })
      confirmation(this.$t('account.closed').toString())
    }
  }

  public async archive(): Promise<void> {
    const ok: boolean = await accountService.archive(this.account._id || '')
    if (ok) {
      this.$router.push({ name: 'home' })
      confirmation(this.$t('account.closed').toString())
    }
  }

  public async remove(): Promise<void> {
    const ok: boolean = await accountService.remove(this.account._id || '')
    if (ok) {
      this.$router.push({ name: 'home' })
      confirmation('Compte supprimée')
    }
  }

  public async save(): Promise<void> {
    if (!this.account || !this.account._id) {
      return
    }
    const ok: boolean = await accountService.update(
      this.account._id,
      this.account
    )
    if (!ok) {
      queueNotifService.error(`Une erreur s'est produite.`)
    }
  }

  public async saveUsers(): Promise<void> {
    if (!this.account._id || !this.validate()) {
      return
    }
    this.account.users = [...this.account.users, ...this.newUsers]
    const ok: boolean = await accountService.update(
      this.account._id,
      this.account
    )
    if (!ok) {
      queueNotifService.error(`Une erreur s'est produite.`)
      return
    }
    queueNotifService.success(
      this.$tc('account.newUserAdded', this.newUsers.length).toString()
    )
    this.newUsers = []
  }

  public getUserInfo(user: IUser): string {
    const email = (user.email && ` - ${user.email}`) || ''
    return `${user.alias} (${user.userId}${email})`
  }

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

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

    return true
  }

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

  public get backgroundColor(): any | null {
    if (!this.account.color) {
      return null
    }
    return {
      backgroundColor: this.account.color,
      color: 'white'
    }
  }

  public get isMultiUser(): boolean {
    return this.account.users.length > 1
  }
}
</script>

<style>
.user-id {
  font-family: 'Cutive Mono', monospace;
}
.action-buttons {
  margin: 15px;
}
</style>
