<template>
  <div class="container">
    <app-form @submit="calculate" ref="calculateForm" :validator="$v">
      <div class="row">
        <div class="col-md-5">
          <label class="mandatory">Sequence</label>
          <input type="text" class="form-control" v-model="$v.sequence.$model" required />
          <br />
        </div>
        <div class="col-md-3">
          <label class="mandatory">Target G4 hunter score</label>
          <input type="number" class="form-control" step="0.1" min="0" max="2" required v-model="$v.threshold.$model" />
          <br />
        </div>
        <div class="col-md-4">
          <label>On complementary sequence</label>
          <b-form-checkbox class="form-control switch" name="check-button" v-model="onComplementary" switch>
            <b>(Complementary: {{ onComplementary ? 'On' : 'Off' }})</b>
          </b-form-checkbox>
          <br />
        </div>
      </div>
      <div class="alert alert-danger" v-if="$v.$anyError">
        <div v-if="!$v.sequence.required">Sequence is required.</div>
        <div v-if="!$v.sequence.maxLength">Sequence max length is {{ $v.sequence.$params.maxLength.max }}.</div>
        <div v-if="!$v.threshold.required">Threshold is required.</div>
        <div v-if="!$v.threshold.decimal">
          Threshold must be decimal number.
        </div>
        <div v-if="$v.threshold.$model <= 1.2">
          The probability of G-quadruplex formation with G4Hunter score below 1.2 is low.
        </div>
        <div v-if="!$v.threshold.maxValue">Maximal value of threshold is {{ $v.threshold.$params.maxValue.max }}.</div>
      </div>
      <div class="alert alert-danger" v-if="analyse">Analyse failed: {{ analyse.errors[0].defaultMessage }}</div>
      <button type="submit" class="btn btn-primary">Calculate</button>
    </app-form>

    <hr />

    <div v-if="result">
      <h2>Result</h2>
      <table class="table table-striped">
        <tbody>
          <tr>
            <th class="text-left">Original sequence</th>
            <th class="text-left">Score</th>
            <th class="text-center"></th>
          </tr>
          <tr>
            <td class="sequence text-left text-bold">
              <Highlight :sequence="result.originSequence" />
            </td>
            <td class="text-left">{{ result.originScore | number }}</td>
            <td class="text-center"></td>
          </tr>
          <template v-if="result.mutationSequences">
            <tr>
              <th class="text-left" v-if="result.mutationSequences.length == 1">
                A mutated sequence
              </th>
              <th class="text-left" v-else>List of mutated sequences</th>
              <th class="text-left">Score</th>
              <th class="text-center">Details</th>
            </tr>
          </template>
          <template v-for="mutationSequence in result.mutationSequences">
            <tr>
              <td class="sequence text-monospace text-bold">
                <Highlight :sequence="mutationSequence.sequence" :mask="mutationSequence.origin">
                </Highlight>
              </td>
              <td class="text-left">{{ result.mutationScore | number }}</td>
              <td class="text-center">
                <b-button
                  variant="primary"
                  v-if="!mutationSequence.showDetail"
                  @click="toggleShowDetail(mutationSequence)"
                >
                  Show detail
                </b-button>
                <b-button
                  variant="primary"
                  v-if="mutationSequence.showDetail"
                  @click="toggleShowDetail(mutationSequence)"
                >
                  Hide detail
                </b-button>
              </td>
            </tr>
            <tr v-if="mutationSequence.showDetail">
              <td class="text-center" colspan="3">
                <G4KillerDetail :sequence="result.originSequence" :mutation="mutationSequence"> </G4KillerDetail>
              </td>
            </tr>
          </template>
        </tbody>
      </table>
      <div class="alert alert-warning" v-if="result && !result.mutationSequences">
        The target score {{ threshold }} is below the G4Hunter score of the sequence.
        <b>No mutation is needed!</b>
      </div>
      <hr />
    </div>
    <div class="card bg-light">
      <div class="card-body">
        Please insert your nucleic acid sequence and choose desired G4 hunter score.
      </div>
    </div>
  </div>
</template>

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

export default {
  components: {
    Highlight,
    G4KillerDetail,
    AppForm,
  },
  data() {
    return {
      sequence: '',
      threshold: 1.0,
      result: null,
      differences: '',
      onComplementary: false,
      analyse: null,
    }
  },
  validations: {
    sequence: {
      required,
      maxLength: maxLength(100),
    },
    threshold: {
      required,
      decimal,
      minValue: minValue(0),
      maxValue: maxValue(2),
    },
  },
  methods: {
    calculate() {
      this.result = null
      this.differences = []

      this.$http
        .post('/analyse/g4killer', {
          sequence: this.sequence,
          threshold: this.threshold,
          onComplementary: this.onComplementary,
        })
        .then(response => {
          this.result = response.data
          this.analyse = null

          this.result.mutationSequences = response.data.mutationSequences.map(ms => ({
            origin: ms,
            sequence: this.replaceMutationSequence(ms),
            showDetail: false,
          }))
        })
        .catch(error => {
          if (error.response) {
            this.analyse = error.response.data
          }
        })
        .finally(() => {
          this.$refs.calculateForm.enable()
        })
    },
    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
    },
  },
  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.onComplementary = this.$route.query.onComplementary
      this.calculate()
    }
  },
  filters: {
    number: Formatters.number,
    difference: function(mutationSequence) {
      return mutationSequence.origin.replace(/W/g, '-').replace(/\w/g, '|')
    },
  },
}
</script>

<style scoped>
.sequence {
  max-width: 400px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.switch {
  border: 0;
}
</style>