<template>
  <d2-container>
    <template #header>
      <div class="search-bar">
        <el-form :inline="true" :model="search" size="mini">
          <el-form-item :label="$t(key('consumables_category_code'))">
            <el-input v-model.trim="search.code" :placeholder="$t(key('enter_consumables_category_code'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
          </el-form-item>
          <el-form-item :label="$t(key('consumables_category_name'))">
            <el-input v-model.trim="search.name" :placeholder="$t(key('enter_consumables_category_name'))" clearable style="width:220px" @keyup.enter.native="onSearch" />
          </el-form-item>
          <el-form-item :label="$t(key('create_time'))">
            <el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
          </el-form-item>
          <el-form-item :label="$t(key('update_time'))">
            <el-date-picker v-model="search.update_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
            <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
          </el-form-item>
        </el-form>
      </div>
    </template>

    <page-table
      ref="pageTable"
      :columns="columns"
      :data="tableData"
      :loading="loading"
      :toolbar-buttons="toolbarButtons"
      :row-buttons="rowButtons"
      :pagination="pagination"
      auto-height
      @page-change="onPageChange"
      @selection-change="selectedRows = $event"
    />

    <page-dialog-form
      ref="dialogForm"
      :visible.sync="dialogVisible"
      :title="dialogTitle"
      width="520px"
      :form-cols="formCols"
      :form-data="formData"
      :rules="rules"
      label-width="130px"
      :submitting="submitting"
      :confirm-text="key('confirm')"
      :cancel-text="key('cancel')"
      @submit="onDialogSubmit"
      @close="resetForm"
    />

    <el-dialog :title="$t(key('import_title'))" :visible.sync="importVisible" width="760px" :close-on-click-modal="false">
      <el-alert :title="$t(key('import_tip'))" type="warning" :closable="false" />
      <el-upload class="import-upload" action="" :auto-upload="false" :show-file-list="true" :file-list="importFileList" accept=".xls,.xlsx" :on-change="onImportFileChange">
        <el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
        <el-button style="margin-left:10px" size="mini" type="primary" :loading="importLoading" @click.stop="downloadTemplate">{{ $t(key('download_template')) }}</el-button>
      </el-upload>
      <el-table v-loading="importTableLoading" :data="importRows" border height="320" size="mini">
        <el-table-column prop="code" :label="$t(key('consumables_category_code'))" />
        <el-table-column prop="name" :label="$t(key('consumables_category_name'))" />
        <el-table-column prop="remark" :label="$t(key('remark'))" />
      </el-table>
      <span slot="footer">
        <el-button @click="importVisible = false">{{ $t(key('cancel')) }}</el-button>
        <el-button type="primary" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
      </span>
    </el-dialog>
  </d2-container>
</template>

<script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { downloadRename, readExcel } from '@/utils/file'
import { getList, createItem, editItem, deleteItem, createExportTask, getImportTemplate, importData } from '@/api/equipment-management/consumables-category'

function readPageData (res) {
  const data = res && res.data !== undefined ? res.data : res
  if (Array.isArray(data)) return { list: data, total: data.length }
  if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
  if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
  return { list: [], total: 0 }
}

export default {
  name: 'equipment-management-consumables-category',
  components: { PageTable, PageDialogForm },
  mixins: [i18nMixin('page.equipment_management.consumables_management.consumables_category'), confirmMixin],
  data () {
    return {
      loading: false,
      submitting: false,
      tableData: [],
      selectedRows: [],
      search: { code: '', name: '', create_time: [], update_time: [] },
      pagination: { current: 1, size: 10, total: 0 },
      dialogVisible: false,
      dialogTitle: '',
      handleType: 'create',
      editId: '',
      formData: { code: '', name: '', remark: '' },
      importVisible: false,
      importFileList: [],
      importRows: [],
      importLoading: false,
      importTableLoading: false,
      columns: [],
      toolbarButtons: [],
      rowButtons: [],
      formCols: [
        [{ type: 'input', prop: 'code', label: this.key('consumables_category_code'), placeholder: this.key('enter_consumables_category_code'), style: { width: '100%' } }],
        [{ type: 'input', prop: 'name', label: this.key('consumables_category_name'), placeholder: this.key('enter_consumables_category_name'), style: { width: '100%' } }],
        [{ type: 'input', prop: 'remark', label: this.key('remark'), placeholder: this.key('enter_remark'), inputType: 'textarea', autosize: { minRows: 2, maxRows: 6 }, style: { width: '100%' } }]
      ],
      rules: {
        code: [{ required: true, message: this.key('enter_consumables_category_code'), trigger: 'blur' }, { min: 1, max: 100, message: this.key('length_1_100'), trigger: 'blur' }],
        name: [{ required: true, message: this.key('enter_consumables_category_name'), trigger: 'blur' }, { min: 1, max: 100, message: this.key('length_1_100'), trigger: 'blur' }]
      }
    }
  },
  created () {
    this.columns = useTableColumns([
      { prop: 'sort', label: this.key('sort'), width: 80 },
      { prop: 'code', label: this.key('consumables_category_code'), minWidth: 160 },
      { prop: 'name', label: this.key('consumables_category_name'), minWidth: 160 },
      { prop: 'remark', label: this.key('remark'), minWidth: 160, showOverflowTooltip: true },
      { prop: 'create_time', label: this.key('create_time'), minWidth: 160 },
      { prop: 'update_time', label: this.key('update_time'), minWidth: 160 },
      { prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
    ])
    const btns = useTableButtons({
      toolbar: [
        { key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_category/create', onClick: this.openAdd },
        { key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_category/batch-delete', needSelection: true, disabledTip: this.key('please_select_data'), onClick: this.handleBatchDelete },
        { key: 'import', label: this.key('import'), icon: 'el-icon-upload2', type: 'success', auth: '/device_management/device_consumables/device_consumables_category/import', onClick: this.openImport },
        { key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/device_management/device_consumables/device_consumables_category/export', onClick: this.handleExport }
      ],
      row: [
        { key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_category/edit', onClick: this.openEdit },
        { key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_category/delete', onClick: this.handleDelete }
      ]
    }, this.$permission)
    this.toolbarButtons = btns.toolbarButtons
    this.rowButtons = btns.rowButtons
    this.fetchData()
  },
  methods: {
    buildSearchParams () {
      const params = { ...this.search }
      if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
      if (!Array.isArray(params.update_time) || !params.update_time.length) delete params.update_time
      return params
    },
    async fetchData () {
      this.loading = true
      try {
        const res = await getList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size })
        const page = readPageData(res)
        this.tableData = page.list
        this.pagination.total = page.total
      } finally {
        this.loading = false
      }
    },
    onSearch () { this.pagination.current = 1; this.fetchData() },
    onReset () { this.search = { code: '', name: '', create_time: [], update_time: [] }; this.pagination.current = 1; this.fetchData() },
    onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
    resetForm () { this.formData = { code: '', name: '', remark: '' }; this.editId = '' },
    openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_title'); this.resetForm(); this.dialogVisible = true },
    openEdit (row) { this.handleType = 'edit'; this.dialogTitle = this.key('edit_title'); this.editId = row.id; this.formData = { code: row.code || '', name: row.name || '', remark: row.remark || '' }; this.dialogVisible = true },
    async onDialogSubmit () {
      this.submitting = true
      try {
        if (this.handleType === 'create') await createItem(this.formData)
        else await editItem({ ...this.formData, id: this.editId })
        this.$message.success(this.$t(this.key('operation_success')))
        this.dialogVisible = false
        this.fetchData()
      } finally {
        this.submitting = false
      }
    },
    async handleDelete (row) {
      const cancelled = await this.$confirmAction({ message: this.key('confirm_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: [row.id] }))
      if (cancelled) return
      this.$message.success(this.$t(this.key('operation_success')))
      this.fetchData()
    },
    async handleBatchDelete () {
      if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_data'))); return }
      const cancelled = await this.$confirmAction({ message: this.key('confirm_batch_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteItem({ id: this.selectedRows.map(item => item.id) }))
      if (cancelled) return
      this.$message.success(this.$t(this.key('operation_success')))
      this.fetchData()
    },
    async handleExport () {
      const cancelled = await this.$confirmAction({ message: this.key('confirm_export'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => createExportTask({ ...this.buildSearchParams(), action: 'download' }))
      if (cancelled) return
      this.$message.success(this.$t(this.key('create_download_task_success')))
    },
    openImport () { this.importFileList = []; this.importRows = []; this.importVisible = true },
    async downloadTemplate () { this.importLoading = true; try { const res = await getImportTemplate({}); downloadRename(res, 'xlsx', this.$t(this.key('import_template_name'))) } finally { this.importLoading = false } },
    async onImportFileChange (file) {
      if (!file || !/\.(xls|xlsx)$/i.test(file.name)) { this.$message.error(this.$t(this.key('file_format_error'))); return }
      this.importFileList = [file]
      this.importTableLoading = true
      try {
        const rows = await readExcel(file.raw)
        const required = [this.$t(this.key('consumables_category_code')), this.$t(this.key('consumables_category_name')), this.$t(this.key('remark'))]
        if (rows.length && required.some(title => !Object.prototype.hasOwnProperty.call(rows[0], title))) {
          this.$message.error(this.$t(this.key('file_column_missing'), { title: required.find(title => !Object.prototype.hasOwnProperty.call(rows[0], title)) }))
          this.importRows = []
          return
        }
        this.importRows = rows.map(row => ({ code: row[required[0]], name: row[required[1]], remark: row[required[2]] }))
      } finally {
        this.importTableLoading = false
      }
    },
    async submitImport () {
      if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_data'))); return }
      await importData({ import_data: JSON.stringify(this.importRows) })
      this.$message.success(this.$t(this.key('operation_success')))
      this.importVisible = false
      this.fetchData()
    }
  }
}
</script>

<style scoped>
.search-bar { padding: 10px 0; }
.import-upload { margin: 12px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>
