<template>
  <d2-container>
    <div class="inspection-items-page">
      <aside class="category-panel" v-loading="treeLoading">
        <el-input
          v-model.trim="categoryFilter"
          size="mini"
          :placeholder="$t(key('enter_device_category_name'))"
          clearable
          class="category-filter"
        />
        <el-tree
          v-if="deviceCategoryTree.length"
          ref="categoryTree"
          :data="deviceCategoryTree"
          show-checkbox
          highlight-current
          default-expand-all
          node-key="id"
          :expand-on-click-node="false"
          :default-checked-keys="currentCategoryId ? [currentCategoryId] : []"
          :current-node-key="currentCategoryId"
          :filter-node-method="filterCategoryNode"
          @node-click="handleCategoryClick"
          @check-change="handleCategoryCheckChange"
        >
          <template #default="{ node, data }">
            <span class="category-node">
              <span>{{ node.label }}</span>
              <span class="category-code">({{ data.code || '-' }})</span>
            </span>
          </template>
        </el-tree>
        <el-result v-else icon="info" :title="$t(key('no_data'))" sub-title="" />
      </aside>

      <section class="items-panel">
        <div class="items-context">
          <span class="context-label">{{ $t(key('current_device_category')) }}</span>
          <strong>{{ currentCategoryLabel || '-' }}</strong>
        </div>
        <div class="search-bar">
          <el-form :inline="true" :model="search" size="mini">
            <el-form-item :label="$t(key('inspection_item_name'))">
              <el-input v-model.trim="search.name" :placeholder="$t(key('enter_inspection_item_name'))" clearable style="width:200px" @keyup.enter.native="onSearch" />
            </el-form-item>
            <el-form-item :label="$t(key('check_method'))">
              <el-input v-model.trim="search.check_method" :placeholder="$t(key('enter_check_method'))" clearable style="width:190px" @keyup.enter.native="onSearch" />
            </el-form-item>
            <el-form-item :label="$t(key('standard'))">
              <el-input v-model.trim="search.standard" :placeholder="$t(key('enter_standard'))" clearable style="width:190px" @keyup.enter.native="onSearch" />
            </el-form-item>
            <el-form-item :label="$t(key('unit'))">
              <el-input v-model.trim="search.unit" :placeholder="$t(key('enter_unit'))" clearable style="width:160px" @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>
              <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>

        <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"
        >
          <template #col-status="{ row }">
            <el-tag :type="Number(row.status) === 1 ? 'success' : 'info'" size="mini">
              {{ Number(row.status) === 1 ? $t(key('enabled')) : $t(key('disabled')) }}
            </el-tag>
          </template>
        </page-table>
      </section>
    </div>

    <page-dialog-form
      ref="dialogForm"
      :visible.sync="dialogVisible"
      :title="dialogTitle"
      width="700px"
      :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="900px" :close-on-click-modal="false">
      <el-alert :title="$t(key('import_tip'))" type="warning" :closable="false" />
      <el-form size="mini" label-width="130px" class="import-form">
        <el-form-item :label="$t(key('device_category'))" required>
          <el-select v-model="importDeviceCategoryId" :placeholder="$t(key('please_select_device_category'))" disabled style="width:260px">
            <el-option v-for="item in deviceCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item :label="$t(key('import_file'))">
          <el-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-form-item>
      </el-form>
      <el-table v-loading="importTableLoading" :data="importRows" border height="330" size="mini">
        <el-table-column prop="name" :label="$t(key('inspection_item_name'))" min-width="130" />
        <el-table-column prop="status" :label="$t(key('status'))" width="100" />
        <el-table-column prop="standard" :label="$t(key('standard'))" min-width="130" />
        <el-table-column prop="check_method" :label="$t(key('check_method'))" min-width="130" />
        <el-table-column prop="unit" :label="$t(key('unit'))" width="110" />
        <el-table-column prop="frequentness" :label="$t(key('frequentness'))" width="110" />
        <el-table-column prop="example" :label="$t(key('example'))" width="110" />
        <el-table-column prop="remark" :label="$t(key('remark'))" min-width="130" />
      </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 { getEquipmentCategoryALL } from '@/api/equipment-management/equipment-category'
import { getList, createItem, editItem, deleteItem, batchDeleteItems, getImportTemplate, importData } from '@/api/equipment-management/inspection-items'

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 }
}

function normalizeCategories (list) {
  return (Array.isArray(list) ? list : []).map((item, index) => ({
    id: item.id || item.value,
    value: item.id || item.value,
    label: item.name || item.label,
    name: item.name || item.label,
    code: item.code || '',
    index,
    children: []
  }))
}

export default {
  name: 'equipment-management-inspection-items',
  components: { PageTable, PageDialogForm },
  mixins: [i18nMixin('page.equipment_management.inspection_management.inspection_items'), confirmMixin],
  data () {
    return {
      loading: false,
      treeLoading: false,
      submitting: false,
      tableData: [],
      selectedRows: [],
      categoryFilter: '',
      deviceCategoryTree: [],
      deviceCategoryOptions: [],
      currentCategoryId: '',
      currentCategory: null,
      search: { name: '', check_method: '', standard: '', unit: '', create_time: [] },
      pagination: { current: 1, size: 10, total: 0 },
      dialogVisible: false,
      dialogTitle: '',
      handleType: 'create',
      editId: '',
      formData: this.emptyForm(),
      importVisible: false,
      importDeviceCategoryId: '',
      importFileList: [],
      importRows: [],
      importLoading: false,
      importTableLoading: false,
      columns: [],
      toolbarButtons: [],
      rowButtons: [],
      rules: {
        name: [
          { required: true, message: this.key('enter_inspection_item_name'), trigger: 'blur' },
          { min: 1, max: 100, message: this.key('length_1_100'), trigger: 'blur' }
        ],
        device_category_id: [{ required: true, message: this.key('please_select_device_category'), trigger: 'change' }],
        status: [{ required: true, message: this.key('please_select_status'), trigger: 'change' }]
      }
    }
  },
  computed: {
    currentCategoryLabel () {
      if (!this.currentCategory) return ''
      return `${this.currentCategory.label}${this.currentCategory.code ? ` (${this.currentCategory.code})` : ''}`
    },
    formCols () {
      return [
        [
          { type: 'input', prop: 'name', label: this.key('inspection_item_name'), placeholder: this.key('enter_inspection_item_name'), style: { width: '100%' } },
          { type: 'select', prop: 'device_category_id', label: this.key('device_category'), placeholder: this.key('please_select_device_category'), options: this.deviceCategoryOptions, disabled: true, style: { width: '100%' } }
        ],
        [
          { type: 'select', prop: 'status', label: this.key('status'), placeholder: this.key('please_select_status'), options: [{ label: this.$t(this.key('enabled')), value: 1 }, { label: this.$t(this.key('disabled')), value: 0 }], style: { width: '100%' } },
          { type: 'input', prop: 'standard', label: this.key('standard'), placeholder: this.key('enter_standard'), style: { width: '100%' } }
        ],
        [
          { type: 'input', prop: 'check_method', label: this.key('check_method'), placeholder: this.key('enter_check_method'), style: { width: '100%' } },
          { type: 'input', prop: 'unit', label: this.key('unit'), placeholder: this.key('enter_unit'), style: { width: '100%' } }
        ],
        [
          { type: 'input', prop: 'frequentness', label: this.key('frequentness'), placeholder: this.key('enter_frequentness'), style: { width: '100%' } },
          { type: 'input', prop: 'example', label: this.key('example'), placeholder: this.key('enter_example'), 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%' } }]
      ]
    }
  },
  watch: {
    categoryFilter (val) {
      if (this.$refs.categoryTree) this.$refs.categoryTree.filter(val)
    }
  },
  created () {
    this.columns = useTableColumns([
      { prop: 'sort', label: this.key('sort'), width: 80 },
      { prop: 'name', label: this.key('inspection_item_name'), minWidth: 150 },
      { prop: 'status', label: this.key('status'), slot: 'status', width: 100 },
      { prop: 'standard', label: this.key('standard'), minWidth: 140, showOverflowTooltip: true },
      { prop: 'check_method', label: this.key('check_method'), minWidth: 140, showOverflowTooltip: true },
      { prop: 'unit', label: this.key('unit'), minWidth: 100 },
      { prop: 'frequentness', label: this.key('frequentness'), minWidth: 110 },
      { prop: 'example', label: this.key('example'), minWidth: 110 },
      { prop: 'remark', label: this.key('remark'), minWidth: 140, 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_check/device_check_items/create', onClick: this.openAdd },
        { key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', type: 'danger', auth: '/device_management/device_check/device_check_items/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_check/device_check_items/import', onClick: this.openImport }
      ],
      row: [
        { key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_check/device_check_items/edit', onClick: this.openEdit },
        { key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_check/device_check_items/delete', onClick: this.handleDelete }
      ]
    }, this.$permission)
    this.toolbarButtons = btns.toolbarButtons
    this.rowButtons = btns.rowButtons
    this.loadDeviceCategories()
  },
  methods: {
    emptyForm () {
      return { name: '', device_category_id: '', status: 1, standard: '', check_method: '', unit: '', frequentness: '', example: '', remark: '' }
    },
    async loadDeviceCategories () {
      this.treeLoading = true
      try {
        const res = await getEquipmentCategoryALL({ no_denglu_sign: 'no' })
        const list = normalizeCategories((res && res.data) || res)
        this.deviceCategoryTree = list
        this.deviceCategoryOptions = list.map(item => ({ label: item.label, value: item.id, raw: item }))
        if (list.length) {
          this.setCurrentCategory(list[0], false)
          this.$nextTick(() => {
            if (this.$refs.categoryTree) {
              this.$refs.categoryTree.setCheckedKeys([this.currentCategoryId])
              this.$refs.categoryTree.setCurrentKey(this.currentCategoryId)
            }
          })
          this.fetchData()
        }
      } finally {
        this.treeLoading = false
      }
    },
    setCurrentCategory (category, shouldFetch = true) {
      this.currentCategory = category
      this.currentCategoryId = category ? category.id : ''
      this.selectedRows = []
      this.pagination.current = 1
      if (shouldFetch) this.fetchData()
    },
    filterCategoryNode (value, data) {
      if (!value) return true
      const text = String(value).toLowerCase()
      return String(data.label || '').toLowerCase().includes(text) || String(data.code || '').toLowerCase().includes(text)
    },
    handleCategoryClick (data) {
      this.setCurrentCategory(data)
      this.$nextTick(() => {
        if (this.$refs.categoryTree) this.$refs.categoryTree.setCheckedKeys([data.id])
      })
    },
    handleCategoryCheckChange (data, checked) {
      if (!checked) return
      if (this.$refs.categoryTree) this.$refs.categoryTree.setCheckedKeys([data.id])
      if (String(data.id) !== String(this.currentCategoryId)) this.setCurrentCategory(data)
    },
    buildSearchParams () {
      const params = { ...this.search, device_category_id: this.currentCategoryId }
      if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
      return params
    },
    async fetchData () {
      if (!this.currentCategoryId) {
        this.tableData = []
        this.pagination.total = 0
        return
      }
      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 = { name: '', check_method: '', standard: '', unit: '', create_time: [] }
      this.pagination.current = 1
      this.fetchData()
    },
    onPageChange (page) {
      this.pagination.current = page.current
      this.pagination.size = page.size
      this.fetchData()
    },
    resetForm () {
      this.formData = this.emptyForm()
      this.editId = ''
    },
    ensureCategorySelected () {
      if (this.currentCategoryId) return true
      this.$message.warning(this.$t(this.key('please_select_device_category')))
      return false
    },
    openAdd () {
      if (!this.ensureCategorySelected()) return
      this.handleType = 'create'
      this.dialogTitle = this.key('add_title')
      this.resetForm()
      this.formData.device_category_id = this.currentCategoryId
      this.dialogVisible = true
    },
    openEdit (row) {
      this.handleType = 'edit'
      this.dialogTitle = this.key('edit_title')
      this.editId = row.id
      this.formData = {
        name: row.name || '',
        device_category_id: row.device_category_id || this.currentCategoryId,
        status: Number(row.status),
        standard: row.standard || '',
        check_method: row.check_method || '',
        unit: row.unit || '',
        frequentness: row.frequentness || '',
        example: row.example || '',
        remark: row.remark || ''
      }
      this.dialogVisible = true
    },
    async onDialogSubmit () {
      this.submitting = true
      try {
        const payload = { ...this.formData, device_category_id: this.currentCategoryId }
        if (this.handleType === 'create') await createItem(payload)
        else await editItem({ ...payload, 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) {
        this.$message.success(this.$t(this.key('operation_success')))
        this.fetchData()
      }
    },
    async handleBatchDelete () {
      if (!this.selectedRows.length) {
        this.$message.warning(this.$t(this.key('please_select_data')))
        return
      }
      const ids = this.selectedRows.map(item => item.id)
      const cancelled = await this.$confirmAction(
        { message: this.key('confirm_batch_delete'), title: this.key('tip'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') },
        () => batchDeleteItems({ id: ids })
      )
      if (!cancelled) {
        this.$message.success(this.$t(this.key('operation_success')))
        this.fetchData()
      }
    },
    openImport () {
      if (!this.ensureCategorySelected()) return
      this.importDeviceCategoryId = this.currentCategoryId
      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 headers = ['inspection_item_name', 'status', 'standard', 'check_method', 'unit', 'frequentness', 'example', 'remark'].map(item => this.$t(this.key(item)))
        const first = rows[0] || {}
        for (const title of headers) {
          if (!Object.prototype.hasOwnProperty.call(first, title)) {
            this.$message.error(this.$t(this.key('file_column_missing'), { title }))
            this.importRows = []
            return
          }
        }
        const names = new Set()
        const normalized = []
        for (const row of rows) {
          const name = row[headers[0]]
          if (names.has(name)) {
            this.$message.error(this.$t(this.key('duplicate_import_name'), { name }))
            this.importRows = []
            return
          }
          names.add(name)
          normalized.push({
            name,
            status: row[headers[1]],
            standard: row[headers[2]],
            check_method: row[headers[3]],
            unit: row[headers[4]],
            frequentness: row[headers[5]],
            example: row[headers[6]],
            remark: row[headers[7]]
          })
        }
        this.importRows = normalized
      } finally {
        this.importTableLoading = false
      }
    },
    async submitImport () {
      if (!this.importDeviceCategoryId) {
        this.$message.warning(this.$t(this.key('please_select_device_category')))
        return
      }
      if (!this.importRows.length) {
        this.$message.warning(this.$t(this.key('please_import_data')))
        return
      }
      await importData({ device_category_id: this.importDeviceCategoryId, import_data: JSON.stringify(this.importRows) })
      this.$message.success(this.$t(this.key('operation_success')))
      this.importVisible = false
      this.fetchData()
    }
  }
}
</script>

<style scoped>
.inspection-items-page {
  display: flex;
  gap: 16px;
  height: 100%;
  min-height: 560px;
}
.category-panel {
  flex: 0 0 260px;
  min-width: 220px;
  border-right: 1px solid #ebeef5;
  padding: 10px 14px 10px 0;
  overflow: auto;
}
.category-filter {
  margin-bottom: 12px;
}
.category-node {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.category-code {
  color: #909399;
  font-size: 12px;
}
.items-panel {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.items-context {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  margin-bottom: 8px;
  color: #303133;
}
.context-label {
  color: #909399;
}
.search-bar {
  padding-bottom: 8px;
  border-bottom: 1px solid #ebeef5;
  margin-bottom: 10px;
}
.import-form {
  margin-top: 14px;
}
/deep/ .el-form-item--mini.el-form-item {
  margin-bottom: 4px;
}
/deep/ .d2-container-full__body {
  overflow: hidden;
}
</style>
