Vue.component(VueQrcode.name, VueQrcode)

const mapCards = obj => {
  obj.date = Quasar.utils.date.formatDate(
    new Date(obj.time * 1000),
    'YYYY-MM-DD HH:mm'
  )

  return obj
}

new Vue({
  el: '#vue',
  mixins: [windowMixin],
  data: function () {
    return {
      toggleAdvanced: false,
      nfcTagReading: false,
      lnurlLink: `${window.location.host}/boltcards/api/v1/scan/`,
      cards: [],
      hits: [],
      refunds: [],
      cardDialog: {
        show: false,
        data: {
          counter: 1,
          k0: '',
          k1: '',
          k2: '',
          uid: '',
          card_name: ''
        },
        temp: {}
      },
      cardsTable: {
        columns: [
          {
            name: 'card_name',
            align: 'left',
            label: 'Card name',
            field: 'card_name'
          },
          {
            name: 'counter',
            align: 'left',
            label: 'Counter',
            field: 'counter'
          },
          {
            name: 'wallet',
            align: 'left',
            label: 'Wallet',
            field: 'wallet'
          },
          {
            name: 'tx_limit',
            align: 'left',
            label: 'Max tx',
            field: 'tx_limit'
          },
          {
            name: 'daily_limit',
            align: 'left',
            label: 'Daily tx limit',
            field: 'daily_limit'
          }
        ],
        pagination: {
          rowsPerPage: 10
        }
      },
      refundsTable: {
        columns: [
          {
            name: 'hit_id',
            align: 'left',
            label: 'Hit ID',
            field: 'hit_id'
          },
          {
            name: 'refund_amount',
            align: 'left',
            label: 'Refund Amount',
            field: 'refund_amount'
          },
          {
            name: 'date',
            align: 'left',
            label: 'Time',
            field: 'date'
          }
        ],
        pagination: {
          rowsPerPage: 10,
          sortBy: 'date',
          descending: true
        }
      },
      hitsTable: {
        columns: [
          {
            name: 'card_name',
            align: 'left',
            label: 'Card name',
            field: 'card_name'
          },
          {
            name: 'amount',
            align: 'left',
            label: 'Amount',
            field: 'amount'
          },
          {
            name: 'old_ctr',
            align: 'left',
            label: 'Old counter',
            field: 'old_ctr'
          },
          {
            name: 'new_ctr',
            align: 'left',
            label: 'New counter',
            field: 'new_ctr'
          },
          {
            name: 'date',
            align: 'left',
            label: 'Time',
            field: 'date'
          },
          {
            name: 'ip',
            align: 'left',
            label: 'IP',
            field: 'ip'
          },
          {
            name: 'useragent',
            align: 'left',
            label: 'User agent',
            field: 'useragent'
          }
        ],
        pagination: {
          rowsPerPage: 10,
          sortBy: 'date',
          descending: true
        }
      },
      qrCodeDialog: {
        show: false,
        data: null
      }
    }
  },
  methods: {
    readNfcTag: function () {
      try {
        const self = this

        if (typeof NDEFReader == 'undefined') {
          throw {
            toString: function () {
              return 'NFC not supported on this device or browser.'
            }
          }
        }

        const ndef = new NDEFReader()

        const readerAbortController = new AbortController()
        readerAbortController.signal.onabort = event => {
          console.log('All NFC Read operations have been aborted.')
        }

        this.nfcTagReading = true
        this.$q.notify({
          message: 'Tap your NFC tag to copy its UID here.'
        })

        return ndef.scan({signal: readerAbortController.signal}).then(() => {
          ndef.onreadingerror = () => {
            self.nfcTagReading = false

            this.$q.notify({
              type: 'negative',
              message: 'There was an error reading this NFC tag.'
            })

            readerAbortController.abort()
          }

          ndef.onreading = ({message, serialNumber}) => {
            //Decode NDEF data from tag
            var self = this
            self.cardDialog.data.uid = serialNumber
              .toUpperCase()
              .replaceAll(':', '')
            this.$q.notify({
              type: 'positive',
              message: 'NFC tag read successfully.'
            })
          }
        })
      } catch (error) {
        this.nfcTagReading = false
        this.$q.notify({
          type: 'negative',
          message: error
            ? error.toString()
            : 'An unexpected error has occurred.'
        })
      }
    },
    getCards: function () {
      var self = this

      LNbits.api
        .request(
          'GET',
          '/boltcards/api/v1/cards?all_wallets=true',
          this.g.user.wallets[0].inkey
        )
        .then(function (response) {
          self.cards = response.data.map(function (obj) {
            return mapCards(obj)
          })
        })
        .then(function () {
          self.getHits()
        })
    },
    getHits: function () {
      var self = this
      LNbits.api
        .request(
          'GET',
          '/boltcards/api/v1/hits?all_wallets=true',
          this.g.user.wallets[0].inkey
        )
        .then(function (response) {
          self.hits = response.data.map(function (obj) {
            obj.card_name = self.cards.find(d => d.id == obj.card_id).card_name
            return mapCards(obj)
          })
        })
    },
    getRefunds: function () {
      var self = this
      LNbits.api
        .request(
          'GET',
          '/boltcards/api/v1/refunds?all_wallets=true',
          this.g.user.wallets[0].inkey
        )
        .then(function (response) {
          self.refunds = response.data.map(function (obj) {
            return mapCards(obj)
          })
        })
    },
    openQrCodeDialog(cardId) {
      var card = _.findWhere(this.cards, {id: cardId})
      this.qrCodeDialog.data = {
        link: window.location.origin + '/boltcards/api/v1/auth?a=' + card.otp,
        name: card.card_name,
        uid: card.uid,
        external_id: card.external_id,
        k0: card.k0,
        k1: card.k1,
        k2: card.k2,
        k3: card.k1,
        k4: card.k2
      }
      this.qrCodeDialog.show = true
    },
    addCardOpen: function () {
      this.cardDialog.show = true
      this.generateKeys()
    },
    generateKeys: function () {
      var self = this
      const genRanHex = size =>
        [...Array(size)]
          .map(() => Math.floor(Math.random() * 16).toString(16))
          .join('')

      debugcard =
        typeof this.cardDialog.data.card_name === 'string' &&
        this.cardDialog.data.card_name.search('debug') > -1

      self.cardDialog.data.k0 = debugcard
        ? '11111111111111111111111111111111'
        : genRanHex(32)

      self.cardDialog.data.k1 = debugcard
        ? '22222222222222222222222222222222'
        : genRanHex(32)

      self.cardDialog.data.k2 = debugcard
        ? '33333333333333333333333333333333'
        : genRanHex(32)
    },
    closeFormDialog: function () {
      this.cardDialog.data = {}
    },
    sendFormData: function () {
      let wallet = _.findWhere(this.g.user.wallets, {
        id: this.cardDialog.data.wallet
      })
      let data = this.cardDialog.data
      if (data.id) {
        this.updateCard(wallet, data)
      } else {
        this.createCard(wallet, data)
      }
    },
    createCard: function (wallet, data) {
      var self = this

      LNbits.api
        .request('POST', '/boltcards/api/v1/cards', wallet.adminkey, data)
        .then(function (response) {
          self.cards.push(mapCards(response.data))
          self.cardDialog.show = false
          self.cardDialog.data = {}
        })
        .catch(function (error) {
          LNbits.utils.notifyApiError(error)
        })
    },
    updateCardDialog: function (formId) {
      var card = _.findWhere(this.cards, {id: formId})
      this.cardDialog.data = _.clone(card)

      this.cardDialog.temp.k0 = this.cardDialog.data.k0
      this.cardDialog.temp.k1 = this.cardDialog.data.k1
      this.cardDialog.temp.k2 = this.cardDialog.data.k2

      this.cardDialog.show = true
    },
    updateCard: function (wallet, data) {
      var self = this

      if (
        this.cardDialog.temp.k0 != data.k0 ||
        this.cardDialog.temp.k1 != data.k1 ||
        this.cardDialog.temp.k2 != data.k2
      ) {
        data.prev_k0 = this.cardDialog.temp.k0
        data.prev_k1 = this.cardDialog.temp.k1
        data.prev_k2 = this.cardDialog.temp.k2
      }

      LNbits.api
        .request(
          'PUT',
          '/boltcards/api/v1/cards/' + data.id,
          wallet.adminkey,
          data
        )
        .then(function (response) {
          self.cards = _.reject(self.cards, function (obj) {
            return obj.id == data.id
          })
          self.cards.push(mapCards(response.data))
          self.cardDialog.show = false
          self.cardDialog.data = {}
        })
        .catch(function (error) {
          LNbits.utils.notifyApiError(error)
        })
    },
    enableCard: function (wallet, card_id, enable) {
      var self = this
      let fullWallet = _.findWhere(self.g.user.wallets, {
        id: wallet
      })
      LNbits.api
        .request(
          'GET',
          '/boltcards/api/v1/cards/enable/' + card_id + '/' + enable,
          fullWallet.adminkey
        )
        .then(function (response) {
          console.log(response.data)
          self.cards = _.reject(self.cards, function (obj) {
            return obj.id == response.data.id
          })
          self.cards.push(mapCards(response.data))
        })
        .catch(function (error) {
          LNbits.utils.notifyApiError(error)
        })
    },
    deleteCard: function (cardId) {
      let self = this
      let cards = _.findWhere(this.cards, {id: cardId})

      LNbits.utils
        .confirmDialog('Are you sure you want to delete this card')
        .onOk(function () {
          LNbits.api
            .request(
              'DELETE',
              '/boltcards/api/v1/cards/' + cardId,
              _.findWhere(self.g.user.wallets, {id: cards.wallet}).adminkey
            )
            .then(function (response) {
              self.cards = _.reject(self.cards, function (obj) {
                return obj.id == cardId
              })
            })
            .catch(function (error) {
              LNbits.utils.notifyApiError(error)
            })
        })
    },
    exportCardsCSV: function () {
      LNbits.utils.exportCSV(this.cardsTable.columns, this.cards)
    },
    exportHitsCSV: function () {
      LNbits.utils.exportCSV(this.hitsTable.columns, this.hits)
    },
    exportRefundsCSV: function () {
      LNbits.utils.exportCSV(this.refundsTable.columns, this.refunds)
    }
  },
  created: function () {
    if (this.g.user.wallets.length) {
      this.getCards()
      this.getRefunds()
    }
  }
})
