<template>
  <base-modal
    :show-modal="showModal"
    max-width="800px"
    @close-modal="closeModal">

    <template slot="title">
      <span v-if="currentSubmission">Resubmit batch of samples</span>
      <span v-else>Submit a New Batch of Samples?</span>
    </template>

    <template slot="header-actions">
      <v-tooltip top>
        <v-icon
          slot="activator"
          small
          flat
          class="primary--text"
          @click="downloadForm">
          file_download
        </v-icon>
        <span>Download latest version of form for Sample Submission.</span>
      </v-tooltip>
    </template>

    <template slot="content">
      <v-container grid-list-md>
        <v-layout wrap>

          <v-flex xs12>
            <project-search-input
              ref="projects"
              v-model="project"
              :rules="[rules.required]"
              label="Projects"
              hint="Projects that will contain these samples"/>
          </v-flex>

          <v-flex xs12>
            <v-text-field
              ref="description"
              v-model="submission.description"
              :rules="[rules.required]"
              label="Description"
              hint="This is for our future selfs."/>
          </v-flex>

          <v-flex xs12>
            <tag-search-input
              ref="tags"
              v-model="submission.tags"
              label="Tags"
              hint="Add existing or new keywords which are helpful when searching"/>
          </v-flex>

          <v-flex xs12>
            <upload-file
              ref="file"
              :disabled="!canUpload"
              :status="submissionStatus"
              :loading="loading"
              @upload-file="uploadFile"
              @reset-status="submissionStatus = {}"/>
          </v-flex>

        </v-layout>
      </v-container>
    </template>

    <template slot="footer-actions">
      <v-tooltip
        :disabled="canCommit"
        top>
        <v-btn
          slot="activator"
          :disabled="!canCommit"
          color="primary darken-1"
          flat="flat"
          @click="commitForm">
          Commit Submission
        </v-btn>
        To commit this form, it needs to be free of errors!
      </v-tooltip>
    </template>

  </base-modal>
</template>

<script>
import { mapGetters } from 'vuex'
import BaseModal from '@/components/base/BaseModal'
import ProjectSearchInput from '@/components/projects/ProjectSearchInput'
import TagSearchInput from '@/components/tags/TagSearchInput'
import UploadFile from '@/components/submissions/UploadFile'

import rules from '@/utils/rules'
import { SHOW_ALERT } from '@/store/actions/alert'
import {
  createRecord,
  downloadSubmissionForm,
  processSubmissionForm,
  uploadSubmissionForm,
  deleteSubmission
} from '@/utils/api'

export default {
  name: 'NewSubmissionModal',
  components: {
    BaseModal,
    ProjectSearchInput,
    TagSearchInput,
    UploadFile
  },
  props: {
    showModal: {
      type: Boolean,
      default: false,
      required: true
    }
  },
  data () {
    return {
      loading: false,
      fieldsToValidate: [
        'description',
        'projects'
      ],
      files: [],
      formHasErrors: false,
      users: [],
      usersQuery: '',
      refs: {},
      rules,
      submission: {
        projects: [],
        description: ''
      },
      project: {},
      submissionId: null,
      submissionStatus: {}
    }
  },
  computed: {
    canCommit () {
      return this.submissionStatus &&
        'errors' in this.submissionStatus &&
        !this.submissionStatus.errors.length
    },
    canUpload () {
      return !!(this.submission &&
        this.submission.projects &&
        this.submission.projects.length &&
        this.submission.description
      )
    },
    ...mapGetters([
      'currentProject',
      'currentSubmission'
    ])
  },
  watch: {
    project: {
      immediate: true,
      handler (value) {
        const projectId = this.$get(value, 'pk')
        this.submission.projects = projectId ? [projectId] : []
      }
    },
    currentProject: {
      immediate: true,
      handler (newValue, oldValue) {
        if (newValue !== oldValue) {
          this.project = { ...newValue }
        }
      }
    },
    showModal: {
      immediate: true,
      handler (value) {
        if (value) {
          this.project = { ...this.currentProject }
          this.submission = { ...this.currentSubmission }
        }
      }
    }
  },
  mounted () {
    // Map all local and nested inputs to local 'refs'
    this.refs = {}
    this.refs['description'] = this.$refs['description']
    this.refs['projects'] = this.$refs['projects'].$refs.projectSearchInput
    this.refs['tags'] = this.$refs['tags'].$refs.tagSearchInput
  },
  methods: {
    closeModal () {
      this.resetForm()
      this.deleteUncommitedSubmission()
      this.$emit('close-modal')
    },
    resetForm () {
      Object.keys(this.refs).forEach(field => {
        this.refs[field].reset()
      })
      this.$refs.file.files = []
      this.submissionStatus = {}
      this.formHasErrors = false
    },
    downloadForm () {
      window.location.assign(downloadSubmissionForm())
    },
    async createSubmission () {
      this.formHasErrors = false
      this.fieldsToValidate.forEach(field => {
        if (!this.submission[field]) {
          this.formHasErrors = true
        }
        this.refs[field].validate(true)
      })
      if (!this.formHasErrors) {
        const response = await createRecord('submissions', this.submission)
        this.submissionId = this.$get(response, 'pk', '')
      }
    },
    async uploadFile (file) {
      this.loading = true
      if (!this.submissionId) {
        await this.createSubmission()
      }
      if (this.submissionId) {
        const form = new FormData()
        form.append('submission_form', file, file.name)
        let response = await uploadSubmissionForm(this.submissionId, form)
        response = await processSubmissionForm(this.submissionId, {
          commit: false
        })
        this.submissionStatus = response.data
      }
      this.loading = false
    },
    async commitForm () {
      let response = await processSubmissionForm(this.submissionId, {
        commit: true
      })
      if (response.data && response.data.summary) {
        this.$store.dispatch(SHOW_ALERT, {
          message: `${response.data.summary}: created successfully!`
        })
      }
      this.$emit('close-modal')
    },
    async deleteUncommitedSubmission () {
      if (this.submissionId && !this.$get(this.submission, 'processed', '')) {
        await deleteSubmission(this.submissionId)
        this.submissionId = null
      }
    }
  }
}
</script>
