<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    :append-to-body="true"
    :close-on-click-modal="false"
    :before-close="handleClose"
    width="80%"
  >
    <div class="result-param-content">
      <div class="search-content-card">
        <el-card class="box-card" :style="{ height: boxcardHeight }">
          <div slot="header" class="clearfix">
            <span>{{ $t(key('search')) }}</span>
            <el-button style="float:right;padding:3px 0" type="text" @click="onSearch">
              {{ $t(key('query')) }}
            </el-button>
          </div>
          <el-form label-position="top" :model="searchForm" size="mini">
            <el-form-item :label="$t(key('name'))">
              <el-input
                v-model.trim="searchForm.name"
                :placeholder="$t(key('enter_name'))"
                clearable
                @keyup.enter.native="onSearch"
              />
            </el-form-item>
            <el-form-item :label="$t(key('param'))">
              <el-input
                v-model.trim="searchForm.code"
                :placeholder="$t(key('enter_param'))"
                clearable
                @keyup.enter.native="onSearch"
              />
            </el-form-item>
          </el-form>
        </el-card>
      </div>
      <div class="search-content-table">
        <el-table
          ref="table"
          v-loading="loading"
          :data="tableData"
          border
          height="550"
          style="width:100%"
        >
          <el-table-column :label="$t(key('name'))" prop="name" width="280" show-overflow-tooltip />
          <el-table-column :label="$t(key('param'))" prop="code" width="200" show-overflow-tooltip />
          <el-table-column :label="$t(key('category'))" prop="field_type" show-overflow-tooltip />
          <el-table-column :label="$t(key('remark'))" prop="remark" show-overflow-tooltip />
          <el-table-column width="120" align="center">
            <template slot="header">
              <el-tooltip effect="dark" :content="$t(key('multi_step_not_unique'))" placement="bottom">
                <i class="el-icon-question" />
              </el-tooltip>
              <span>{{ $t(key('is_unique')) }}</span>
            </template>
            <template slot-scope="{ row }">
              <span v-if="Number(row.is_only) === 1">{{ $t(key('yes')) }}</span>
              <span v-else>{{ $t(key('no')) }}</span>
            </template>
          </el-table-column>
          <el-table-column width="120" align="center">
            <template slot="header">
              <el-tooltip effect="dark" :content="$t(key('need_device_upload'))" placement="bottom">
                <i class="el-icon-question" />
              </el-tooltip>
              <span>{{ $t(key('is_upload')) }}</span>
            </template>
            <template slot-scope="{ row }">
              <span v-if="Number(row.is_upload) === 1">{{ $t(key('yes')) }}</span>
              <span v-else>{{ $t(key('no')) }}</span>
            </template>
          </el-table-column>
          <el-table-column :label="$t(key('operation'))" width="110" fixed="right" align="center">
            <template slot-scope="{ row }">
              <el-button type="text" icon="el-icon-edit" @click="handleEdit(row)" />
              <el-button type="text" icon="el-icon-delete" style="color:#F56C6C" @click="handleDelete(row)" />
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>

    <el-pagination
      :current-page="pagination.current"
      :page-sizes="[10, 20, 50, 100]"
      :page-size="pagination.size"
      :total="pagination.total"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />

    <div slot="footer" class="dialog-footer">
      <el-button type="primary" size="mini" @click="handleAdd">{{ $t(key('add_row')) }}</el-button>
      <el-button type="success" size="mini" icon="el-icon-download" @click="handleImport">{{ $t(key('import')) }}</el-button>
      <el-button size="mini" @click="handleClose">{{ $t(key('close')) }}</el-button>
    </div>

    <el-dialog
      :title="$t(dialogTitle)"
      :visible.sync="innerVisible"
      append-to-body
      width="800px"
      :before-close="handleInnerClose"
    >
      <el-form ref="form" :model="formData" :rules="rules" label-width="100px" size="mini">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item :label="$t(key('param'))" prop="code">
              <el-input v-model="formData.code" :placeholder="$t(key('enter_param'))" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="$t(key('name'))" prop="name">
              <el-input v-model="formData.name" :placeholder="$t(key('enter_name'))" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="$t(key('category'))" prop="field_type">
              <el-select v-model="formData.field_type" :placeholder="$t(key('select_type'))" style="width:100%">
                <el-option label="FLOAT" value="FLOAT" />
                <el-option label="INT" value="INT" />
                <el-option label="VARCHAR" value="VARCHAR" />
                <el-option label="TEXT" value="TEXT" />
                <el-option label="TIMESTAMP" value="TIMESTAMP" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="$t(key('remark'))">
              <el-input v-model="formData.remark" :placeholder="$t(key('remark_required'))" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="$t(key('is_unique'))">
              <el-radio-group v-model="formData.is_only">
                <el-radio :label="1">{{ $t(key('yes')) }}</el-radio>
                <el-radio :label="0">{{ $t(key('no')) }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="$t(key('is_upload'))">
              <el-radio-group v-model="formData.is_upload">
                <el-radio :label="1">{{ $t(key('yes')) }}</el-radio>
                <el-radio :label="0">{{ $t(key('no')) }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer">
        <el-button @click="handleInnerClose">{{ $t(key('cancel')) }}</el-button>
        <el-button type="primary" @click="handleSubmit">{{ $t(key('confirm')) }}</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :title="$t(key('preset_result_param_import'))"
      :visible.sync="importVisible"
      append-to-body
      width="75%"
      :close-on-click-modal="false"
      :before-close="handleImportClose"
    >
      <el-alert
        :title="$t(key('file_suffix_rule'))"
        :closable="false"
        type="warning"
        show-icon
      />
      <el-form label-width="90px" class="import-form">
        <el-form-item :label="$t(key('import_table'))">
          <el-upload
            action=""
            :multiple="false"
            :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="downloadImportLoading"
              @click.stop="downloadTemplate"
            >
              {{ $t(key('download_template')) }}
            </el-button>
          </el-upload>
        </el-form-item>
        <el-form-item :label="$t(key('preview'))">
          <el-table
            v-loading="importTableLoading"
            :data="importRows"
            border
            height="360"
            style="width:100%"
          >
            <el-table-column prop="name" :label="$t(key('name'))" min-width="140" show-overflow-tooltip />
            <el-table-column prop="code" :label="$t(key('param'))" min-width="140" show-overflow-tooltip />
            <el-table-column prop="field_type" :label="$t(key('category'))" min-width="120" />
            <el-table-column prop="remark" :label="$t(key('remark'))" min-width="160" show-overflow-tooltip />
            <el-table-column prop="is_only" :label="$t(key('is_unique'))" width="110" />
            <el-table-column prop="is_upload" :label="$t(key('is_upload'))" width="110" />
          </el-table>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="handleImportClose">{{ $t(key('cancel')) }}</el-button>
        <el-button type="primary" :loading="importSubmitting" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
      </div>
    </el-dialog>
  </el-dialog>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import {
  getOptionalParamsList,
  createOptionalParams,
  editOptionalParams,
  deleteOptionalParams,
  getImportTemplate,
  importDataCreate
} from '@/api/production-master-data/optional-params'
import { downloadRename, readExcel } from '@/utils/file'

export default {
  name: 'ProcessStepResultParam',
  components: {},
  mixins: [i18nMixin('page.production_master_data.process_model.process_step')],
  props: {
    title: {
      type: String,
      default: ''
    },
    visible: {
      type: Boolean,
      default: false
    },
    workingsubclass_id: {
      type: [String, Number],
      default: ''
    }
  },
  data () {
    return {
      loading: false,
      tableData: [],
      searchForm: { name: '', code: '' },
      pagination: { current: 1, size: 10, total: 0 },
      boxcardHeight: '550px',
      innerVisible: false,
      dialogTitle: '',
      importVisible: false,
      downloadImportLoading: false,
      importFileList: [],
      importTableLoading: false,
      importSubmitting: false,
      importRows: [],
      formData: {
        id: '',
        code: '',
        name: '',
        field_type: '',
        remark: '',
        is_only: 0,
        is_upload: 0
      },
      rules: {
        code: [{ required: true, message: this.key('enter_param'), trigger: 'blur' }],
        name: [{ required: true, message: this.key('enter_name'), trigger: 'blur' }],
        field_type: [{ required: true, message: this.key('select_type'), trigger: 'change' }]
      }
    }
  },
  watch: {
    workingsubclass_id: {
      handler (val) {
        if (val) {
          this.fetchData()
        }
      },
      immediate: true
    }
  },
  methods: {
    handleClose () {
      this.$emit('close')
    },
    handleInnerClose () {
      this.innerVisible = false
      this.$refs.form && this.$refs.form.resetFields()
    },
    normalizeResponse (res) {
      const getTotal = (source, fallback) => {
        if (!source) return fallback
        const total = source.count ?? source.total ?? source.total_count ?? source.record_count
        const value = Number(total)
        return Number.isNaN(value) ? fallback : value
      }
      const containers = [res, res && res.data, res && res.data && res.data.data].filter(Boolean)
      for (const item of containers) {
        if (Array.isArray(item)) {
          return { list: item, total: getTotal(res, item.length) }
        }
        const list = item.data || item.list || item.rows || item.records || item.items
        if (Array.isArray(list)) {
          return { list, total: getTotal(item, getTotal(res, list.length)) }
        }
      }
      return { list: [], total: 0 }
    },
    onSearch () {
      this.pagination.current = 1
      this.fetchData()
    },
    fetchData () {
      if (!this.workingsubclass_id) return
      this.loading = true
      getOptionalParamsList({
        workingsubclass_id: this.workingsubclass_id,
        page_no: this.pagination.current,
        page_size: this.pagination.size,
        ...this.searchForm
      }).then(res => {
        const data = this.normalizeResponse(res)
        this.tableData = data.list
        this.pagination.total = data.total
      }).finally(() => {
        this.loading = false
      })
    },
    handleSizeChange (size) {
      this.pagination.size = size
      this.pagination.current = 1
      this.fetchData()
    },
    handleCurrentChange (current) {
      this.pagination.current = current
      this.fetchData()
    },
    handleAdd () {
      this.dialogTitle = this.key('add_row')
      this.formData = {
        id: '',
        code: '',
        name: '',
        field_type: '',
        remark: '',
        is_only: 0,
        is_upload: 0
      }
      this.innerVisible = true
    },
    handleEdit (row) {
      this.dialogTitle = this.key('edit')
      this.formData = {
        id: row.id,
        code: row.code,
        name: row.name,
        field_type: row.field_type,
        remark: row.remark || '',
        is_only: row.is_only || 0,
        is_upload: row.is_upload || 0
      }
      this.innerVisible = true
    },
    handleDelete (row) {
      this.$confirm(this.$t(this.key('confirm_delete_data')), this.$t(this.key('tips')), {
        confirmButtonText: this.$t(this.key('confirm')),
        cancelButtonText: this.$t(this.key('cancel')),
        type: 'warning'
      }).then(() => {
        deleteOptionalParams({ workingsubclass_id: this.workingsubclass_id, id: row.id }).then(() => {
          this.$message.success(this.$t(this.key('operation_success')))
          this.pagination.current = Math.min(this.pagination.current, Math.ceil((this.pagination.total - 1) / this.pagination.size) || 1)
          this.fetchData()
        })
      }).catch(() => {})
    },
    handleSubmit () {
      this.$refs.form.validate(valid => {
        if (!valid) return
        const action = this.formData.id ? editOptionalParams : createOptionalParams
        const data = { workingsubclass_id: this.workingsubclass_id, ...this.formData }
        action(data).then(() => {
          this.$message.success(this.$t(this.key('operation_success')))
          this.innerVisible = false
          this.$refs.form.resetFields()
          this.fetchData()
        })
      })
    },
    handleImport () {
      this.importFileList = []
      this.importRows = []
      this.importVisible = true
    },
    handleImportClose () {
      this.importVisible = false
      this.importFileList = []
      this.importRows = []
    },
    async downloadTemplate () {
      this.downloadImportLoading = true
      try {
        const res = await getImportTemplate({})
        downloadRename(res, 'xlsx', this.$t(this.key('optional_param_import_template')))
      } finally {
        this.downloadImportLoading = false
      }
    },
    getImportValue (row, keys) {
      for (const key of keys) {
        if (row[key] !== undefined && row[key] !== null) return row[key]
      }
      return ''
    },
    normalizeFlag (value) {
      if (value === 1 || value === '1') return 1
      if (value === 0 || value === '0') return 0
      const text = String(value || '').trim().toLowerCase()
      if ([this.$t(this.key('yes')).toLowerCase(), '是', 'yes', 'true'].includes(text)) return 1
      if ([this.$t(this.key('no')).toLowerCase(), '否', 'no', 'false'].includes(text)) return 0
      return value
    },
    async onImportFileChange (file) {
      if (!file || !/\.(xls|xlsx)$/i.test(file.name)) {
        this.$message.error(this.$t(this.key('upload_format_error')))
        this.importFileList = []
        return
      }
      this.importFileList = [file]
      this.importTableLoading = true
      try {
        const rows = await readExcel(file.raw)
        const required = [
          { label: this.key('name'), aliases: [this.$t(this.key('name')), '名称', 'Name'] },
          { label: this.key('param'), aliases: [this.$t(this.key('param')), '参数', 'Parameter'] },
          { label: this.key('category'), aliases: [this.$t(this.key('category')), '类别', 'Category'] }
        ]
        const first = rows[0] || {}
        const missing = required.find(field => !field.aliases.some(alias => Object.prototype.hasOwnProperty.call(first, alias)))
        if (missing) {
          this.$message.error(this.$t(this.key('import_missing_column'), { name: this.$t(missing.label) }))
          this.importRows = []
          return
        }
        const nameSet = new Set()
        const codeSet = new Set()
        const result = []
        for (const row of rows) {
          const name = this.getImportValue(row, [this.$t(this.key('name')), '名称', 'Name'])
          const code = this.getImportValue(row, [this.$t(this.key('param')), '参数', 'Parameter'])
          if (nameSet.has(name)) {
            this.$message.error(this.$t(this.key('import_duplicate_name'), { name }))
            this.importRows = []
            return
          }
          if (codeSet.has(code)) {
            this.$message.error(this.$t(this.key('import_duplicate_param'), { param: code }))
            this.importRows = []
            return
          }
          nameSet.add(name)
          codeSet.add(code)
          result.push({
            name,
            code,
            field_type: this.getImportValue(row, [this.$t(this.key('category')), '类别', 'Category']),
            remark: this.getImportValue(row, [this.$t(this.key('remark')), '备注', 'Remark']),
            is_only: this.normalizeFlag(this.getImportValue(row, [this.$t(this.key('is_unique')), '是否唯一', 'Is Unique'])),
            is_upload: this.normalizeFlag(this.getImportValue(row, [this.$t(this.key('is_upload')), '是否上传', 'Is Upload Required']))
          })
        }
        this.importRows = result
      } finally {
        this.importTableLoading = false
      }
    },
    async submitImport () {
      if (!this.importRows.length) {
        this.$message.error(this.$t(this.key('please_import_data')))
        return
      }
      this.importSubmitting = true
      try {
        await importDataCreate({
          workingsubclass_id: this.workingsubclass_id,
          import_data: JSON.stringify(this.importRows)
        })
        this.$message.success(this.$t(this.key('operation_success')))
        this.handleImportClose()
        this.fetchData()
      } finally {
        this.importSubmitting = false
      }
    }
  }
}
</script>

<style scoped>
.result-param-content {
  display: flex;
  justify-content: center;
  flex-direction: row;
}
.search-content-card {
  width: 20%;
  margin-right: 20px;
}
.search-content-table {
  width: 80%;
}
.box-card {
  width: 100%;
}
.import-form {
  margin-top: 16px;
}
</style>
