<template>
  <div class="app-container sale-out-page">
    <!-- 上：查询 -->
    <el-card shadow="never" class="top-card">
      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
        <el-form-item label="单据编号" prop="returnNum">
          <el-input v-model="queryParams.returnNum" placeholder="请输入单据编号" clearable style="width: 200px" />
        </el-form-item>

        <el-form-item label="日期" prop="dateRange">
          <el-date-picker
            v-model="queryParams.dateRange"
            type="daterange"
            value-format="yyyy-MM-dd"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            style="width: 260px"
            clearable
          />
        </el-form-item>

        <el-form-item label="客户" prop="customerNum">
          <el-select v-model="queryParams.customerNum" placeholder="请选择客户" filterable clearable style="width: 200px">
            <el-option v-for="item in customerOptions" :key="item.customerNum" :value="item.customerNum" :label="item.customerName" />
          </el-select>
        </el-form-item>

        <el-form-item label="业务员" prop="employeeNum">
          <el-select v-model="queryParams.employeeNum" placeholder="请选择业务员" filterable clearable style="width: 200px">
            <el-option v-for="item in salespersonOptions" :key="item.employeeNum" :value="item.employeeNum" :label="item.employeeName" />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <el-row :gutter="10" class="mb8">
        <el-col :span="1.5">
          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDeleteAll">批量删除</el-button>
        </el-col>
      </el-row>
    </el-card>

    <br />

    <!-- 下：列表 -->
    <el-card shadow="never" class="bottom-card">
      <el-table border stripe v-loading="loading" ref="multipleTable" :data="list" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="单据日期" align="center" prop="documentDate" min-width="110" />
        <el-table-column label="单据编号" align="center" prop="returnNum" min-width="150" />
        <el-table-column label="客户编号" align="center" prop="customerNum" min-width="120" />
        <el-table-column label="客户名称" align="center" prop="customerName" min-width="140" />
        <el-table-column label="业务员" align="center" prop="employeeName" min-width="120" />
        <el-table-column label="备注" align="center" prop="remark" min-width="160" />
        <el-table-column label="总计金额" align="center" prop="totalAmount" min-width="110" />
        <el-table-column label="操作" align="center" fixed="right" width="200">
          <template slot-scope="scope">
            <el-button type="text" size="mini" icon="el-icon-document" @click="handleDetail(scope.row)">查看详情</el-button>
            <el-button type="text" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</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="dialogOpen" fullscreen append-to-body class="sale-out-dialog">
      <!-- 查看详情：除表格外，其余字段用带边框 descriptions（总计金额放备注后面） -->
      <div v-if="dialogMode === 'view'" class="dialog-detail-body">
        <el-card shadow="never" class="dialog-detail-card">
          <el-descriptions :column="3" border size="small" class="detail-desc">
            <el-descriptions-item label="单据日期">{{ emptyDisplay(form.documentDate) }}</el-descriptions-item>
            <el-descriptions-item label="单据编号">{{ emptyDisplay(form.returnNum) }}</el-descriptions-item>
            <el-descriptions-item label="客户">{{ emptyDisplay(form.customerName) }}</el-descriptions-item>
            <el-descriptions-item label="业务员">{{ emptyDisplay(form.employeeName) }}</el-descriptions-item>
            <el-descriptions-item label="备注">{{ emptyDisplay(form.remark) }}</el-descriptions-item>
            <el-descriptions-item label="总计金额">{{ emptyDisplay(form.totalAmount) }}</el-descriptions-item>
          </el-descriptions>

          <div class="dialog-table-card dialog-table-card--detail">
            <el-table :data="form.goods" border stripe height="100%" class="dialog-table">
              <el-table-column label="货品编号" align="center" prop="goodsNum" min-width="120" show-overflow-tooltip />
              <el-table-column label="货品名称" align="center" prop="goodsName" min-width="130" show-overflow-tooltip />
              <el-table-column label="规格" align="center" prop="goodsSpec" min-width="100" show-overflow-tooltip />
              <el-table-column label="仓库" align="center" prop="warehouseName" min-width="100" show-overflow-tooltip />
              <el-table-column label="基本计量数量" align="center" prop="baseNum" min-width="120" />
              <el-table-column label="基本计量单位" align="center" prop="baseUnit" min-width="110" />
              <el-table-column label="辅助计量数量" align="center" prop="assNum" min-width="120" />
              <el-table-column label="辅助计量单位" align="center" prop="assUnit" min-width="110" />
              <el-table-column label="单价" align="center" prop="unitPrice" min-width="100" />
              <el-table-column label="金额" align="center" prop="amount" min-width="110" />
              <el-table-column label="货品备注" align="center" prop="goodsRemark" min-width="140" show-overflow-tooltip />
            </el-table>
          </div>
        </el-card>
      </div>

      <!-- 新增/编辑：单 el-form 包裹表头 + 明细表（明细行字段可校验） -->
      <div v-else class="dialog-body">
        <el-form ref="dialogForm" :model="form" :rules="dialogFormRules" label-width="90px" size="small" class="dialog-main-form">
          <!-- 上：表头 -->
          <el-card shadow="never" class="dialog-head-card">
            <el-row :gutter="12">
              <el-col :span="6">
                <el-form-item label="单据日期" prop="documentDate">
                  <el-date-picker v-model="form.documentDate" type="date" value-format="yyyy-MM-dd" placeholder="单据日期" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="单据编号" prop="returnNum">
                  <el-input v-model="form.returnNum" placeholder="请输入单据编号" clearable />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="销货转入" prop="deliveryNum">
                  <el-input v-model="form.deliveryNum" placeholder="销货转入" clearable>
                    <el-button slot="append" icon="el-icon-search" @click="openSaleTransferQueryDialog" />
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="客户" prop="customerNum">
                  <el-select v-model="form.customerNum" placeholder="请选择客户" filterable clearable style="width: 100%" @change="onDialogCustomerChange">
                    <el-option v-for="item in customerOptions" :key="item.customerNum" :value="item.customerNum" :label="item.customerName" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="业务员" prop="employeeNum">
                  <el-select v-model="form.employeeNum" placeholder="请选择业务员" filterable clearable style="width: 100%">
                    <el-option v-for="item in salespersonOptions" :key="item.employeeNum" :value="item.employeeNum" :label="item.employeeName" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="备注" prop="remark">
                  <el-input v-model="form.remark" placeholder="请输入备注" clearable />
                </el-form-item>
              </el-col>
            </el-row>
          </el-card>

          <!-- 中：明细工具栏 + 可编辑表格（对齐 saleOut，无「批次」列） -->
          <div class="dialog-detail-toolbar">
            <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddDetailRow">添加明细</el-button>
          </div>
          <el-card shadow="never" class="dialog-table-card">
            <el-table :data="form.goods" border stripe height="100%" class="dialog-table dialog-table--with-form">
              <el-table-column label="货品编号" align="center" prop="goodsNum" min-width="168">
                <template slot-scope="{ row, $index }">
                  <el-form-item :prop="'goods.' + $index + '.goodsNum'" :rules="detailGoodsFieldRules.goodsNum" label-width="0" class="dialog-goods-form-item">
                    <el-input v-model="row.goodsNum" size="mini" placeholder="货品编号" clearable>
                      <template slot="append">
                        <el-tooltip :content="dialogMaterialQueryTooltip" placement="top">
                          <span class="dialog-material-query-append">
                            <el-button
                              type="primary"
                              icon="el-icon-search"
                              circle
                              size="mini"
                              :disabled="!canQueryDialogMaterial"
                              @click="openDialogMaterialQuery($index)"
                            />
                          </span>
                        </el-tooltip>
                      </template>
                    </el-input>
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column label="货品名称" align="center" prop="goodsName" min-width="130">
                <template slot-scope="{ row }">
                  <el-input v-model="row.goodsName" size="mini" placeholder="货品名称" clearable />
                </template>
              </el-table-column>
              <el-table-column label="规格" align="center" prop="goodsSpec" min-width="100">
                <template slot-scope="{ row }">
                  <el-input v-model="row.goodsSpec" size="mini" placeholder="规格" clearable />
                </template>
              </el-table-column>
              <el-table-column label="仓库" align="center" prop="warehouseName" min-width="150">
                <template slot-scope="{ row }">
                  <el-input v-model="row.warehouseName" size="mini" placeholder="仓库" clearable />
                </template>
              </el-table-column>
              <el-table-column label="基本计量数量" align="center" prop="baseNum" min-width="120">
                <template slot-scope="{ row, $index }">
                  <el-form-item :prop="'goods.' + $index + '.baseNum'" :rules="detailGoodsFieldRules.baseNum" label-width="0" class="dialog-goods-form-item">
                    <decimal-input
                      v-model="row.baseNum"
                      size="mini"
                      :precision="2"
                      :min="0"
                      placeholder="数量"
                      @change="() => recalcLineAmount($index)"
                    />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column label="基本计量单位" align="center" prop="baseUnit" min-width="130">
                <template slot-scope="{ row }">
                  <el-input v-model="row.baseUnit" size="mini" placeholder="单位" clearable />
                </template>
              </el-table-column>
              <el-table-column label="辅助计量数量" align="center" prop="assNum" min-width="120">
                <template slot-scope="{ row, $index }">
                  <decimal-input
                    v-model="row.assNum"
                    size="mini"
                    :precision="2"
                    :min="0"
                    placeholder="数量"
                    @change="() => syncDetailBaseNumFromAssist(row, $index)"
                  />
                </template>
              </el-table-column>
              <el-table-column label="辅助计量单位" align="center" prop="assUnit" min-width="110">
                <template slot-scope="{ row }">
                  <el-input v-model="row.assUnit" size="mini" placeholder="单位" clearable />
                </template>
              </el-table-column>
              <el-table-column label="单价" align="center" prop="unitPrice" min-width="120">
                <template slot-scope="{ row, $index }">
                  <el-form-item :prop="'goods.' + $index + '.unitPrice'" :rules="detailGoodsFieldRules.unitPrice" label-width="0" class="dialog-goods-form-item">
                    <decimal-input v-model="row.unitPrice" size="mini" :precision="2" :min="0" placeholder="单价" @change="() => recalcLineAmount($index)" />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column label="金额" align="center" prop="amount" min-width="120">
                <template slot-scope="{ row, $index }">
                  <el-form-item :prop="'goods.' + $index + '.amount'" :rules="detailGoodsFieldRules.amount" label-width="0" class="dialog-goods-form-item">
                    <el-input :value="row.amount != null && row.amount !== '' ? row.amount : ''" size="mini" readonly placeholder="自动计算" />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column label="货品备注" align="center" prop="goodsRemark" min-width="140">
                <template slot-scope="{ row }">
                  <el-input v-model="row.goodsRemark" size="mini" placeholder="货品备注" clearable />
                </template>
              </el-table-column>
              <el-table-column label="操作" align="center" width="70" fixed="right">
                <template slot-scope="{ $index }">
                  <el-button
                    type="text"
                    icon="el-icon-delete"
                    :disabled="!form.goods || form.goods.length <= 1"
                    @click="handleRemoveDetailRow($index)"
                  />
                </template>
              </el-table-column>
            </el-table>
          </el-card>

          <!-- 下：总计 -->
          <el-card shadow="never" class="dialog-foot-card">
            <el-row :gutter="12">
              <el-col :span="6">
                <div class="total-amount-field">
                  <span class="total-amount-label">总计金额</span>
                  <decimal-input v-model="form.totalAmount" size="mini" :precision="2" :min="0" placeholder="总计金额" disabled />
                </div>
              </el-col>
            </el-row>
          </el-card>
        </el-form>
      </div>

      <div slot="footer" class="dialog-footer">
        <template v-if="dialogMode === 'view'">
          <el-button type="primary" @click="dialogOpen = false">关 闭</el-button>
        </template>
        <template v-else>
          <el-button @click="dialogOpen = false">取 消</el-button>
          <el-button type="primary" @click="submitForm">确 定</el-button>
        </template>
      </div>
    </el-dialog>

    <!-- 退货明细货品速查（单选）；选后按单据日期+客户+货品拉单价（与销售出库一致） -->
    <query-material
      ref="queryMaterial"
      :isMultiple="false"
      :excludeGoodsNums="dialogMaterialExcludeGoodsNums"
      @selectList="handleDialogMaterialSelect"
    />

    <!-- 销货转入查询：单选高亮，选中后把销货出库单 goods 写入退货明细（getSaleOutList） -->
    <el-dialog
      title="销货转入查询"
      :visible.sync="saleTransferQueryDialogOpen"
      width="1200px"
      append-to-body
      class="sale-transfer-dialog"
      @close="onSaleTransferDialogClose"
    >
      <el-form :model="saleTransferQueryParams" size="small" :inline="true" label-width="80px" class="sale-transfer-query-form">
        <el-form-item label="单据编号" prop="deliveryNum">
          <el-input v-model="saleTransferQueryParams.deliveryNum" placeholder="请输入单据编号" clearable style="width: 200px" />
        </el-form-item>
        <el-form-item label="日期" prop="dateRange">
          <el-date-picker
            v-model="saleTransferQueryParams.dateRange"
            type="daterange"
            value-format="yyyy-MM-dd"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            style="width: 260px"
            clearable
          />
        </el-form-item>
        <el-form-item label="客户" prop="customerNum">
          <el-select v-model="saleTransferQueryParams.customerNum" placeholder="请选择客户" filterable clearable style="width: 200px">
            <el-option v-for="item in customerOptions" :key="item.customerNum" :value="item.customerNum" :label="item.customerName" />
          </el-select>
        </el-form-item>
        <el-form-item label="业务员" prop="employeeNum">
          <el-select v-model="saleTransferQueryParams.employeeNum" placeholder="请选择业务员" filterable clearable style="width: 200px">
            <el-option v-for="item in salespersonOptions" :key="item.employeeNum" :value="item.employeeNum" :label="item.employeeName" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleSaleTransferQuery">查询</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetSaleTransferQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <el-table
        ref="saleTransferTable"
        v-loading="saleTransferLoading"
        :data="saleTransferList"
        border
        stripe
        highlight-current-row
        height="420"
        style="width: 100%"
        class="sale-transfer-table"
        @row-click="handleSaleTransferRowClick"
      >
        <!-- 列与 saleOut/index.vue 主表 list 一致（不含备注、操作） -->
        <el-table-column label="单据日期" align="center" prop="documentDate" min-width="110" />
        <el-table-column label="单据编号" align="center" prop="deliveryNum" min-width="150" />
        <el-table-column label="客户编号" align="center" prop="customerNum" min-width="120" />
        <el-table-column label="客户名称" align="center" prop="customerName" min-width="140" />
        <el-table-column label="业务员" align="center" prop="employeeName" min-width="120" />
        <el-table-column label="总计金额" align="center" prop="totalAmount" min-width="110" />
      </el-table>

      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleSaleTransferConfirm">确 定</el-button>
        <el-button @click="saleTransferQueryDialogOpen = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { formatDateYMS } from "@/utils";
import { getStaffList } from "@/api/baseInfo/staff";
import { getClienteleList } from "@/api/sale/clientele";
import { getSaleBackPage, addSaleBack, editSaleBack, delSaleBack, getSaleBackById, getLatestSaleBackNum } from "@/api/sale/saleBack";
import { getSaleOutList, getSaleOutById } from "@/api/sale/saleOut";
import { getGoodsPriceInfo } from "@/api/sale/saleOrder";
import DecimalInput from "@/views/components/DecimalInput.vue";
import QueryMaterial from "@/views/components/queryMaterial.vue";

export default {
  name: "SaleBack",
  components: { DecimalInput, QueryMaterial },
  data() {
    return {
      /** 列表加载状态 */
      loading: false,
      /** 表格数据 */
      list: [],
      /** 总数 */
      total: 0,
      /** 选中 ids */
      ids: [],
      /** 批量删除禁用控制 */
      multiple: true,
      /** 查询参数（必须包含 pageNum/pageSize） */
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        returnNum: null,
        dateRange: [],
        customerNum: null,
        employeeNum: null,
        documentDateStart: null,
        documentDateEnd: null,
      },
      /** 客户下拉（当前模拟，后续接接口替换） */
      customerOptions: [],
      /** 业务员下拉（employeeType === '3'） */
      salespersonOptions: [],

      /** 新增/编辑弹框 */
      dialogOpen: false,
      dialogTitle: "新增",
      dialogMode: "add",
      /** 表头表单 */
      form: {
        id: null,
        documentDate: null,
        returnNum: null,
        /** 销货转入（新增/编辑；查看详情不展示） */
        deliveryNum: null,
        customerNum: null,
        employeeNum: null,
        remark: null,
        totalAmount: "0.00",
        remark1: null,
        goods: [],
      },
      /** 物料速查：当前编辑的明细行下标 */
      currentDetailMaterialRowIndex: null,
      /** 已选货品编号，避免重复选（不含当前行） */
      dialogMaterialExcludeGoodsNums: [],
      /** 销货转入查询弹框 */
      saleTransferQueryDialogOpen: false,
      /** 销货转入查询：表格加载 */
      saleTransferLoading: false,
      /** 销货转入查询：销货出库列表（getSaleOutList） */
      saleTransferList: [],
      /** 销货转入查询：当前单行选中 */
      saleTransferSelectedRow: null,
      /** 销货转入查询：条件（与销货出库页 query 字段对齐，POST 给 getSaleOutList） */
      saleTransferQueryParams: {
        deliveryNum: null,
        dateRange: [],
        documentDateStart: null,
        documentDateEnd: null,
        customerNum: null,
        employeeNum: null,
      },
    };
  },
  created() {
    /** 初始化：日期默认今天到今天 */
    const today = formatDateYMS(new Date().getTime());
    this.queryParams.dateRange = [today, today];
    this.queryParams.documentDateStart = today;
    this.queryParams.documentDateEnd = today;
    /** 初始化：下拉数据 */
    this.fetchCustomerOptions();
    this.fetchSalespersonOptions();
    /** 初始化：默认查询 */
    this.getList();
  },
  watch: {
    'queryParams.dateRange': {
      handler(newVal) {
        if(newVal && newVal.length === 2) {
          this.queryParams.documentDateStart = newVal[0];
          this.queryParams.documentDateEnd = newVal[1];
        }
      },
      deep: true,
      immediate: true,
    },
    /** 销货转入弹框内日期区间 -> documentDateStart/End */
    "saleTransferQueryParams.dateRange": {
      handler(newVal) {
        if (newVal && newVal.length === 2) {
          this.saleTransferQueryParams.documentDateStart = newVal[0];
          this.saleTransferQueryParams.documentDateEnd = newVal[1];
        } else {
          this.saleTransferQueryParams.documentDateStart = null;
          this.saleTransferQueryParams.documentDateEnd = null;
        }
      },
      deep: true,
      immediate: true,
    },
  },
  computed: {
    /** 新增/编辑弹框表头：单据日期、单据编号、客户、业务员必填 */
    dialogFormRules() {
      return {
        documentDate: [{ required: true, message: "请选择单据日期", trigger: "change" }],
        returnNum: [{ required: true, message: "请输入单据编号", trigger: "blur" }],
        customerNum: [{ required: true, message: "请选择客户", trigger: "change" }],
        employeeNum: [{ required: true, message: "请选择业务员", trigger: "change" }],
      };
    },
    /** 物料速查：需先选单据日期与客户 */
    canQueryDialogMaterial() {
      return !!(this.form && this.form.documentDate && this.form.customerNum);
    },
    dialogMaterialQueryTooltip() {
      return this.canQueryDialogMaterial ? "点击查询货品" : "请先选择单据日期和客户";
    },
    /**
     * 明细表单元格校验规则（货品编号、基本计量单位、单价、金额不可为空）
     * @returns {Object<string, Array>}
     */
    detailGoodsFieldRules() {
      return {
        goodsNum: [{ required: true, message: "货品编号不能为空", trigger: "blur" }],
        baseNum: [
          { required: true, message: "基本计量数量不能为空", trigger: "blur" },
          {
            validator: (rule, value, callback) => {
              if (value === null || value === undefined || String(value).trim() === "") {
                callback(new Error("基本计量数量不能为空"));
                return;
              }
              if (!Number.isFinite(Number(value))) {
                callback(new Error("基本计量数量须为有效数字"));
                return;
              }
              callback();
            },
            trigger: "change",
          },
          ],
        unitPrice: [
          { required: true, message: "单价不能为空", trigger: "change" },
          {
            validator: (rule, value, callback) => {
              if (value === null || value === undefined || String(value).trim() === "") {
                callback(new Error("单价不能为空"));
                return;
              }
              if (!Number.isFinite(Number(value))) {
                callback(new Error("单价须为有效数字"));
                return;
              }
              callback();
            },
            trigger: "change",
          },
        ],
        amount: [
          {
            validator: (rule, value, callback) => {
              if (value === null || value === undefined || String(value).trim() === "") {
                callback(new Error("金额不能为空"));
                return;
              }
              if (!Number.isFinite(Number(value))) {
                callback(new Error("金额须为有效数字"));
                return;
              }
              callback();
            },
            trigger: "change",
          },
        ],
      };
    },
  },
  methods: {
    /**
     * 详情展示：空值显示「—」
     * @param {*} val 原值
     * @returns {string}
     */
    emptyDisplay(val) {
      if (val === null || val === undefined) return "—";
      const s = String(val).trim();
      return s === "" ? "—" : s;
    },
    /**
     * 详情弹框：业务员展示（优先姓名，否则按编号匹配下拉）
     * @returns {string|null}
     */
    viewSalespersonText() {
      if (this.form.salespersonName) return this.form.salespersonName;
      const no = this.form.salespersonNo;
      if (no == null || no === "") return null;
      const hit = (this.salespersonOptions || []).find((x) => String(x.employeeNum) === String(no));
      return hit ? hit.employeeName : String(no);
    },
    /**
     * 空明细行
     * @returns {Object}
     */
    createEmptyDetailRow() {
      return {
        goodsNum: null,
        goodsName: null,
        goodsSpec: null,
        warehouseNum: null,
        warehouseName: null,
        baseNum: null,
        salesWeight: null,
        baseUnit: null,
        assNum: null,
        assUnit: null,
        unitPrice: null,
        amount: null,
        goodsRemark: null,
        /** 基本计量数量 = conversionValue × 辅助计量数量（来自物料速查） */
        conversionValue: null,
      };
    },
    /** 添加一行退货明细（与销货出库「添加明细」一致） */
    handleAddDetailRow() {
      if (!Array.isArray(this.form.goods)) this.$set(this.form, "goods", []);
      this.form.goods.push(this.createEmptyDetailRow());
    },
    /**
     * 删除一行明细，至少保留一行
     * @param {number} index 行下标
     */
    handleRemoveDetailRow(index) {
      const goods = this.form.goods || [];
      if (goods.length <= 1) return;
      goods.splice(index, 1);
      this.recalcTotalAmount();
    },
    /**
     * 客户变化：带出客户名称
     * @param {string} customerNo 客户编号
     */
    onDialogCustomerChange(customerNum) {
      const hit = (this.customerOptions || []).find((x) => String(x.customerNum) === String(customerNum));
      this.form.customerName = hit ? hit.customerName : null;
    },
    /**
     * 打开明细行物料速查（需单据日期+客户）
     * @param {number} rowIndex 行下标
     */
    openDialogMaterialQuery(rowIndex) {
      if (!this.canQueryDialogMaterial) {
        this.$message.warning("请先选择单据日期和客户");
        return;
      }
      this.currentDetailMaterialRowIndex = rowIndex;
      this.dialogMaterialExcludeGoodsNums = (this.form.goods || [])
        .map((r, i) => {
          if (i === rowIndex || !r) return null;
          const n = r.goodsNum;
          return n != null && String(n).trim() !== "" ? String(n) : null;
        })
        .filter(Boolean);
      if (this.$refs.queryMaterial) this.$refs.queryMaterial.open();
    },
    /**
     * 物料速查确定：写入货品信息并拉单价
     * @param {Array<Object>} list 选中行
     */
    handleDialogMaterialSelect(list) {
      const selected = list || [];
      if (!selected.length) return;
      const idx = this.currentDetailMaterialRowIndex;
      if (idx == null || idx < 0) return;
      const row = (this.form.goods || [])[idx];
      if (!row) return;
      const item = selected[0];
      this.$set(row, "goodsNum", item.goodsNum != null ? item.goodsNum : null);
      this.$set(row, "goodsName", item.goodsName != null ? item.goodsName : null);
      this.$set(row, "goodsSpec", item.goodsSpec != null ? item.goodsSpec : null);
      this.$set(row, "warehouseNum", item.warehouseNo != null ? item.warehouseNo : null);
      this.$set(row, "warehouseName", item.warehouseName != null ? item.warehouseName : null);
      this.$set(row, "baseUnit", item.unit != null ? item.unit : null);
      this.$set(
        row,
        "assUnit",
        item.assistantUnit != null ? item.assistantUnit : item.assUnit != null ? item.assUnit : null
      );
      this.$set(
        row,
        "conversionValue",
        item.conversionValue != null && item.conversionValue !== "" ? item.conversionValue : null
      );
      this.syncDetailBaseNumFromAssist(row, idx);
      this.fetchGoodsPriceInfoForDetailRow(idx);
    },
    /**
     * 是否存在有效换算值（基本数量由辅助数量推算）
     * @param {Object} row 明细行
     */
    isDetailBaseNumDerivedFromAssist(row) {
      const cv = Number(row && row.conversionValue);
      return Number.isFinite(cv) && cv > 0;
    },
    /**
     * 按换算同步基本计量数量并重算金额
     * @param {Object} row 明细行
     * @param {number} index 行下标
     */
    syncDetailBaseNumFromAssist(row, index) {
      if (!row) return;
      const cv = Number(row.conversionValue);
      const assRaw = row.assNum;
      const hasAss =
        assRaw !== null &&
        assRaw !== undefined &&
        String(assRaw).trim() !== "" &&
        !Number.isNaN(Number(assRaw));

      if (!Number.isFinite(cv) || cv <= 0) {
        this.recalcLineAmount(index);
        return;
      }
      if (!hasAss) {
        this.$set(row, "baseNum", null);
        this.recalcLineAmount(index);
        return;
      }
      const ass = Number(assRaw);
      if (ass >= 0) {
        this.$set(row, "baseNum", (cv * ass).toFixed(2));
      }
      this.recalcLineAmount(index);
    },
    /**
     * 按单据日期、客户、货品编号查询单价（销售订单侧接口）
     * @param {number} index 明细行下标
     */
    fetchGoodsPriceInfoForDetailRow(index) {
      const row = (this.form.goods || [])[index];
      if (!row) return;
      const documentDate = this.form.documentDate;
      const customerNum = this.form.customerNum;
      const goodsNum = row.goodsNum;
      if (!documentDate) {
        this.$message.warning("请先选择单据日期");
        this.$set(row, "unitPrice", "0.00");
        this.recalcLineAmount(index);
        return;
      }
      if (customerNum == null || String(customerNum).trim() === "") {
        this.$message.warning("请先选择客户");
        this.$set(row, "unitPrice", "0.00");
        this.recalcLineAmount(index);
        return;
      }
      if (goodsNum == null || String(goodsNum).trim() === "") {
        this.$set(row, "unitPrice", "0.00");
        this.recalcLineAmount(index);
        return;
      }
      getGoodsPriceInfo({
        documentDate: String(documentDate).trim(),
        customerNum: String(customerNum).trim(),
        goodsNum: String(goodsNum).trim(),
      })
        .then((res) => {
          this.applyGoodsPriceInfoToDetailRow(row, res && res.data);
          this.syncDetailBaseNumFromAssist(row, index);
        })
        .catch(() => {
          this.$set(row, "unitPrice", "0.00");
          this.recalcLineAmount(index);
        });
    },
    /**
     * 合并 getGoodsPriceInfo 返回（单价、数量等）
     * @param {Object} row 明细行
     * @param {*} data 接口 data
     */
    applyGoodsPriceInfoToDetailRow(row, data) {
      if (data == null) {
        this.$set(row, "unitPrice", "0.00");
        return;
      }
      let d = data;
      if (Array.isArray(d)) {
        d = d[0];
        if (d == null) {
          this.$set(row, "unitPrice", "0.00");
          return;
        }
      }
      if (typeof d !== "object") {
        this.$set(row, "unitPrice", this.pickUnitPriceFromGoodsPriceResponse(data));
        return;
      }
      const price =
        d.unitPrice != null
          ? d.unitPrice
          : d.salePrice != null
            ? d.salePrice
            : d.price != null
              ? d.price
              : null;
      if (price != null && price !== "") {
        const n = Number(price);
        this.$set(row, "unitPrice", Number.isFinite(n) ? n.toFixed(2) : "0.00");
      } else {
        this.$set(row, "unitPrice", "0.00");
      }
      ["goodsSpec", "baseUnit", "assUnit", "assNum"].forEach((k) => {
        if (d[k] != null && d[k] !== "") this.$set(row, k, d[k]);
      });
      if (!this.isDetailBaseNumDerivedFromAssist(row)) {
        if (d.baseNum != null && d.baseNum !== "") this.$set(row, "baseNum", d.baseNum);
      }
    },
    /**
     * 从 getGoodsPriceInfo 返回中解析单价
     * @param {*} data 接口 data
     * @returns {string}
     */
    pickUnitPriceFromGoodsPriceResponse(data) {
      let d = data;
      if (d == null) return "0.00";
      if (Array.isArray(d)) {
        d = d[0];
        if (d == null) return "0.00";
      }
      if (typeof d !== "object") {
        const n = Number(d);
        return Number.isFinite(n) ? n.toFixed(2) : "0.00";
      }
      const raw = d.unitPrice != null ? d.unitPrice : d.salePrice != null ? d.salePrice : d.price;
      if (raw == null || raw === "") return "0.00";
      const n = Number(raw);
      return Number.isFinite(n) ? n.toFixed(2) : "0.00";
    },
    /**
     * 打开销货转入查询弹框：默认今天～今天并拉取销货出库列表
     */
    openSaleTransferQueryDialog() {
      const today = formatDateYMS(new Date().getTime());
      this.saleTransferQueryParams = {
        deliveryNum: null,
        dateRange: [today, today],
        documentDateStart: today,
        documentDateEnd: today,
        customerNum: null,
        employeeNum: null,
      };
      this.saleTransferSelectedRow = null;
      this.saleTransferQueryDialogOpen = true;
      this.$nextTick(() => {
        if (this.$refs.saleTransferTable) this.$refs.saleTransferTable.setCurrentRow(null);
      });
      this.fetchSaleTransferOrderList();
    },
    /** 销货转入弹框关闭：清空当前行高亮状态 */
    onSaleTransferDialogClose() {
      this.saleTransferSelectedRow = null;
      this.$nextTick(() => {
        if (this.$refs.saleTransferTable) this.$refs.saleTransferTable.setCurrentRow(null);
      });
    },
    /**
     * 拉取销货出库列表（POST getSaleOutList，兼容 data 为数组或分页 records）
     */
    fetchSaleTransferOrderList() {
      this.saleTransferLoading = true;
      const p = { ...this.saleTransferQueryParams };
      delete p.dateRange;
      getSaleOutList(p)
        .then((res) => {
          const raw = res && res.data !== undefined ? res.data : res;
          let list = [];
          if (Array.isArray(raw)) {
            list = raw;
          } else if (raw && Array.isArray(raw.records)) {
            list = raw.records;
          } else if (raw && Array.isArray(raw.list)) {
            list = raw.list;
          }
          this.saleTransferList = list;
        })
        .catch(() => {
          this.saleTransferList = [];
        })
        .finally(() => {
          this.saleTransferLoading = false;
          this.saleTransferSelectedRow = null;
          this.$nextTick(() => {
            if (this.$refs.saleTransferTable) this.$refs.saleTransferTable.setCurrentRow(null);
          });
        });
    },
    /** 销货转入弹框：查询按钮 */
    handleSaleTransferQuery() {
      this.fetchSaleTransferOrderList();
    },
    /** 销货转入弹框：重置查询条件 */
    resetSaleTransferQuery() {
      const today = formatDateYMS(new Date().getTime());
      this.saleTransferQueryParams = {
        deliveryNum: null,
        dateRange: [today, today],
        documentDateStart: today,
        documentDateEnd: today,
        customerNum: null,
        employeeNum: null,
      };
      this.fetchSaleTransferOrderList();
    },
    /**
     * 表格行点击：单选并高亮当前行
     * @param {Object} row 当前行
     */
    handleSaleTransferRowClick(row) {
      if (!row) return;
      this.saleTransferSelectedRow = row;
      this.$nextTick(() => {
        if (this.$refs.saleTransferTable) this.$refs.saleTransferTable.setCurrentRow(row);
      });
    },
    /**
     * 将销货出库明细行转为销售退货明细字段（兼容 subTotal、行备注等字段名）
     * @param {Array<Object>} goods 销货出库 goods
     * @returns {Array<Object>}
     */
    mapSaleOutGoodsToSaleBackDetails(goods) {
      const arr = Array.isArray(goods) ? goods : [];
      return arr.map((g) => ({
        goodsNum: g.goodsNum != null ? g.goodsNum : null,
        goodsName: g.goodsName != null ? g.goodsName : null,
        goodsSpec: g.goodsSpec != null ? g.goodsSpec : null,
        warehouseNum: g.warehouseNum != null ? g.warehouseNum : null,
        warehouseName: g.warehouseName != null ? g.warehouseName : null,
        baseNum: g.baseNum != null ? g.baseNum : null,
        salesWeight: g.salesWeight != null ? g.salesWeight : null,
        baseUnit: g.baseUnit != null ? g.baseUnit : null,
        assNum: g.assNum != null ? g.assNum : null,
        assUnit: g.assUnit != null ? g.assUnit : null,
        unitPrice: g.unitPrice != null ? g.unitPrice : null,
        amount: g.amount != null ? g.amount : g.subTotal != null ? g.subTotal : null,
        goodsRemark:
          g.goodsRemark != null ? g.goodsRemark : g.lineRemark != null ? g.lineRemark : g.remark != null ? g.remark : null,
        conversionValue: g.conversionValue != null ? g.conversionValue : null,
      }));
    },
    /**
     * 确定：回填销货转入单号，并把选中单的 goods 写入 form.goods（优先 getSaleOutById）
     */
    handleSaleTransferConfirm() {
      const row = this.saleTransferSelectedRow;
      if (!row) {
        this.$message.warning("请先选择一条销货出库单");
        return;
      }
      const deliveryNum = row.deliveryNum != null ? row.deliveryNum : null;
      this.form.deliveryNum = deliveryNum;
      this.form.customerNum = row.customerNum;
      this.form.customerName = row.customerName;
      this.form.employeeNum = row.employeeNum;
      this.form.employeeName = row.employeeName;

      const applyGoods = (data) => {
        const goods = data && data.goods;
        const lines = this.mapSaleOutGoodsToSaleBackDetails(goods);
        if (!lines.length) {
          this.$message.warning("该销货出库单无明细货品，已带出单号，明细保留为空行");
          this.$set(this.form, "goods", [this.createEmptyDetailRow()]);
        } else {
          this.$set(this.form, "goods", lines);
        }
        this.recalcTotalAmount();
        this.saleTransferQueryDialogOpen = false;
      };

      if (row.id != null && row.id !== "") {
        getSaleOutById({ id: row.id })
          .then((res) => {
            const data = res && res.data ? res.data : res;
            applyGoods(data);
          })
          .catch(() => {
            applyGoods(row);
          });
      } else {
        applyGoods(row);
      }
    },
    /**
     * 重算行金额（数量 × 单价）并汇总总计
     * @param {number} index 行下标
     */
    recalcLineAmount(index) {
      const row = (this.form.goods || [])[index];
      if (!row) return;
      const q = Number(row.baseNum);
      const p = Number(row.unitPrice);
      const amt = Number.isFinite(q) && Number.isFinite(p) ? (q * p).toFixed(2) : null;
      this.$set(row, "amount", amt);
      this.recalcTotalAmount();
      /** 金额/单价由计算更新后，触发明细对应字段校验便于消除红字 */
      this.$nextTick(() => {
        const formRef = this.$refs.dialogForm;
        if (!formRef) return;
        const prefix = `goods.${index}.`;
        formRef.validateField(prefix + "amount");
        formRef.validateField(prefix + "unitPrice");
      });
    },
    /**
     * 汇总总计金额
     */
    recalcTotalAmount() {
      let sum = 0;
      (this.form.goods || []).forEach((r) => {
        const v = Number(r && r.amount);
        if (Number.isFinite(v)) sum += v;
      });
      this.form.totalAmount = sum.toFixed(2);
    },
    /**
     * 从列表行解析明细（无则返回模拟行，接接口后替换）
     * @param {Object} row 列表行
     * @returns {Array<Object>}
     */
    resolveDetailFromRow(row) {
      const list = row && row.goods;
      if (Array.isArray(list) && list.length) return list.map((x) => ({ ...x }));
      return [
        {
          goodsNum: "M001",
          goodsName: "示例货品",
          goodsSpec: "标品",
          warehouseName: "默认仓",
          baseNum: "1",
          salesWeight: "1",
          baseUnit: "kg",
          assNum: null,
          assUnit: "箱",
          unitPrice: "10",
          amount: "10.00",
          goodsRemark: null,
          conversionValue: null,
        },
      ];
    },
    /**
     * 获取客户下拉数据
     */
    fetchCustomerOptions() {
      getClienteleList({}).then((res) => {
        const list = (res && res.data) || [];
        this.customerOptions = list;
      });
    },
    /**
     * 获取业务员下拉数据（employeeType === '3'）
     */
    fetchSalespersonOptions() {
      getStaffList({}).then((res) => {
        const list = (res && res.data) || [];
        this.salespersonOptions = (list || []).filter((item) => String(item.employeeType) === "3");
      });
    },
    /**
     * 获取列表（预留接口）
     */
    getList() {
      getSaleBackPage(this.queryParams).then(res => {
        this.list = res.data.records;
        this.total = res.data.total;
        this.loading = false;
      });
    },
    /**
     * 表格勾选变化
     * @param {Array} selection 选中行
     */
    handleSelectionChange(selection) {
      this.ids = (selection || []).map((r) => r.id);
      this.multiple = this.ids.length === 0;
    },
    /**
     * 查询按钮
     */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /**
     * 重置按钮
     */
    resetQuery() {
      const today = formatDateYMS(new Date().getTime() );
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        returnNum: null,
        dateRange: [today, today],
        customerNum: null,
        employeeNum: null,
        documentDateStart: today,
        documentDateEnd: today,
      };
      this.handleQuery();
    },
    /**
     * 新增（预留）
     */
    handleAdd() {
      const today = formatDateYMS(new Date().getTime());
      this.dialogTitle = "新增";
      this.dialogMode = "add";
      this.form = {
        id: null,
        documentDate: today,
        returnNum: null,
        deliveryNum: null,
        customerNum: null,
        employeeNum: null,
        remark: null,
        totalAmount: "0.00", 
        goods: [],
      };
      getLatestSaleBackNum({}).then(res => {
        this.form.returnNum = res.msg || '';
      });
      this.form.goods = [this.createEmptyDetailRow()];
      this.dialogOpen = true;
    },
    /**
     * 批量删除（预留）
     */
    handleDeleteAll() {
      /** TODO：接批量删除接口 */
      if (!this.ids.length) return;
      delSaleBack({ ids: this.ids.join(',') }).then(res => {
        this.$message.success("删除成功");
        this.getList();
      });
    },
    /**
     * 查看详情（预留）
     * @param {Object} row 当前行
     */
    handleDetail(row) {
      this.dialogTitle = "查看详情";
      this.dialogMode = "view";
      getSaleBackById({ id: row.id }).then(res => {
        const data = res.data;
        this.form = { ...data, goods: this.resolveDetailFromRow(data) };
        this.dialogOpen = true;
      });
    },
    /**
     * 编辑（预留）
     * @param {Object} row 当前行
     */
    handleEdit(row) {
      this.dialogTitle = "编辑";
      this.dialogMode = "edit";
      getSaleBackById({ id: row.id }).then(res => {
        const data = res.data;
        this.form = { ...data, goods: this.resolveDetailFromRow(data) };
        this.dialogOpen = true;
      });
    },
    /**
     * 弹框确定：先校验表头必填再提交
     */
    submitForm() {
      if (this.dialogMode === "view") return;
      this.$refs.dialogForm.validate((valid) => {
        if (!valid) return;
        if (this.dialogMode === "add") {
          addSaleBack(this.form).then(() => {
            this.$message.success("保存成功");
            this.dialogOpen = false;
            this.getList();
          });
        } else {
          editSaleBack(this.form).then(() => {
            this.$message.success("保存成功");
            this.dialogOpen = false;
            this.getList();
          });
        }
      });
    },
    /**
     * 删除（单行，预留）
     * @param {Object} row 当前行
     */
    handleDelete(row) {
      /** TODO：接删除接口 */
      this.$confirm("确定要删除这条数据吗？", "提示", { type: "warning" })
        .then(() => {
          delSaleBack({ ids: row.id }).then(res => {
            this.$message.success("删除成功");
            this.getList();
          });
        })
        .catch(() => {});
    },
  },
};
</script>

<style scoped lang="scss">
.sale-out-page {
  display: flex;
  flex-direction: column;
}

.dialog-body {
  height: calc(100vh - 140px);
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/** 表头+明细+总计同属一个 el-form，用 flex 撑满弹框高度 */
.dialog-main-form {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden;
}

.dialog-detail-body {
  height: calc(100vh - 140px);
  display: flex;
  flex-direction: column;
}

.dialog-detail-card {
  flex: 1;
  display: flex;
  flex-direction: column;
}

::v-deep .dialog-detail-card > .el-card__body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.detail-desc {
  flex-shrink: 0;
}

.dialog-table-card--detail {
  flex: 1;
  min-height: 0;
  margin-top: 12px;
}

.dialog-head-card {
  flex-shrink: 0;
}

/** 退货明细「添加明细」工具栏（与销货出库一致） */
.dialog-detail-toolbar {
  flex-shrink: 0;
}

/** 物料搜索按钮 disabled 时仍能让 tooltip 收到悬停 */
.dialog-material-query-append {
  display: inline-block;
  vertical-align: middle;
  line-height: 1;
}

.dialog-table-card {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

::v-deep .dialog-table-card > .el-card__body {
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.dialog-foot-card {
  flex-shrink: 0;
}

.total-amount-field {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sale-transfer-query-form {
  margin-bottom: 12px;
}

/** 销货转入查询表格：当前行浅蓝高亮（单选） */
::v-deep .sale-transfer-dialog .sale-transfer-table .el-table__body tr.current-row > td {
  background-color: #d9ecff !important;
}

.total-amount-label {
  font-size: 13px;
  color: #606266;
  white-space: nowrap;
}

/** 表格内嵌表单项：压缩默认下边距，避免行高过大 */
::v-deep .dialog-goods-form-item {
  margin-bottom: 0;
}

/** 单元格不裁剪，便于显示校验错误 */
::v-deep .dialog-table--with-form .el-table__cell {
  overflow: visible !important;
  vertical-align: top;
}

::v-deep .dialog-table--with-form .el-form-item__error {
  position: static !important;
  white-space: nowrap;
  line-height: 1.2;
  padding-top: 2px;
}
</style>

