<template>
  <v-form lazy-validation>
    <v-alert v-model="deck.count !== 50" type="warning">
      {{ deck.count }} cards detected! (Decks should have 50)
    </v-alert>
    <v-alert v-model="deck.maximum > 3" type="warning">
      Card with {{ deck.maximum }} copies detected! (Cards should not have more than 3 copies)
    </v-alert>

    <v-textarea
      ref="textarea"
      label="Edit Deck"
      :value="deck_list"
      rows="35"
      hint="Change card counts and/or serial numbers. Names will be updated automatically."
      style="font-family: monospace"
    >
    </v-textarea>

    <v-spacer></v-spacer>
    <v-btn color="success" @click.native="check">
      Check Deck
    </v-btn>
  </v-form>
</template>

<script>
export default {
  name: 'DeckEditor',

  props: {
    deck_list: String
  },

  data: () => ({
    deck: {
      count: 50,
      maximum: 0
    }
  }),

  methods: {
    parse_deck(deck_string) {
      let retval = {
        name: '',
        note: '',
        cards: [],
        count: 0
      }

      // select all lines containing card serial numbers
      let cardLinesRE = /^.*\b\d-\d{3}[A-Z]?\b.*$/gm
      let cardLines = deck_string.match(cardLinesRE)
      let cardCounts = {}

      cardLines.forEach(cardLine => {
        // extract serial (guaranteed to be in here!)
        let serialRE = /\b(\d-\d{3})[A-Z]?\b/i
        let serial = serialRE.exec(cardLine)[1]

        // strip out serial number
        cardLine = cardLine.replace(serialRE, '')

        let countREs = [
          // prioritize a count with "times" symbol *, x, ×
          /\b([0-9]+)(?:[*×]|[x]\b)/,
          /(?:[*×]|\b[x])([0-9]+)\b/,
          // next priority: count with whitespace
          /\s+([0-9]+)\s+/,
          /\s+([0-9]+)\b/,
          /\b([0-9]+)\s+/,
          // least priority: any simple number
          /\b([0-9]+)\b/
        ]

        // fallback value
        let count = 1
        for (let i = 0; i < countREs.length; i++) {
          let data = countREs[i].exec(cardLine)

          if (data) {
            count = Number(data[1])
            break
          }
        }

        // count copies
        if (!cardCounts[serial]) {
          cardCounts[serial] = 0
        }
        cardCounts[serial] += count

        retval.count += count
      })

      // push card data into deck
      Object.keys(cardCounts).forEach(serial => {
        retval.cards.push({
          serial: serial,
          count: cardCounts[serial]
        })
      })

      // strip out lines with serial numbers
      deck_string = deck_string.replace(cardLinesRE, '')

      // select the line containing 'deck name:'
      // and its successor (ffdecks format)
      let metaRE = /^Deck Name: (.+)$[\s]*?^(.+)$/m
      let metaData = metaRE.exec(deck_string)

      // fallback
      retval.name = 'Unnamed Deck'
      retval.note = ''

      if (!metaData) {
        // no ffdecks format found: strip out anything after the first empty line
        deck_string = deck_string.replace(/^[\s]*$[^]*/m, '')

        // use lax format: <anything>:[deck name][newline][note]
        metaRE = /[^]*?:(.+)$[\s]*?^([^]*)/m
        metaData = metaRE.exec(deck_string)
      }

      // look again, I am not an else!
      if (metaData) {
        // extract matches
        retval.name = metaData[1].trim()
        retval.note = metaData[2].trim()
      }

      return retval
    },

    check() {
      let new_deck = this.parse_deck(this.$refs.textarea.lazyValue)

      // count number of cards
      this.deck.count = new_deck.count

      // find most frequent card
      this.deck.maximum = 0
      new_deck.cards.forEach(card => {
        if(card.count > this.deck.maximum)
          this.deck.maximum = card.count
      })
    }
  }
}
</script>
