<template>
  <div>
  <div class="action-bar">
    <input
        ref="excel-upload-input"
        class="excel-upload-input"
        type="file"
        accept=".xlsx, .xls"
        @change="handleClick"
    >
    <el-button
        type="primary"
        icon="el-icon-edit"
        @click="handleAddQuestion"
    >
      添加
    </el-button>
    <el-button
        type="success"
        icon="el-icon-s-promotion"
        @click="importFromOther"
    >
      从其他挑战导入
    </el-button>
    <el-button
        type="success"
        icon="el-icon-upload2"
        @click="handleImport"
    >
      导入Excel
    </el-button>
    <el-button
        type="warning"
        icon="el-icon-download"
        :loading="downloadLoading"
        @click="handleExport"
    >
      {{exportBtnName}}
    </el-button>
    <el-button
        type="danger"
        icon="el-icon-delete-solid"
        @click="handleRemoveAll"
    >
      {{deleteBtnName}}
    </el-button>
  </div>
  <el-table
      :data="tableData"
      border
      fit
      stripe
      row-key="question"
      ref="question_table"
      highlight-current-row
      @selection-change="handleSelectionChange"
  >
    <el-table-column
        type="selection"
        :reserve-selection="true"
        width="55">
    </el-table-column>
    <el-table-column
        type="index"
        :index="computeTableIndex"
        width="50">
    </el-table-column>
    <el-table-column
        label="题目"
        prop="question"
    >
    </el-table-column>
    <el-table-column
        label="正确答案"
        prop="a1"
    >
    </el-table-column>
    <el-table-column
        label="混淆答案1"
        prop="a2"
    >
    </el-table-column>
    <el-table-column
        label="混淆答案2"
        prop="a3"
    >
    </el-table-column>
    <el-table-column
        label="混淆答案3"
        prop="a4"
    >
    </el-table-column>
    <el-table-column
        label="题目类型"
    >
      <template slot-scope="{row}">
        <span>{{ row.type === 3 ? '问卷' : '普通' }}</span>
      </template>
    </el-table-column>
    <el-table-column
        align="center"
        width="180"
        label="操作"
        fixed="right"
    >
      <template slot-scope="scope">
        <el-button
            type="primary"
            size="small"
            icon="el-icon-edit"
            v-permission="['shopexam:edit']"
            @click="handleEditQuestion(scope)"
        >
          编辑
        </el-button>
        <el-button
            type="danger"
            size="small"
            style="margin-left: 10px"
            v-permission="['shopexam:delete']"
            @click="handleDelete(scope)"
        >
          删除
        </el-button>
      </template>
    </el-table-column>
  </el-table>
  <!-- pagination -->
  <el-pagination
      :hide-on-single-page="false"
      :current-page="currentPage"
      :page-sizes="[5, 10, 20, 50, 100]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="dataCount"
      class="al-r"
      @size-change="sizeChange"
      @current-change="pageChange"
  />
    <el-dialog
        :visible.sync="dialogVisible"
        :title="dialogType==='edit'?'Edit Question':'New Question'"
    >
      <el-form
          :model="record"
          ref="modalForm"
          :rules="modalRules"
          label-width="120px"
          label-position="left"
      >
        <el-form-item label="题目" prop="question">
          <el-input
              v-model="record.question"
              placeholder="题目"
              clearable
          />
        </el-form-item>
        <el-form-item label="正确答案" prop="a1">
          <el-input
              v-model="record.a1"
              placeholder="正确答案"
              clearable
          />
        </el-form-item>
        <el-form-item label="混淆答案1" prop="a2">
          <el-input
              v-model="record.a2"
              placeholder="混淆答案1"
              clearable
          />
        </el-form-item>
        <el-form-item label="混淆答案2" prop="a3">
          <el-input
              v-model="record.a3"
              placeholder="混淆答案2"
              clearable
          />
        </el-form-item>
        <el-form-item label="混淆答案3" prop="a4">
          <el-input
              v-model="record.a4"
              placeholder="混淆答案3"
              clearable
          />
        </el-form-item>
        <el-form-item label="题目类型" prop="type">
          <el-select
              v-model="record.type"
              placeholder="选择类型"
              name="type"
              required
              class="w100"
          >
            <el-option
                label="普通"
                :value="1"
            />
            <el-option
                label="问卷"
                :value="3"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div style="text-align:right;">
        <el-button
            type="danger"
            @click="closeModal"
        >
          {{$t('permission.cancel')}}
        </el-button>
        <el-button
            type="primary"
            @click="saveModalData"
        >
          {{$t('permission.confirm')}}
        </el-button>
      </div>
    </el-dialog>

    <el-dialog
        :visible.sync="listVisible"
        title="选择活动"
    >
      <div class="action-bar">
        <el-select
            v-model="shop"
            :placeholder="'选择'+$t('main.shop')"
            name="shop"
            required
            class="w100"
            v-if="userLevel === 1"
        >
          <el-option
              v-for="item in allDepts"
              :key="item._id"
              :label="item.name"
              :value="item._id"
          />
        </el-select>
      </div>
      <el-table
          v-loading="listLoading"
          :data="shopExamList"
          border
          fit
          stripe
          highlight-current-row
          @current-change="clickChange"
          style="width: 100%;margin-top:30px;"
      >
        <el-table-column label="选择" width="55">
          <template slot-scope="scope">
            <el-radio  v-model="tableRadio" :label="scope.row"><i></i></el-radio>
          </template>
        </el-table-column>
        <el-table-column
            :label="$t('main.shop')"
            prop="shop"
            v-if="userLevel === 1"
            :formatter = "formatDept"
        >
        </el-table-column>
        <el-table-column
            min-width="200px"
            label="名称"
        >
          <template slot-scope="{row}">
            <span>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column
            min-width="200px"
            label="题目数量"
        >
          <template slot-scope="{row}">
            <span>{{ row.questions.length }}</span>
          </template>
        </el-table-column>
      </el-table>
      <div style="text-align:right;">
        <el-button
            type="danger"
            @click="closeListModal"
        >
          {{$t('permission.cancel')}}
        </el-button>
        <el-button
            type="primary"
            @click="importQuestions"
        >
          {{$t('permission.confirm')}}
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import XLSX from 'xlsx'
import { getExams, IExamData, IExamQuerstion } from '@/api/exam'
import { exportJson2Excel } from '@/utils/excel'
import { formatJson, parseTime } from '@/utils'
import { cloneDeep } from 'lodash'
import { UserModule } from '@/store/modules/user'
import { IShopData } from '@/api/types'
import { getShops } from '@/api/shop'

declare module 'vue/types/vue' {
  interface Vue {
    questions: IExamQuerstion[]
    examid?: string
  }
}

@Component({
  name: 'PuzzleList',
  props: ['questions', 'examid'],
  model: {
    prop: 'questions',
    event: 'update'
  }
})
export default class extends Vue {
  private excelData = {
    header: null,
    results: null
  }

  // pagination
  private currentPage = 1
  private pageSize = 5
  private dataCount = 0
  private tableData: IExamQuerstion[] = []
  private loading = false
  private downloadLoading = false
  private filename : string | null= ''
  private multipleSelection : IExamQuerstion[] = []
  private deleteBtnName = '删除所有'
  private exportBtnName = '导出所有'
  private dialogVisible = false
  private listVisible = false
  private dialogType = 'new'
  private record = Object.assign({}, this.defaultPuzzle())
  private shop = UserModule.department || ''
  private allDepts: IShopData[] = []
  private listLoading = false
  private shopExamList: IExamData[] = []
  private tableRadio: any = {}

  $refs!: {
    modalForm: HTMLFormElement
    'question_table': HTMLTableElement
    'excel-upload-input': HTMLFormElement
  }

  get userLevel() {
    return UserModule.level
  }

  async created() {
    if (UserModule.level === 1) {
      await this.getRemoteDeptList()
    } else if (UserModule.department) {
      this.shop = UserModule.department
    }
  }

  private modalRules = {
    question: [{ required: true, message: '请输入题目', trigger: 'blur' },
      { min: 2, max: 35, message: '长度在 2 到 35 个字符', trigger: 'blur' }],
    a1: [{ required: true, message: '请输入正确答案', trigger: 'blur' }],
    a2: [{ required: true, message: '至少输入一个错误答案', trigger: 'blur' }]
  }

  @Watch('questions')
  private initDataChange() {
    this.sliceData()
  }

  @Watch('multipleSelection')
  private selectChange() {
    this.deleteBtnName = this.multipleSelection.length > 0 ? '删除选中项' : '删除所有'
    this.exportBtnName = this.multipleSelection.length > 0 ? '导出选中项' : '导出所有'
  }

  @Watch('shop')
  private shopChange() {
    console.log(`shop change: ${this.shop}`)
    this.getList()
  }

  private defaultPuzzle() {
    return {
      _id: undefined,
      question: '',
      a1: '',
      a2: '',
      a3: '',
      a4: '',
      type: 1
    }
  }

  // begin of 题库编辑
  private handleClick(e: MouseEvent) {
    const files = (e.target as HTMLInputElement).files
    if (files) {
      const rawFile = files[0] // only use files[0]
      this.upload(rawFile)
    }
  }

  private handleAddQuestion() {
    this.dialogType = 'new'
    this.dialogVisible = true
    this.record = Object.assign({}, this.defaultPuzzle())
  }

  private handleEditQuestion(scope: any) {
    this.dialogType = 'edit'
    this.dialogVisible = true
    this.record = cloneDeep(scope.row)
  }

  private handleImport() {
    (this.$refs['excel-upload-input']).click()
  }

  private async handleRemoveAll() {
    try {
      const str = this.multipleSelection.length > 0 ? '确定删除选中的题目' : '确定删除所有题目'
      await this.$confirm(str, 'Warning', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      if (this.multipleSelection.length > 0) {
        for (const s of this.multipleSelection) {
          this.questions.splice(this.questions.indexOf(s), 1)
        }
        (this.$refs.question_table as any).clearSelection()
      } else {
        this.questions.length = 0
      }
      this.sliceData()
      this.$message({
        type: 'success',
        message: 'Deleted!'
      })
    } catch (err) {
      console.log(err)
    }
  }

  private handleExport() {
    this.handleDownload()
  }

  private async handleDelete(scope: any) {
    const { $index, row } = scope
    console.log($index, row)
    try {
      await this.$confirm('确定删除当前记录?', 'Warning', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      this.questions.splice(this.questions.indexOf(row), 1)
      this.sliceData()
      this.$message({
        type: 'success',
        message: 'Deleted!'
      })
    } catch (err) {
      console.log(err)
    }
  }

  private handleSelectionChange(val: any) {
    this.multipleSelection = val
    console.log(this.multipleSelection)
  }

  private upload(rawFile: File) {
    this.$refs['excel-upload-input'].value = '' // Fixes can't select the same excel

    this.readerData(rawFile)
  }

  private readerData(rawFile: File) {
    this.loading = true
    const reader = new FileReader()
    reader.onload = e => {
      const data = (e.target as FileReader).result
      const workbook = XLSX.read(data, { type: 'array' })
      const firstSheetName = workbook.SheetNames[0]
      const worksheet = workbook.Sheets[firstSheetName]
      const header = this.getHeaderRow(worksheet)
      const results = XLSX.utils.sheet_to_json(worksheet)
      this.generateData(header, results)
      this.loading = false
    }
    reader.readAsArrayBuffer(rawFile)
  }

  private getHeaderRow(sheet: { [key: string]: any }) {
    const headers: string[] = []
    const range = XLSX.utils.decode_range(sheet['!ref'])
    const R = range.s.r
    // start in the first row
    for (let C = range.s.c; C <= range.e.c; ++C) { // walk every column in the range
      const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
      // find the cell in the first row
      let hdr = ''
      if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
      if (hdr === '') {
        hdr = 'UNKNOWN ' + C // replace with your desired default
      }
      headers.push(hdr)
    }
    return headers
  }

  private generateData(header: any, results: any) {
    this.excelData.header = header
    this.excelData.results = results
    const questionSet = new Set()
    for (const _q of this.questions) {
      questionSet.add(_q.question)
    }
    let count = 0
    for (const _q of results) {
      if (!questionSet.has(_q.question)) {
        this.questions.push(_q)
        questionSet.add(_q.question)
        count += 1
      }
    }
    this.sliceData()
    console.log(this.excelData)
    const msg = `操作成功, 共导入${count}个题目`
    this.$message({
      type: 'success',
      message: msg
    })
  }

  // pagination
  private sizeChange(val: number) {
    this.pageSize = val
    this.sliceData()
  }

  private pageChange(val: number) {
    this.currentPage = val
    this.sliceData()
  }

  private computeTableIndex(index: number) {
    return (this.currentPage - 1) * this.pageSize + index + 1
  }

  private sliceData() {
    // 满足过滤条件 -> 分页
    const data = this.filterData()
    this.tableData = data.slice(
      (this.currentPage - 1) * this.pageSize,
      this.currentPage * this.pageSize
    )
    if (this.tableData.length === 0 && this.currentPage > 1) {
      this.currentPage -= 1
      this.sliceData()
    }
  }

  private filterData() {
    const result: IExamQuerstion[] = []
    for (const _d of this.questions) {
      result.push(_d)
    }
    this.dataCount = result.length
    return result
  }

  private valchange(val: any) {
    console.log('valchange', val)
    this.$emit('update', val)
  }

  private handleDownload() {
    this.downloadLoading = true
    const tHeader = ['question', 'a1', 'a2', 'a3', 'a4', 'type']
    const list = this.multipleSelection.length > 0 ? this.multipleSelection.slice(0) : this.questions.slice(0)
    this.filename = parseTime(new Date(), '{y}{m}{d}{h}{i}{s}')
    const data = formatJson(tHeader, list)
    console.log('begin generate excel')
    exportJson2Excel(tHeader, data, this.filename ? this.filename : undefined, undefined, undefined, true, 'xlsx')
    this.downloadLoading = false
  }

  private async importFromOther() {
    console.log('importFromOther')
    if (UserModule.level === 9 && UserModule.department) {
      await this.getList()
    }
    this.listVisible = true
  }

  private closeModal() {
    this.dialogVisible = false
    this.$refs.modalForm.clearValidate()
  }

  private closeListModal() {
    this.listVisible = false
  }

  private saveModalData() {
    const isEdit = this.dialogType === 'edit'
    this.$refs.modalForm.validate(async(valid: boolean) => {
      if (!valid) {
        this.$message.error('请按要求填写表单')
        return false
      }
      if (isEdit) {
        for (let index = 0; index < this.questions.length; index++) {
          if (this.questions[index]._id === this.record._id) {
            this.questions.splice(index, 1, Object.assign({}, this.record))
            break
          }
        }
      } else {
        this.questions.push(this.record)
      }
      this.dialogVisible = false
      this.$notify({
        title: 'Success',
        dangerouslyUseHTMLString: true,
        message: `
          题目编辑成功, 请点击保存
        `,
        type: 'success'
      })
    })
  }

  // begin of 活动选择
  private async getRemoteDeptList() {
    const { data } = await getShops({ })
    if (!data.records) return
    this.allDepts = data.records
  }

  private formatDept(row: number, column: number, cellValue: string) {
    let result = '未指定'
    for (const dep of this.allDepts) {
      if (dep._id === cellValue) {
        result = dep.name
        break
      }
    }
    return result
  }

  private async getList() {
    this.listLoading = true
    const { data } = await getExams({
      page: 1,
      limit: 20,
      key: '',
      shop: this.shop
    })
    this.listLoading = false
    const records: IExamData[] = data.records
    this.shopExamList = records.filter(o => o._id !== this.examid)
  }

  private clickChange(item: any) {
    this.tableRadio = item
    console.log(this.tableRadio)
  }

  private async importQuestions() {
    if (!(this.tableRadio?.questions?.length > 0)) {
      this.$message.error('请先选择一个有题目的活动')
      return
    }
    try {
      await this.$confirm('确定导入当前挑战活动的所有题目?', 'Warning', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      const questionSet = new Set()
      for (const _q of this.questions) {
        questionSet.add(_q.question)
      }
      let count = 0
      for (const _q of this.tableRadio.questions) {
        if (!questionSet.has(_q.question)) {
          this.questions.push(_q)
          questionSet.add(_q.question)
          count += 1
        }
      }
      this.sliceData()
      console.log(this.excelData)
      this.closeListModal()
      const msg = `操作成功, 共导入${count}个题目`
      this.$message({
        type: 'success',
        message: msg
      })
    } catch (err) {
      console.log(err)
    }
  }
}
</script>
<style lang="scss" scoped>
.action-bar {
  margin-bottom: 15px;
}

.excel-upload-input {
  display: none;
  z-index: -9999;
}
.el-form-item{
  margin-bottom: 22px;
}
</style>
