<template>
  <div class="app-container">
    <el-card shadow="never">
      <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
        <el-form-item prop="orderNo">
          <template slot="label">{{ tmT("queryOrderNo") }}</template>
          <el-input
            v-model="queryParams.orderNo"
            :placeholder="tmT('queryOrderNoPh')"
            clearable
            style="width: 180px"
            @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="distributorId">
          <template slot="label">{{ tmT("queryDistributor") }}</template>
          <el-select v-model="queryParams.distributorId" :placeholder="tmCommon('pleaseSelect')" clearable filterable style="width: 200px">
            <el-option v-for="item in distributorOptions" :key="item.id" :label="item.distributorName" :value="item.id" />
          </el-select>
        </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:tradeOrder: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('colOrderNo')" prop="orderNo" align="center" min-width="120" :show-overflow-tooltip="true" />
        <el-table-column :label="tmT('colCreateTime')" align="center" width="160">
          <template slot-scope="scope">
            <span>{{ scope.row.createTime ? parseTime(scope.row.createTime) : dash }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colSupplier')" prop="supplierName" align="center" min-width="110" :show-overflow-tooltip="true" />
        <el-table-column :label="tmT('colDistributor')" prop="distributorName" align="center" min-width="110" :show-overflow-tooltip="true" />
        <el-table-column :label="tmT('colLineList')" align="center" min-width="140">
          <template slot-scope="scope">
            <el-button type="text" size="mini" @click="openLineView(scope.row)">{{ scope.row.lineSummary || tmT("lineTableLink") }}</el-button>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colTotalHeads')" align="center" width="110">
          <template slot-scope="scope">
            <span>{{ scope.row.totalHeads }}{{ tmT("unitHead") }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colTotalAmount')" align="center" width="120">
          <template slot-scope="scope">
            <span>{{ formatAmount(scope.row.totalAmount) }}{{ tmT("unitYuan") }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colOrderStatus')" align="center" width="100">
          <template slot-scope="scope">
            <el-tag :type="isPending(scope.row) ? 'warning' : 'success'" size="small">{{ orderStatusLabel(scope.row) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colPayVoucher')" align="center" width="90">
          <template slot-scope="scope">
            <el-image
              v-if="scope.row.payVoucherUrl"
              :src="mediaUrl(scope.row.payVoucherUrl)"
              :preview-src-list="[mediaUrl(scope.row.payVoucherUrl)]"
              fit="cover"
              class="order-list-voucher"
            />
            <span v-else>{{ dash }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colFinishTime')" prop="finishTime" align="center" width="160">
          <template slot-scope="scope">
            <span>{{ scope.row.finishTime || dash }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmCommon('colOp')" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
          <template slot-scope="scope">
            <el-button
              v-if="isPending(scope.row)"
              v-hasPermi="['tradeMarket:tradeOrder:query']"
              type="text"
              size="mini"
              @click="handlePrint(scope.row, 'receipt')"
            >{{ tmT("btnPrintReceipt") }}</el-button>
            <el-button
              v-if="isPending(scope.row)"
              v-hasPermi="['tradeMarket:tradeOrder:pay']"
              type="text"
              size="mini"
              @click="openCompletePay(scope.row)"
            >{{ tmT("btnCompletePay") }}</el-button>
            <el-button
              v-if="isCompleted(scope.row)"
              v-hasPermi="['tradeMarket:tradeOrder:query']"
              type="text"
              size="mini"
              @click="handlePrint(scope.row, 'voucher')"
            >{{ tmT("btnPrintVoucher") }}</el-button>
            <el-button v-hasPermi="['tradeMarket:tradeOrder:query']" type="text" size="mini" @click="handleView(scope.row)">{{ tmCommon("view") }}</el-button>
            <el-button
              v-if="isPending(scope.row)"
              v-hasPermi="['tradeMarket:tradeOrder:edit']"
              type="text"
              size="mini"
              @click="handleEdit(scope.row)"
            >{{ tmCommon("edit") }}</el-button>
            <el-button
              v-if="isPending(scope.row)"
              v-hasPermi="['tradeMarket:tradeOrder: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="860px" append-to-body @close="cancel">
      <el-form :key="formKey" ref="form" :model="form" label-width="130px">
        <el-form-item v-if="dialogEdit" :label="tmT('formOrderNo')">
          <span>{{ form.orderNo || dash }}</span>
        </el-form-item>
        <el-form-item v-else>
          <div class="el-form-item__tip">{{ tmT("tipOrderNoAuto") }}</div>
        </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="distributorId" :rules="formRules.distributorId">
          <template slot="label">{{ tmT("formDistributor") }}</template>
          <el-select v-model="form.distributorId" :placeholder="tmT('phDistributorFilter')" filterable style="width: 100%">
            <el-option v-for="item in distributorOptions" :key="item.id" :label="item.distributorName" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="lineList" :rules="formRules.lineList">
          <template slot="label">{{ tmT("formLineList") }}</template>
          <el-button type="primary" plain size="mini" icon="el-icon-plus" :disabled="!form.supplierId" @click="addLineRow">{{ tmT("btnAddLine") }}</el-button>
          <el-table :data="form.lineList" border size="small" style="margin-top: 8px">
            <el-table-column :label="tmT('colLineEarTag')" align="center" min-width="160">
              <template slot-scope="scope">
                <el-select
                  v-model="scope.row.earTag"
                  :placeholder="tmCommon('pleaseSelect')"
                  style="width: 100%"
                  :disabled="!form.supplierId"
                  @change="syncTotals"
                >
                  <el-option v-for="tag in earTagOptionsForRow(scope.$index)" :key="tag" :label="tag" :value="tag" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column :label="tmT('colLineWeight')" align="center" width="140">
              <template slot-scope="scope">
                <el-input-number
                  v-model="scope.row.weight"
                  :min="0.01"
                  :precision="2"
                  :step="1"
                  controls-position="right"
                  style="width: 110px"
                  @change="syncTotals"
                />
                <span class="form-unit-inline">{{ tmT("unitKg") }}</span>
              </template>
            </el-table-column>
            <el-table-column :label="tmT('colLineAmount')" align="center" width="150">
              <template slot-scope="scope">
                <el-input-number
                  v-model="scope.row.amount"
                  :min="0.01"
                  :precision="2"
                  :step="1"
                  controls-position="right"
                  style="width: 110px"
                  @change="syncTotals"
                />
                <span class="form-unit-inline">{{ tmT("unitYuan") }}</span>
              </template>
            </el-table-column>
            <el-table-column :label="tmCommon('colOp')" align="center" width="80">
              <template slot-scope="scope">
                <el-button type="text" size="mini" @click="removeLineRow(scope.$index)">{{ tmCommon("delete") }}</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div v-if="form.supplierId && !supplierEarTagOptions.length" class="el-form-item__error" style="position: static">{{ tmT("tipNoEarTags") }}</div>
        </el-form-item>
        <el-form-item :label="tmT('formTotalHeads')">
          <span>{{ form.totalHeads }}{{ tmT("unitHead") }}</span>
        </el-form-item>
        <el-form-item :label="tmT('formTotalAmount')">
          <span>{{ formatAmount(form.totalAmount) }}{{ tmT("unitYuan") }}</span>
        </el-form-item>
        <div class="form-tip">{{ tmT("tipSavePending") }}</div>
      </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="tmT('dialogCompletePay')" :visible.sync="payOpen" width="520px" append-to-body @close="cancelPay">
      <el-form ref="payFormRef" :model="payForm" label-width="120px">
        <el-form-item prop="payVoucherPath" :rules="payFormRules.payVoucherPath">
          <template slot="label">{{ tmT("formPayVoucher") }}</template>
          <el-upload
            class="order-voucher-uploader"
            :action="uploadAction"
            :headers="uploadHeaders"
            :show-file-list="false"
            accept=".jpg,.jpeg,.png"
            :before-upload="beforeVoucherUpload"
            :on-success="handleVoucherUploadSuccess"
            :on-error="handleUploadHttpError"
          >
            <img v-if="payForm.payVoucherUrl" :src="mediaUrl(payForm.payVoucherUrl)" class="order-voucher-preview">
            <i v-else class="el-icon-plus order-voucher-icon" />
          </el-upload>
          <div class="el-upload__tip">{{ tmT("tipPayVoucher") }}</div>
          <el-button v-if="payForm.payVoucherPath" type="text" size="mini" @click="clearPayVoucher">{{ tmCommon("delete") }}</el-button>
        </el-form-item>
        <div class="form-tip">{{ tmT("tipCompletePay") }}</div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitCompletePay">{{ tmCommon("ok") }}</el-button>
        <el-button @click="cancelPay">{{ tmCommon("cancel") }}</el-button>
      </div>
    </el-dialog>

    <!-- 采购明细表 -->
    <el-dialog :title="tmT('lineViewTitle')" :visible.sync="lineViewOpen" width="640px" append-to-body>
      <el-table :data="lineViewList" border size="small">
        <el-table-column :label="tmT('colLineEarTag')" prop="earTag" align="center" min-width="140" />
        <el-table-column :label="tmT('colLineWeight')" align="center" width="120">
          <template slot-scope="scope">
            <span>{{ scope.row.weight }}{{ tmT("unitKg") }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="tmT('colLineAmount')" align="center" width="120">
          <template slot-scope="scope">
            <span>{{ formatAmount(scope.row.amount) }}{{ tmT("unitYuan") }}</span>
          </template>
        </el-table-column>
      </el-table>
      <div slot="footer" class="dialog-footer">
        <el-button @click="lineViewOpen = false">{{ tmCommon("close") }}</el-button>
      </div>
    </el-dialog>

    <!-- 查看 -->
    <el-dialog :title="tmCommon('viewTitle')" :visible.sync="viewOpen" width="860px" append-to-body>
      <el-form label-width="130px" size="small">
        <el-form-item :label="tmT('formOrderNo')"><span>{{ viewRow.orderNo }}</span></el-form-item>
        <el-form-item :label="tmT('colCreateTime')"><span>{{ viewRow.createTime ? parseTime(viewRow.createTime) : dash }}</span></el-form-item>
        <el-form-item :label="tmT('formSupplier')"><span>{{ viewRow.supplierName }}</span></el-form-item>
        <el-form-item :label="tmT('formDistributor')"><span>{{ viewRow.distributorName }}</span></el-form-item>
        <el-form-item :label="tmT('colOrderStatus')">
          <el-tag :type="isPending(viewRow) ? 'warning' : 'success'" size="small">{{ orderStatusLabel(viewRow) }}</el-tag>
        </el-form-item>
        <el-form-item :label="tmT('formLineList')">
          <el-table :data="viewRow.lineList || []" border size="small">
            <el-table-column :label="tmT('colLineEarTag')" prop="earTag" align="center" />
            <el-table-column :label="tmT('colLineWeight')" align="center">
              <template slot-scope="scope">
                <span>{{ scope.row.weight }}{{ tmT("unitKg") }}</span>
              </template>
            </el-table-column>
            <el-table-column :label="tmT('colLineAmount')" align="center">
              <template slot-scope="scope">
                <span>{{ formatAmount(scope.row.amount) }}{{ tmT("unitYuan") }}</span>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
        <el-form-item :label="tmT('formTotalHeads')"><span>{{ viewRow.totalHeads }}{{ tmT("unitHead") }}</span></el-form-item>
        <el-form-item :label="tmT('formTotalAmount')"><span>{{ formatAmount(viewRow.totalAmount) }}{{ tmT("unitYuan") }}</span></el-form-item>
        <el-form-item :label="tmT('formPayVoucher')">
          <el-image
            v-if="viewRow.payVoucherUrl"
            :src="mediaUrl(viewRow.payVoucherUrl)"
            :preview-src-list="[mediaUrl(viewRow.payVoucherUrl)]"
            fit="cover"
            class="order-view-voucher"
          />
          <span v-else>{{ dash }}</span>
        </el-form-item>
        <el-form-item :label="tmT('colFinishTime')"><span>{{ viewRow.finishTime || dash }}</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-if="isPending(viewRow)"
          v-hasPermi="['tradeMarket:tradeOrder:edit']"
          type="primary"
          plain
          @click="openEditFromView"
        >{{ tmCommon("edit") }}</el-button>
        <el-button
          v-if="isPending(viewRow)"
          v-hasPermi="['tradeMarket:tradeOrder: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 { getToken } from "@/utils/auth"
import { parseTime } from "@/utils/ruoyi"
import tradeMarketLocaleMixin from "@/mixins/tradeMarketLocaleMixin"
import { listSupplier } from "@/api/tradeMarket/supplier"
import { listDistributor } from "@/api/tradeMarket/distributor"
import {
  listTradeOrder,
  getTradeOrder,
  addTradeOrder,
  updateTradeOrder,
  delTradeOrder,
  listTradeOrderSupplierEarTags,
  completeTradeOrderPay
} from "@/api/tradeMarket/tradeOrder"

const ORDER_STATUS_PENDING = "0"
const ORDER_STATUS_COMPLETED = "1"
const PHOTO_EXTS = ["jpg", "jpeg", "png"]
const MAX_PHOTO_MB = 10

function createEmptyLine() {
  return { earTag: undefined, weight: undefined, amount: undefined }
}

function createEmptyForm() {
  return {
    id: undefined,
    orderNo: undefined,
    supplierId: undefined,
    distributorId: undefined,
    lineList: [],
    totalHeads: 0,
    totalAmount: 0
  }
}

export default {
  name: "TradeMarketTradeOrder",
  mixins: [tradeMarketLocaleMixin],
  data() {
    return {
      tmNs: "tradeOrder",
      loading: false,
      open: false,
      viewOpen: false,
      payOpen: false,
      lineViewOpen: false,
      viewRow: {},
      lineViewList: [],
      dialogEdit: false,
      formKey: 0,
      total: 0,
      tableList: [],
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        orderNo: undefined,
        supplierId: undefined,
        distributorId: undefined
      },
      supplierOptions: [],
      distributorOptions: [],
      supplierEarTagOptions: [],
      prevSupplierId: undefined,
      form: createEmptyForm(),
      payForm: {
        id: undefined,
        payVoucherUrl: undefined,
        payVoucherPath: undefined
      }
    }
  },
  computed: {
    dash() {
      return this.$t("tradeMarket.status.dash")
    },
    dialogTitle() {
      return this.dialogEdit ? this.tmT("dialogEdit") : this.tmT("dialogAdd")
    },
    uploadAction() {
      return process.env.VUE_APP_BASE_API + "/common/upload"
    },
    uploadHeaders() {
      return { Authorization: "Bearer " + getToken() }
    },
    formRules() {
      return {
        supplierId: [{ required: true, message: this.tmT("ruleSupplier"), trigger: "change" }],
        distributorId: [{ required: true, message: this.tmT("ruleDistributor"), trigger: "change" }],
        lineList: [{ validator: this.validateLineList, trigger: "change" }]
      }
    },
    payFormRules() {
      return {
        payVoucherPath: [{ validator: this.validatePayVoucher, trigger: "change" }]
      }
    }
  },
  created() {
    this.loadSupplierOptions()
    this.loadDistributorOptions()
    this.getList()
  },
  methods: {
    parseTime,
    isPending(row) {
      return row && row.orderStatus === ORDER_STATUS_PENDING
    },
    isCompleted(row) {
      return row && row.orderStatus === ORDER_STATUS_COMPLETED
    },
    orderStatusLabel(row) {
      if (row && row.orderStatusName) {
        return row.orderStatusName
      }
      return this.isCompleted(row) ? this.tmT("statusCompleted") : this.tmT("statusPending")
    },
    formatAmount(val) {
      if (val == null || val === "") {
        return "0.00"
      }
      const n = Number(val)
      if (isNaN(n)) {
        return String(val)
      }
      return n.toFixed(2)
    },
    mediaUrl(url) {
      if (!url) {
        return ""
      }
      if (/^https?:\/\//i.test(url)) {
        return url
      }
      return process.env.VUE_APP_BASE_API + url
    },
    loadSupplierOptions() {
      listSupplier({ pageNum: 1, pageSize: 500 }).then((res) => {
        this.supplierOptions = res.rows || []
      })
    },
    loadDistributorOptions() {
      listDistributor({ pageNum: 1, pageSize: 500 }).then((res) => {
        this.distributorOptions = res.rows || []
      })
    },
    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 = []
      if (keepSelected) {
        for (const line of this.form.lineList || []) {
          if (line.earTag) {
            selected.push(line.earTag)
          }
        }
      }
      return listTradeOrderSupplierEarTags(supplierId).then((res) => {
        const loaded = res.data || []
        this.supplierEarTagOptions = this.mergeEarTagOptions(loaded, selected)
        if (!loaded.length && !selected.length) {
          this.$modal.msgWarning(this.tmT("tipNoEarTags"))
        }
      })
    },
    earTagOptionsForRow(rowIndex) {
      const used = new Set()
      this.form.lineList.forEach((line, idx) => {
        if (idx !== rowIndex && line.earTag) {
          used.add(line.earTag)
        }
      })
      const current = this.form.lineList[rowIndex] && this.form.lineList[rowIndex].earTag
      return this.supplierEarTagOptions.filter((tag) => !used.has(tag) || tag === current)
    },
    onSupplierChange(supplierId) {
      if (this.prevSupplierId !== undefined && supplierId !== this.prevSupplierId) {
        this.form.lineList = []
      }
      this.prevSupplierId = supplierId
      this.loadSupplierEarTags(supplierId, false)
      this.syncTotals()
    },
    addLineRow() {
      if (!this.form.supplierId) {
        this.$modal.msgWarning(this.tmT("phSelectSupplierFirst"))
        return
      }
      this.form.lineList.push(createEmptyLine())
    },
    removeLineRow(index) {
      this.form.lineList.splice(index, 1)
      this.syncTotals()
      this.$nextTick(() => {
        if (this.$refs.form) {
          this.$refs.form.validateField("lineList")
        }
      })
    },
    syncTotals() {
      const lines = this.form.lineList || []
      this.form.totalHeads = lines.length
      let sum = 0
      for (const line of lines) {
        sum += Number(line.amount) || 0
      }
      this.form.totalAmount = Math.round(sum * 100) / 100
    },
    validateLineList(rule, value, callback) {
      const lines = value || []
      if (!this.form.supplierId) {
        callback(new Error(this.tmT("phSelectSupplierFirst")))
        return
      }
      if (!lines.length) {
        callback(new Error(this.tmT("ruleLineEmpty")))
        return
      }
      const seen = new Set()
      for (const line of lines) {
        if (!line.earTag) {
          callback(new Error(this.tmT("ruleEarTag")))
          return
        }
        if (seen.has(line.earTag)) {
          callback(new Error(this.tmT("ruleEarTagDup", { tag: line.earTag })))
          return
        }
        seen.add(line.earTag)
        if (!(Number(line.weight) > 0)) {
          callback(new Error(this.tmT("ruleWeight")))
          return
        }
        if (!(Number(line.amount) > 0)) {
          callback(new Error(this.tmT("ruleAmount")))
          return
        }
      }
      callback()
    },
    validatePayVoucher(rule, value, callback) {
      if (!this.payForm.payVoucherPath) {
        callback(new Error(this.tmT("rulePayVoucher")))
        return
      }
      callback()
    },
    extOf(fileName) {
      if (!fileName || fileName.lastIndexOf(".") < 0) {
        return ""
      }
      return fileName.slice(fileName.lastIndexOf(".") + 1).toLowerCase()
    },
    beforeVoucherUpload(file) {
      const ext = this.extOf(file.name)
      if (!PHOTO_EXTS.includes(ext)) {
        this.$modal.msgError(this.tmT("errPhotoFmt"))
        return false
      }
      if (file.size / 1024 / 1024 > MAX_PHOTO_MB) {
        this.$modal.msgError(this.tmT("errPhotoMb"))
        return false
      }
      return true
    },
    handleVoucherUploadSuccess(res) {
      if (res.code === 200) {
        this.payForm.payVoucherUrl = res.url
        this.payForm.payVoucherPath = res.fileName
        this.$nextTick(() => {
          if (this.$refs.payFormRef) {
            this.$refs.payFormRef.validateField("payVoucherPath")
          }
        })
      } else {
        this.$modal.msgError(res.msg || this.tmT("errPhotoFmt"))
      }
    },
    clearPayVoucher() {
      this.payForm.payVoucherUrl = undefined
      this.payForm.payVoucherPath = undefined
    },
    handleUploadHttpError() {
      this.$modal.msgError(this.tmT("errPhotoFmt"))
    },
    buildSubmitPayload() {
      const lineList = (this.form.lineList || []).map((line) => ({
        earTag: line.earTag,
        weight: line.weight,
        amount: line.amount
      }))
      return {
        id: this.form.id,
        supplierId: this.form.supplierId,
        distributorId: this.form.distributorId,
        lineList,
        totalHeads: lineList.length,
        totalAmount: this.form.totalAmount
      }
    },
    getList() {
      this.loading = true
      listTradeOrder(this.queryParams)
        .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.queryParams.orderNo = undefined
      this.queryParams.supplierId = undefined
      this.queryParams.distributorId = undefined
      this.resetForm("queryForm")
      this.handleQuery()
    },
    resetFormModel() {
      this.form = createEmptyForm()
      this.supplierEarTagOptions = []
      this.prevSupplierId = undefined
      this.syncTotals()
    },
    fillFormFromApi(data) {
      const lines = (data.lineList || []).map((line) => ({
        earTag: line.earTag,
        weight: line.weight != null ? Number(line.weight) : undefined,
        amount: line.amount != null ? Number(line.amount) : undefined
      }))
      this.form = {
        id: data.id,
        orderNo: data.orderNo,
        supplierId: data.supplierId,
        distributorId: data.distributorId,
        lineList: lines.length ? lines : [],
        totalHeads: data.totalHeads != null ? data.totalHeads : lines.length,
        totalAmount: data.totalAmount != null ? Number(data.totalAmount) : 0
      }
      this.prevSupplierId = data.supplierId
      this.loadSupplierEarTags(data.supplierId, true)
    },
    handleAdd() {
      this.formKey += 1
      this.resetFormModel()
      this.dialogEdit = false
      this.open = true
      this.$nextTick(() => this.resetForm("form"))
    },
    handleEdit(row) {
      getTradeOrder(row.id).then((res) => {
        const data = res.data || {}
        if (!this.isPending(data)) {
          this.$modal.msgWarning(this.tmT("ruleCompletedNoEdit"))
          return
        }
        this.formKey += 1
        this.dialogEdit = true
        this.fillFormFromApi(data)
        this.open = true
        this.$nextTick(() => {
          if (this.$refs.form) {
            this.$refs.form.clearValidate()
          }
        })
      })
    },
    openEditFromView() {
      this.viewOpen = false
      this.handleEdit(this.viewRow)
    },
    handleView(row) {
      getTradeOrder(row.id).then((res) => {
        this.viewRow = res.data || {}
        this.viewOpen = true
      })
    },
    openLineView(row) {
      if (row.lineList && row.lineList.length) {
        this.lineViewList = row.lineList
        this.lineViewOpen = true
        return
      }
      getTradeOrder(row.id).then((res) => {
        this.lineViewList = (res.data && res.data.lineList) || []
        this.lineViewOpen = true
      })
    },
    handleDelete(row) {
      this.$modal
        .confirm(
          this.tmT("confirmDelete", {
            orderNo: row.orderNo,
            supplier: row.supplierName,
            totalHeads: row.totalHeads,
            totalAmount: this.formatAmount(row.totalAmount)
          })
        )
        .then(() => delTradeOrder(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.tmCommon("msgDelOk"))
          this.viewOpen = false
          this.getList()
        })
        .catch(() => {})
    },
    submitForm() {
      this.syncTotals()
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        const payload = this.buildSubmitPayload()
        const req = this.dialogEdit ? updateTradeOrder(payload) : addTradeOrder(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()
    },
    openCompletePay(row) {
      this.payForm = {
        id: row.id,
        payVoucherUrl: undefined,
        payVoucherPath: undefined
      }
      this.payOpen = true
      this.$nextTick(() => {
        if (this.$refs.payFormRef) {
          this.$refs.payFormRef.clearValidate()
        }
      })
    },
    cancelPay() {
      this.payOpen = false
      this.payForm = { id: undefined, payVoucherUrl: undefined, payVoucherPath: undefined }
    },
    submitCompletePay() {
      this.$refs.payFormRef.validate((valid) => {
        if (!valid) {
          return
        }
        completeTradeOrderPay({
          id: this.payForm.id,
          payVoucherUrl: this.payForm.payVoucherUrl,
          payVoucherPath: this.payForm.payVoucherPath
        }).then((res) => {
          const data = res.data || {}
          const settlementNo = data.settlementNo
          if (settlementNo) {
            this.$modal.msgSuccess(this.tmT("msgPayOk", { settlementNo }))
          } else {
            this.$modal.msgSuccess(this.tmT("msgPayOkSimple"))
          }
          this.payOpen = false
          this.getList()
        })
      })
    },
    handlePrint(row, mode) {
      getTradeOrder(row.id).then((res) => {
        const order = res.data || {}
        if (mode === "receipt" && !this.isPending(order)) {
          this.$modal.msgWarning(this.tmT("ruleReceiptPendingOnly"))
          return
        }
        if (mode === "voucher" && !this.isCompleted(order)) {
          this.$modal.msgWarning(this.tmT("ruleVoucherCompletedOnly"))
          return
        }
        this.openPrintWindow(order, mode)
      })
    },
    openPrintWindow(order, mode) {
      const title = mode === "receipt" ? this.tmT("printReceiptTitle") : this.tmT("printVoucherTitle")
      const lines = order.lineList || []
      const lineRows = lines
        .map(
          (line) =>
            `<tr><td>${line.earTag || ""}</td><td>${line.weight || ""}${this.tmT("unitKg")}</td><td>${this.formatAmount(line.amount)}${this.tmT("unitYuan")}</td></tr>`
        )
        .join("")
      const voucherHtml =
        mode === "voucher" && order.payVoucherUrl
          ? `<p><strong>${this.tmT("formPayVoucher")}：</strong><br/><img src="${this.mediaUrl(order.payVoucherUrl)}" style="max-width:320px;margin-top:8px;" /></p>`
          : ""
      const finishHtml =
        mode === "voucher"
          ? `<p>${this.tmT("colFinishTime")}：${order.finishTime || this.dash}</p>`
          : ""
      const html = `<!DOCTYPE html><html><head><meta charset="utf-8"/><title>${title}</title>
        <style>body{font-family:sans-serif;padding:24px;font-size:14px;} table{border-collapse:collapse;width:100%;margin:12px 0;}
        th,td{border:1px solid #333;padding:6px 8px;text-align:center;} h2{text-align:center;}</style></head><body>
        <h2>${title}</h2>
        <p>${this.tmT("formOrderNo")}：${order.orderNo || ""}</p>
        <p>${this.tmT("formSupplier")}：${order.supplierName || ""}</p>
        <p>${this.tmT("formDistributor")}：${order.distributorName || ""}</p>
        <p>${this.tmT("colCreateTime")}：${order.createTime ? parseTime(order.createTime) : ""}</p>
        <p>${this.tmT("colOrderStatus")}：${this.orderStatusLabel(order)}</p>
        <table><thead><tr><th>${this.tmT("colLineEarTag")}</th><th>${this.tmT("colLineWeight")}</th><th>${this.tmT("colLineAmount")}</th></tr></thead><tbody>${lineRows}</tbody></table>
        <p>${this.tmT("formTotalHeads")}：${order.totalHeads || 0}${this.tmT("unitHead")}</p>
        <p>${this.tmT("formTotalAmount")}：${this.formatAmount(order.totalAmount)}${this.tmT("unitYuan")}</p>
        ${finishHtml}${voucherHtml}
        </body></html>`
      const win = window.open("", "_blank")
      if (!win) {
        this.$modal.msgError(this.tmT("errPrintBlocked"))
        return
      }
      win.document.write(html)
      win.document.close()
      win.focus()
      win.print()
    }
  }
}
</script>

<style scoped lang="scss">
.form-unit-inline {
  margin-left: 4px;
  color: #606266;
  font-size: 12px;
}
.form-tip {
  color: #909399;
  font-size: 12px;
  margin: 0 0 8px 130px;
}
.order-list-voucher {
  width: 48px;
  height: 48px;
  border-radius: 4px;
}
.order-view-voucher {
  width: 120px;
  height: 120px;
  border-radius: 4px;
}
.order-voucher-uploader ::v-deep .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  width: 120px;
  height: 120px;
  line-height: 120px;
  text-align: center;
  overflow: hidden;
}
.order-voucher-uploader ::v-deep .el-upload:hover {
  border-color: #409eff;
}
.order-voucher-preview {
  width: 120px;
  height: 120px;
  object-fit: cover;
  display: block;
}
.order-voucher-icon {
  font-size: 28px;
  color: #8c939d;
}
</style>
