<template>
  <div class="app-container">
    <el-card shadow="never">
      <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
        <el-form-item>
          <template slot="label">{{ tmT("queryEntryDate") }}</template>
          <el-date-picker
            v-model="queryDateRange"
            type="daterange"
            value-format="yyyy-MM-dd"
            range-separator="-"
            :start-placeholder="tmT('queryDateRangePh')"
            :end-placeholder="tmT('queryDateRangeEndPh')"
            clearable
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item prop="stallCode">
          <template slot="label">{{ tmT("queryStallCode") }}</template>
          <el-input
            v-model="queryParams.stallCode"
            :placeholder="tmT('queryStallCodePh')"
            clearable
            style="width: 160px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item prop="supplierId">
          <template slot="label">{{ tmT("querySupplier") }}</template>
          <el-select v-model="queryParams.supplierId" :placeholder="tmCommon('pleaseSelect')" clearable filterable style="width: 200px">
            <el-option v-for="item in supplierOptions" :key="item.id" :label="item.supplierName" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="earTag">
          <template slot="label">{{ tmT("queryEarTag") }}</template>
          <el-input
            v-model="queryParams.earTag"
            :placeholder="tmT('queryEarTagPh')"
            clearable
            style="width: 160px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ tmCommon("search") }}</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ tmCommon("reset") }}</el-button>
          <el-button
            v-hasPermi="['tradeMarket:marketEntry:add']"
            type="primary"
            plain
            icon="el-icon-plus"
            size="mini"
            @click="handleAdd"
          >{{ tmCommon("add") }}</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <br />

    <el-card shadow="never">
      <el-table v-loading="loading" :data="tableList" border>
        <el-table-column :label="tmT('colEntryTime')" prop="entryTime" align="center" width="160" />
        <el-table-column :label="tmT('colStallCode')" prop="stallCode" align="center" width="100" />
        <el-table-column :label="tmT('colSupplier')" prop="supplierName" align="center" min-width="120" :show-overflow-tooltip="true" />
        <el-table-column :label="tmT('colEarTags')" align="center" min-width="160" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span>{{ formatEarTagsDisplay(scope.row) }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colQuantity')" align="center" width="100">
          <template slot-scope="scope">
            <span>{{ scope.row.quantity }}{{ tmT("unitHead") }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmCommon('colOp')" align="center" class-name="small-padding fixed-width" width="200" fixed="right">
          <template slot-scope="scope">
            <el-button v-hasPermi="['tradeMarket:marketEntry:query']" type="text" size="mini" @click="handleView(scope.row)">{{ tmCommon("view") }}</el-button>
            <el-button v-hasPermi="['tradeMarket:marketEntry:edit']" type="text" size="mini" @click="handleEdit(scope.row)">{{ tmCommon("edit") }}</el-button>
            <el-button v-hasPermi="['tradeMarket:marketEntry:remove']" type="text" size="mini" @click="handleDelete(scope.row)">{{ tmCommon("delete") }}</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </el-card>

    <el-dialog :title="dialogTitle" :visible.sync="open" width="640px" append-to-body @close="cancel">
      <el-form :key="formKey" ref="form" :model="form" label-width="120px">
        <el-form-item prop="entryTime" :rules="formRules.entryTime">
          <template slot="label">{{ tmT("formEntryTime") }}</template>
          <el-date-picker
            v-model="form.entryTime"
            type="datetime"
            value-format="yyyy-MM-dd HH:mm:ss"
            :placeholder="tmCommon('pleaseSelect')"
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item prop="stallId" :rules="formRules.stallId">
          <template slot="label">{{ tmT("formStallCode") }}</template>
          <el-select v-model="form.stallId" :placeholder="tmCommon('pleaseSelect')" style="width: 100%">
            <el-option v-for="item in stallOptions" :key="item.stallId" :label="item.stallCode" :value="item.stallId" />
          </el-select>
        </el-form-item>
        <el-form-item prop="supplierId" :rules="formRules.supplierId">
          <template slot="label">{{ tmT("formSupplier") }}</template>
          <el-select
            v-model="form.supplierId"
            :placeholder="tmT('phSupplierFilter')"
            filterable
            style="width: 100%"
            @change="onSupplierChange"
          >
            <el-option v-for="item in supplierOptions" :key="item.id" :label="item.supplierName" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="earTagList" :rules="formRules.earTagList">
          <template slot="label">{{ tmT("formEarTags") }}</template>
          <el-select
            v-model="form.earTagList"
            multiple
            :placeholder="earTagPlaceholder"
            style="width: 100%"
            :disabled="!form.supplierId"
            @change="onEarTagListChange"
          >
            <el-option v-for="tag in supplierEarTagOptions" :key="tag" :label="tag" :value="tag" />
          </el-select>
          <div v-if="form.supplierId && !supplierEarTagOptions.length" class="el-form-item__error" style="position: static">{{ tmT("tipNoEarTags") }}</div>
        </el-form-item>
        <el-form-item prop="quantity" :rules="formRules.quantity">
          <template slot="label">{{ tmT("formQuantity") }}</template>
          <el-input-number
            v-model="form.quantity"
            :min="0"
            :precision="0"
            :step="1"
            controls-position="right"
            style="width: 200px"
            disabled
          />
          <span class="form-unit">{{ tmT("unitHead") }}</span>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{ tmCommon("ok") }}</el-button>
        <el-button @click="cancel">{{ tmCommon("cancel") }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="tmCommon('viewTitle')" :visible.sync="viewOpen" width="640px" append-to-body>
      <el-form label-width="120px" size="small">
        <el-form-item :label="tmT('formEntryTime')"><span>{{ viewRow.entryTime }}</span></el-form-item>
        <el-form-item :label="tmT('formStallCode')"><span>{{ viewRow.stallCode }}</span></el-form-item>
        <el-form-item :label="tmT('formSupplier')"><span>{{ viewRow.supplierName }}</span></el-form-item>
        <el-form-item :label="tmT('formEarTags')"><span>{{ viewEarTagsText }}</span></el-form-item>
        <el-form-item :label="tmT('formQuantity')"><span>{{ viewRow.quantity }}{{ tmT("unitHead") }}</span></el-form-item>
        <el-form-item :label="tmT('viewCreateBy')"><span>{{ viewRow.createBy || dash }}</span></el-form-item>
        <el-form-item :label="tmT('viewCreateTime')"><span>{{ viewRow.createTime ? parseTime(viewRow.createTime) : dash }}</span></el-form-item>
        <el-form-item :label="tmT('viewUpdateBy')"><span>{{ viewRow.updateBy || dash }}</span></el-form-item>
        <el-form-item :label="tmT('viewUpdateTime')"><span>{{ viewRow.updateTime ? parseTime(viewRow.updateTime) : dash }}</span></el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-hasPermi="['tradeMarket:marketEntry:edit']" type="primary" plain @click="openEditFromView">{{ tmCommon("edit") }}</el-button>
        <el-button v-hasPermi="['tradeMarket:marketEntry:remove']" type="danger" plain @click="handleDelete(viewRow)">{{ tmCommon("delete") }}</el-button>
        <el-button @click="viewOpen = false">{{ tmCommon("close") }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { parseTime } from "@/utils/ruoyi"
import tradeMarketLocaleMixin from "@/mixins/tradeMarketLocaleMixin"
import { listSupplier } from "@/api/tradeMarket/supplier"
import {
  listMarketEntry,
  getMarketEntry,
  addMarketEntry,
  updateMarketEntry,
  delMarketEntry,
  listStallOptions,
  listSupplierEarTags
} from "@/api/tradeMarket/marketEntry"

function createEmptyForm() {
  return {
    id: undefined,
    entryTime: undefined,
    stallId: undefined,
    supplierId: undefined,
    earTagList: [],
    quantity: 0
  }
}

export default {
  name: "TradeMarketMarketEntry",
  mixins: [tradeMarketLocaleMixin],
  data() {
    return {
      tmNs: "marketEntry",
      loading: false,
      open: false,
      viewOpen: false,
      viewRow: {},
      dialogEdit: false,
      formKey: 0,
      total: 0,
      tableList: [],
      queryDateRange: [],
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        stallCode: undefined,
        supplierId: undefined,
        earTag: undefined
      },
      supplierOptions: [],
      stallOptions: [],
      supplierEarTagOptions: [],
      prevSupplierId: undefined,
      form: createEmptyForm()
    }
  },
  computed: {
    dash() {
      return this.$t("tradeMarket.status.dash")
    },
    dialogTitle() {
      return this.dialogEdit ? this.tmT("dialogEdit") : this.tmT("dialogAdd")
    },
    earTagPlaceholder() {
      if (!this.form.supplierId) {
        return this.tmT("phSelectSupplierFirst")
      }
      return this.tmCommon("pleaseSelect")
    },
    viewEarTagsText() {
      const list = this.viewRow.earTagList
      if (list && list.length) {
        return list.join("、")
      }
      return this.viewRow.earTags || this.dash
    },
    formRules() {
      return {
        entryTime: [{ validator: this.validateEntryTime, trigger: "change" }],
        stallId: [{ required: true, message: this.tmT("ruleStallCode"), trigger: "change" }],
        supplierId: [{ required: true, message: this.tmT("ruleSupplier"), trigger: "change" }],
        earTagList: [{ validator: this.validateEarTagList, trigger: "change" }],
        quantity: [{ validator: this.validateQuantity, trigger: "change" }]
      }
    }
  },
  created() {
    this.loadSupplierOptions()
    this.getList()
  },
  methods: {
    parseTime,
    formatNow() {
      return parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s}")
    },
    formatEarTagsDisplay(row) {
      const list = row.earTagList
      if (list && list.length) {
        return list.join("、")
      }
      return row.earTags || this.dash
    },
    loadSupplierOptions() {
      listSupplier({ pageNum: 1, pageSize: 500 }).then((res) => {
        this.supplierOptions = res.rows || []
      })
    },
    loadStallOptions() {
      return listStallOptions().then((res) => {
        this.stallOptions = res.data || []
      })
    },
    /** 合并接口返回与已选耳标，编辑时保留当前记录上的耳标 */
    mergeEarTagOptions(loaded, selected) {
      const set = new Set(loaded || [])
      for (const tag of selected || []) {
        set.add(tag)
      }
      return Array.from(set).sort()
    },
    loadSupplierEarTags(supplierId, keepSelected) {
      if (!supplierId) {
        this.supplierEarTagOptions = []
        return Promise.resolve()
      }
      const selected = keepSelected ? [...(this.form.earTagList || [])] : []
      return listSupplierEarTags(supplierId).then((res) => {
        const loaded = res.data || []
        this.supplierEarTagOptions = this.mergeEarTagOptions(loaded, selected)
        if (!loaded.length && !selected.length) {
          this.$modal.msgWarning(this.tmT("tipNoEarTags"))
        }
      })
    },
    onSupplierChange(supplierId) {
      if (this.prevSupplierId !== undefined && supplierId !== this.prevSupplierId) {
        this.form.earTagList = []
      }
      this.prevSupplierId = supplierId
      this.loadSupplierEarTags(supplierId, false)
      this.syncQuantity()
    },
    onEarTagListChange() {
      this.syncQuantity()
    },
    syncQuantity() {
      this.form.quantity = (this.form.earTagList || []).length
    },
    validateEntryTime(rule, value, callback) {
      if (!value) {
        callback(new Error(this.tmT("ruleEntryTime")))
        return
      }
      const t = new Date(String(value).replace(/-/g, "/")).getTime()
      if (isNaN(t)) {
        callback(new Error(this.tmT("ruleEntryTime")))
        return
      }
      if (t > Date.now()) {
        callback(new Error(this.tmT("ruleEntryTimeFuture")))
        return
      }
      callback()
    },
    validateEarTagList(rule, value, callback) {
      if (!this.form.supplierId) {
        callback(new Error(this.tmT("phSelectSupplierFirst")))
        return
      }
      const list = value || []
      if (!list.length) {
        callback(new Error(this.tmT("ruleEarTags")))
        return
      }
      const seen = new Set()
      for (const tag of list) {
        if (seen.has(tag)) {
          callback(new Error(this.tmT("ruleEarTagDup", { tag })))
          return
        }
        seen.add(tag)
      }
      callback()
    },
    validateQuantity(rule, value, callback) {
      const list = this.form.earTagList || []
      if (list.length !== (Number(value) || 0)) {
        callback(new Error(this.tmT("ruleQtyEarMismatch")))
        return
      }
      callback()
    },
    validateQueryDateRange() {
      if (this.queryDateRange && this.queryDateRange.length === 2) {
        const start = this.queryDateRange[0]
        const end = this.queryDateRange[1]
        if (start > end) {
          this.$modal.msgWarning(this.tmT("ruleDateRangeInvalid"))
          return false
        }
      }
      return true
    },
    buildListParams() {
      const params = { ...this.queryParams }
      if (this.queryDateRange && this.queryDateRange.length === 2) {
        params.entryDateStart = this.queryDateRange[0]
        params.entryDateEnd = this.queryDateRange[1]
      } else {
        params.entryDateStart = undefined
        params.entryDateEnd = undefined
      }
      return params
    },
    buildSubmitPayload() {
      const list = [...(this.form.earTagList || [])]
      return {
        id: this.form.id,
        entryTime: this.form.entryTime,
        stallId: this.form.stallId,
        supplierId: this.form.supplierId,
        earTagList: list,
        quantity: list.length
      }
    },
    getList() {
      if (!this.validateQueryDateRange()) {
        return
      }
      this.loading = true
      listMarketEntry(this.buildListParams())
        .then((res) => {
          this.tableList = res.rows || []
          this.total = res.total != null ? res.total : 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    resetQuery() {
      this.queryDateRange = []
      this.queryParams.stallCode = undefined
      this.queryParams.supplierId = undefined
      this.queryParams.earTag = undefined
      this.resetForm("queryForm")
      this.handleQuery()
    },
    resetFormModel() {
      this.form = createEmptyForm()
      this.form.entryTime = this.formatNow()
      this.supplierEarTagOptions = []
      this.prevSupplierId = undefined
      this.syncQuantity()
    },
    fillFormFromApi(data) {
      const tags = data.earTagList || []
      this.form = {
        id: data.id,
        entryTime: data.entryTime,
        stallId: data.stallId,
        supplierId: data.supplierId,
        earTagList: tags.length ? [...tags] : [],
        quantity: data.quantity != null ? data.quantity : tags.length
      }
      this.prevSupplierId = data.supplierId
      this.loadSupplierEarTags(data.supplierId, true)
    },
    handleAdd() {
      this.formKey += 1
      this.resetFormModel()
      this.dialogEdit = false
      this.loadStallOptions().then(() => {
        this.open = true
        this.$nextTick(() => this.resetForm("form"))
      })
    },
    handleEdit(row) {
      getMarketEntry(row.id).then((res) => {
        this.formKey += 1
        this.dialogEdit = true
        this.loadStallOptions().then(() => {
          this.fillFormFromApi(res.data || {})
          this.open = true
          this.$nextTick(() => {
            if (this.$refs.form) {
              this.$refs.form.clearValidate()
            }
          })
        })
      })
    },
    openEditFromView() {
      this.viewOpen = false
      this.handleEdit(this.viewRow)
    },
    handleView(row) {
      getMarketEntry(row.id).then((res) => {
        this.viewRow = res.data || {}
        this.viewOpen = true
      })
    },
    handleDelete(row) {
      this.$modal
        .confirm(
          this.tmT("confirmDelete", {
            supplier: row.supplierName,
            stallCode: row.stallCode,
            entryTime: row.entryTime,
            quantity: row.quantity
          })
        )
        .then(() => delMarketEntry(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.tmCommon("msgDelOk"))
          this.viewOpen = false
          this.getList()
        })
        .catch(() => {})
    },
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        const payload = this.buildSubmitPayload()
        const req = this.dialogEdit ? updateMarketEntry(payload) : addMarketEntry(payload)
        req.then(() => {
          this.$modal.msgSuccess(this.dialogEdit ? this.tmCommon("msgModOk") : this.tmCommon("msgAddOk"))
          this.open = false
          this.getList()
        })
      })
    },
    cancel() {
      this.open = false
      this.resetFormModel()
    }
  }
}
</script>

<style scoped lang="scss">
.form-unit {
  margin-left: 8px;
  color: #606266;
}
</style>
