<template>
  <div class="container">
    <!-- G4killer multiple form -->
    <app-form @submit="calculate" ref="calculateForm" :validator="$v">
      <label class="mandatory">Sequences</label>
      <!--Inputs -->
      <textarea class="form-control" v-model="sequences" rows="10"></textarea>
      <br />
      <div class="alert alert-danger" v-if="$v.$anyError">
        <!--Allert messages -->
        <div v-if="!$v.sequences.required">Sequence is required.</div>
        <div v-if="!$v.sequences.numLines">The limit is {{ $v.sequences.$params.numLines.amount }} rows.</div>
      </div>
      <label class="mandatory">Target G4 hunter score</label>
      <div class="row">
        <div class="col-md-3">
          <input
            type="number"
            class="form-control"
            step="0.1"
            min="1.2"
            max="2"
            required
            v-model="$v.threshold.$model"
          />
        </div>
        <div class="col-md-2">
          <button type="submit" class="btn btn-primary">Calculate</button>
        </div>
      </div>
    </app-form>
    <hr />

    <!-- Results -->
    <div v-if="results">
      <h2>Results</h2>
      <br />
      <table v-for="result in results" class="table table-striped">
        <tbody>
          <!-- Result table header -->
          <tr>
            <th class="text-center">Original sequence</th>
            <th class="text-center">Score</th>
            <th class="text-center">Show mutations</th>
          </tr>
          <!-- Result table content -->
          <tr>
            <td class="sequence text-center text-bold">
              <Highlight :sequence="result.originSequence"></Highlight>
            </td>
            <td class="text-center">{{ result.originScore | number }}</td>
            <td class="text-center">
              <!-- Button show mutation results -->
              <b-button variant="primary" v-if="!result.showMutated" @click="toggleShowMutations(result)"
                >Show</b-button
              >
              <b-button variant="primary" v-if="result.showMutated" @click="toggleShowMutations(result)">Hide</b-button>
            </td>
          </tr>
          <!-- Mutated sequences header -->
          <tr v-if="result.showMutated">
            <th class="text-center">Mutated sequence</th>
            <th class="text-center">Score</th>
            <th class="text-center">Details</th>
          </tr>
          <!-- Mutated sequences content -->
          <template v-for="mutationSequence in result.mutationSequences">
            <tr v-if="result.showMutated">
              <td class="sequence text-center text-bold">
                <Highlight :sequence="mutationSequence.sequence"></Highlight>
              </td>
              <td class="text-center">{{ result.mutationScore | number }}</td>
              <td class="text-center">
                <b-button
                  variant="primary"
                  v-if="!mutationSequence.showDetail"
                  @click="toggleShowDetail(mutationSequence)"
                  >Show</b-button
                >
                <b-button
                  variant="primary"
                  v-if="mutationSequence.showDetail"
                  @click="toggleShowDetail(mutationSequence)"
                  >Hide</b-button
                >
              </td>
            </tr>
            <!-- Mutated sequences detail content -->
            <tr v-if="mutationSequence.showDetail">
              <td colspan="3">
                <pre>
                    {{ mutationSequence.origin }}
                    {{ mutationSequence | difference }}
                    {{ mutationSequence.sequence }}
                </pre>
              </td>
            </tr>
          </template>
        </tbody>
      </table>
    </div>
  </div>
</template>

<script>
import Highlight from '@/components/core/visualisation/highlight'
import Formatters from '@/formatters'
import AppForm from '@/components/core/app-form'
import { required, minValue, maxValue, decimal, helpers } from 'vuelidate/lib/validators'

const numLines = lines => {
  return helpers.withParams({ type: 'numLines', amount: lines }, s => {
    return (
      s.split('\n').filter(r => {
        return r.trim() != ''
      }).length <= lines
    )
  })
}

export default {
  data() {
    return {
      sequences: '',
      threshold: 1.4,
      showRes: false,
      results: null,
      differences: '',
    }
  },
  validations: {
    sequences: {
      required,
      numLines: numLines(20),
    },
    threshold: {
      required,
      decimal,
      minValue: minValue(1.2),
      maxValue: maxValue(2),
    },
  },
  components: {
    Highlight,
    AppForm,
  },
  filters: {
    number: Formatters.number,
    difference: function(mutationSequence) {
      return mutationSequence.origin.replace(/W/g, '-').replace(/\w/g, '|')
    },
  },
  methods: {
    calculate() {
      this.results = []
      this.differences = []

      let promises = []

      this.sequences.split('\n').forEach(item => {
        item = item.trim()

        if (item.length > 0) {
          let p = this.$http
            .post('/analyse/g4killer', {
              sequence: item,
              threshold: this.threshold,
            })
            .then(
              resp => {
                let sequence = resp.data
                console.log(sequence)
                sequence.showMutated = false
                sequence.mutationSequences = resp.data.mutationSequences.map(ms => ({
                  origin: ms,
                  sequence: this.replaceMutationSequence(ms),
                  showDetail: false,
                }))
                this.results.push(sequence)
              },
              () => {
                //TODO
              }
            )
          promises.push(p)
        }
      })
      Promise.all(promises).finally(() => {
        this.$refs.calculateForm.enable()
        this.showRes = true
      })
    },
    replaceMutationSequence(mutationSequence) {
      const replacement = ['A', 'T']
      return mutationSequence.replace(/W/g, () => {
        return replacement[Math.floor(Math.random() * replacement.length)]
      })
    },
    toggleShowDetail(mutationSequence) {
      mutationSequence.showDetail = !mutationSequence.showDetail
    },
    toggleShowMutations(sequence) {
      sequence.showMutated = !sequence.showMutated
    },
  },
  mounted() {
    if (this.$route.query.threshold) {
      this.threshold = parseFloat(this.$route.query.threshold)
    }
    if (this.$route.query.sequence) {
      this.sequence = this.$route.query.sequence
      this.calculate()
    }
  },
}
</script>

<style scoped>
textarea {
  font-family: monospace;
}
</style>