<template>
  <div class="app-container">
    <!-- 检索区 -->
    <el-card shadow="never" class="search-card">
      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
        <el-form-item label="模版名称" prop="keyword">
          <el-input v-model="queryParams.keyword" placeholder="输入模版名称" clearable style="width: 220px" @keyup.enter.native="handleQuery" />
        </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-card>

    <br/>

    <!-- 列表区 -->
    <el-card shadow="never" class="table-card">
      <el-row :gutter="10" class="mb8">
        <el-col :span="1.5">
          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['agri:seller:freightTemplate:add']">添加运费模版</el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete()" v-hasPermi="['agri:seller:freightTemplate:remove']">批量删除</el-button>
        </el-col>
        <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
      </el-row>

      <el-table border v-loading="loading" :data="templateList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="模版名称" align="left" prop="templateName" min-width="140" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span>{{ scope.row.templateName || '—' }}</span>
            <el-tag v-if="scope.row.isDefault === '1'" size="mini" type="warning" class="default-tag">默认</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="是否包邮" align="center" width="90">
          <template slot-scope="scope">
            <span>{{ freeFlagLabel(scope.row.freeFlag) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="计价方式" align="center" width="100">
          <template slot-scope="scope">
            <span>{{ scope.row.pricingTypeLabel || (scope.row.freeFlag === '1' ? '—' : '—') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="发货时间" align="center" prop="shipTime" min-width="130" :show-overflow-tooltip="true" />
        <el-table-column label="是否默认" align="center" width="90">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.isDefault === '1'" type="success" size="small">是</el-tag>
            <span v-else>否</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="220" fixed="right">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-star-off"
              :disabled="scope.row.isDefault === '1'"
              @click="handleSetDefault(scope.row)"
              v-hasPermi="['agri:seller:freightTemplate:edit']"
            >设为默认</el-button>
            <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['agri:seller:freightTemplate:edit']">编辑</el-button>
            <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['agri:seller:freightTemplate:remove']">删除</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" width="920px" append-to-body top="5vh" @close="cancelForm">
      <el-form ref="form" :model="form" :rules="rules" label-width="110px" class="freight-form">
        <el-form-item label="模版名称" prop="templateName">
          <el-input v-model="form.templateName" placeholder="请输入模版名称" maxlength="64" />
        </el-form-item>
        <el-form-item label="发货时间" prop="shipTime">
          <el-select v-model="form.shipTime" filterable allow-create default-first-option placeholder="请选择或输入发货承诺" style="width: 100%">
            <el-option v-for="item in shipTimeOptions" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item label="设为默认">
          <el-checkbox v-model="form.isDefault">设为默认运费模版</el-checkbox>
          <div class="form-tip">同店至多一个默认；发品时将自动预填该模版</div>
        </el-form-item>
        <el-form-item label="是否包邮" prop="freeFlag">
          <el-radio-group v-model="form.freeFlag">
            <el-radio label="1">包邮</el-radio>
            <el-radio label="0">不包邮</el-radio>
          </el-radio-group>
        </el-form-item>

        <template v-if="form.freeFlag === '0'">
          <el-form-item label="计价方式" prop="pricingType">
            <el-radio-group v-model="form.pricingType">
              <el-radio label="1">按件数</el-radio>
              <el-radio label="2">按重量</el-radio>
            </el-radio-group>
          </el-form-item>

          <div class="section-title">运送方式 · 默认（全国）</div>
          <el-row :gutter="16" class="rule-row">
            <el-col :span="12">
              <el-form-item :label="firstUnitLabel" prop="defaultRule.firstUnit">
                <el-input-number v-model="form.defaultRule.firstUnit" :min="0.01" :precision="pricingPrecision" :step="1" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="首费(元)" prop="defaultRule.firstFee">
                <el-input-number v-model="form.defaultRule.firstFee" :min="0" :precision="2" :step="1" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="addUnitLabel" prop="defaultRule.addUnit">
                <el-input-number v-model="form.defaultRule.addUnit" :min="0.01" :precision="pricingPrecision" :step="1" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="续费(元)" prop="defaultRule.addFee">
                <el-input-number v-model="form.defaultRule.addFee" :min="0" :precision="2" :step="1" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="满免(元)">
                <el-input-number v-model="form.defaultRule.freeThreshold" :min="0" :precision="2" :step="1" controls-position="right" placeholder="不填表示不启用" style="width: 100%" />
              </el-form-item>
            </el-col>
          </el-row>

          <div class="section-title">
            指定地区运费
            <el-button type="text" icon="el-icon-plus" @click="addRegionRule">添加地区规则</el-button>
          </div>
          <div v-if="!form.regionRules.length" class="empty-tip">未配置时全部地区使用全国默认规则</div>
          <div v-for="(rule, index) in form.regionRules" :key="'region-' + index" class="region-block">
            <div class="region-head">
              <span class="region-label">地区 {{ index + 1 }}</span>
              <el-button type="text" icon="el-icon-delete" @click="removeRegionRule(index)">删除</el-button>
            </div>
            <el-form-item label="选择省份" :prop="'regionRules.' + index + '.provinceIds'" :rules="regionProvinceRules">
              <el-select
                v-model="rule.provinceIds"
                multiple
                filterable
                collapse-tags
                placeholder="请选择省份（可多选）"
                style="width: 100%"
              >
                <el-option
                  v-for="item in provinceOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                  :disabled="isProvinceDisabled(item.id, index)"
                />
              </el-select>
            </el-form-item>
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item :label="firstUnitLabel">
                  <el-input-number v-model="rule.firstUnit" :min="0.01" :precision="pricingPrecision" :step="1" controls-position="right" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="首费(元)">
                  <el-input-number v-model="rule.firstFee" :min="0" :precision="2" :step="1" controls-position="right" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item :label="addUnitLabel">
                  <el-input-number v-model="rule.addUnit" :min="0.01" :precision="pricingPrecision" :step="1" controls-position="right" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="续费(元)">
                  <el-input-number v-model="rule.addFee" :min="0" :precision="2" :step="1" controls-position="right" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="满免(元)">
                  <el-input-number v-model="rule.freeThreshold" :min="0" :precision="2" :step="1" controls-position="right" placeholder="不填表示不启用" style="width: 100%" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </template>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">保 存</el-button>
        <el-button @click="cancelForm">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listFreightTemplate,
  getFreightTemplate,
  addFreightTemplate,
  updateFreightTemplate,
  setDefaultFreightTemplate,
  delFreightTemplate
} from "@/api/agri/seller/freightTemplate"
import { getRegionTree } from "@/api/agri/region"
import { getSellerContext } from "@/api/agri/seller/context"
import { setSellerShopContext } from "@/utils/sellerShop"

export default {
  name: "AgriSellerFreightTemplate",
  data() {
    return {
      loading: true,
      ids: [],
      multiple: true,
      showSearch: true,
      total: 0,
      templateList: [],
      dialogOpen: false,
      dialogTitle: "",
      provinceOptions: [],
      shipTimeOptions: ["24小时内发货", "48小时内发货", "72小时内发货"],
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        keyword: undefined
      },
      form: {},
      rules: {
        templateName: [{ required: true, message: "请输入模版名称", trigger: "blur" }],
        shipTime: [{ required: true, message: "请选择或输入发货时间", trigger: "change" }],
        freeFlag: [{ required: true, message: "请选择是否包邮", trigger: "change" }],
        pricingType: [{ required: true, message: "请选择计价方式", trigger: "change" }],
        "defaultRule.firstUnit": [{ required: true, message: "请填写首段计量", trigger: "blur" }],
        "defaultRule.firstFee": [{ required: true, message: "请填写首费", trigger: "blur" }],
        "defaultRule.addUnit": [{ required: true, message: "请填写续段计量", trigger: "blur" }],
        "defaultRule.addFee": [{ required: true, message: "请填写续费", trigger: "blur" }]
      },
      regionProvinceRules: [{ required: true, type: "array", min: 1, message: "请至少选择一个省份", trigger: "change" }]
    }
  },
  computed: {
    firstUnitLabel() {
      return this.form.pricingType === "2" ? "首重(kg)" : "首件数"
    },
    addUnitLabel() {
      return this.form.pricingType === "2" ? "续重(kg)" : "续件数"
    },
    pricingPrecision() {
      return this.form.pricingType === "2" ? 2 : 0
    }
  },
  created() {
    this.initPage()
    this.loadProvinceOptions()
  },
  methods: {
    initPage() {
      this.loadShopContext().then(() => {
        this.getList()
      }).catch(() => {
        this.getList()
      })
    },
    loadShopContext() {
      return getSellerContext().then(response => {
        const data = response.data || {}
        if (data.shopId != null) {
          setSellerShopContext(data.shopId, data.shopName)
        }
      })
    },
    loadProvinceOptions() {
      getRegionTree().then(response => {
        const roots = response.data || []
        this.provinceOptions = roots
          .filter(item => item.type === 1 || item.type == null)
          .map(item => ({ id: item.id, name: item.name }))
      }).catch(() => {
        this.provinceOptions = []
      })
    },
    getList() {
      this.loading = true
      listFreightTemplate(this.queryParams).then(response => {
        this.templateList = response.rows || []
        this.total = response.total || 0
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    freeFlagLabel(flag) {
      if (flag === "1") return "是"
      if (flag === "0") return "否"
      return "—"
    },
    createEmptyRule() {
      return {
        firstUnit: 1,
        firstFee: 0,
        addUnit: 1,
        addFee: 0,
        freeThreshold: undefined
      }
    },
    createEmptyRegionRule() {
      return {
        provinceIds: [],
        ...this.createEmptyRule()
      }
    },
    resetFormData() {
      this.form = {
        templateId: undefined,
        templateName: undefined,
        shipTime: undefined,
        isDefault: false,
        freeFlag: "0",
        pricingType: "1",
        defaultRule: this.createEmptyRule(),
        regionRules: []
      }
      this.resetForm("form")
    },
    mapDetailToForm(data) {
      const defaultRule = data.defaultRule || this.createEmptyRule()
      const regionRules = (data.regionRules || []).map(item => ({
        provinceIds: item.provinceIds ? [...item.provinceIds] : [],
        firstUnit: item.firstUnit != null ? item.firstUnit : 1,
        firstFee: item.firstFee != null ? item.firstFee : 0,
        addUnit: item.addUnit != null ? item.addUnit : 1,
        addFee: item.addFee != null ? item.addFee : 0,
        freeThreshold: item.freeThreshold
      }))
      return {
        templateId: data.templateId,
        templateName: data.templateName,
        shipTime: data.shipTime,
        isDefault: data.isDefault === "1",
        freeFlag: data.freeFlag || "0",
        pricingType: data.pricingType || "1",
        defaultRule: {
          firstUnit: defaultRule.firstUnit != null ? defaultRule.firstUnit : 1,
          firstFee: defaultRule.firstFee != null ? defaultRule.firstFee : 0,
          addUnit: defaultRule.addUnit != null ? defaultRule.addUnit : 1,
          addFee: defaultRule.addFee != null ? defaultRule.addFee : 0,
          freeThreshold: defaultRule.freeThreshold
        },
        regionRules: regionRules
      }
    },
    isProvinceDisabled(provinceId, currentIndex) {
      for (let i = 0; i < this.form.regionRules.length; i++) {
        if (i === currentIndex) {
          continue
        }
        const ids = this.form.regionRules[i].provinceIds || []
        if (ids.indexOf(provinceId) !== -1) {
          return true
        }
      }
      return false
    },
    addRegionRule() {
      this.form.regionRules.push(this.createEmptyRegionRule())
    },
    removeRegionRule(index) {
      this.form.regionRules.splice(index, 1)
    },
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    resetQuery() {
      this.resetForm("queryForm")
      this.handleQuery()
    },
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.templateId)
      this.multiple = !selection.length
    },
    handleAdd() {
      this.resetFormData()
      this.dialogOpen = true
      this.dialogTitle = "添加运费模版"
    },
    handleUpdate(row) {
      this.resetFormData()
      getFreightTemplate(row.templateId).then(response => {
        this.form = this.mapDetailToForm(response.data || {})
        this.dialogOpen = true
        this.dialogTitle = "编辑运费模版"
      })
    },
    handleSetDefault(row) {
      if (row.isDefault === "1") {
        return
      }
      this.$modal.confirm('确认将「' + row.templateName + '」设为默认运费模版？').then(() => {
        return setDefaultFreightTemplate(row.templateId)
      }).then(() => {
        this.$modal.msgSuccess("设置成功")
        this.getList()
      }).catch(() => {})
    },
    validateRuleBlock(rule, label) {
      if (rule.firstUnit == null || Number(rule.firstUnit) <= 0) {
        this.$modal.msgWarning(label + "：首段计量须大于 0")
        return false
      }
      if (rule.addUnit == null || Number(rule.addUnit) <= 0) {
        this.$modal.msgWarning(label + "：续段计量须大于 0")
        return false
      }
      if (rule.firstFee == null || Number(rule.firstFee) < 0) {
        this.$modal.msgWarning(label + "：首费不能为负数")
        return false
      }
      if (rule.addFee == null || Number(rule.addFee) < 0) {
        this.$modal.msgWarning(label + "：续费不能为负数")
        return false
      }
      if (rule.freeThreshold != null && rule.freeThreshold !== "" && Number(rule.freeThreshold) <= 0) {
        this.$modal.msgWarning(label + "：满免阈值须大于 0")
        return false
      }
      return true
    },
    buildSubmitPayload() {
      const payload = {
        templateId: this.form.templateId,
        templateName: (this.form.templateName || "").trim(),
        shipTime: (this.form.shipTime || "").trim(),
        isDefault: this.form.isDefault ? "1" : "0",
        freeFlag: this.form.freeFlag
      }
      if (payload.freeFlag === "1") {
        return payload
      }
      if (!this.validateRuleBlock(this.form.defaultRule, "全国默认")) {
        return null
      }
      payload.pricingType = this.form.pricingType
      payload.defaultRule = {
        firstUnit: this.form.defaultRule.firstUnit,
        firstFee: this.form.defaultRule.firstFee,
        addUnit: this.form.defaultRule.addUnit,
        addFee: this.form.defaultRule.addFee,
        freeThreshold: this.form.defaultRule.freeThreshold || undefined
      }
      const regionRules = []
      for (let i = 0; i < this.form.regionRules.length; i++) {
        const row = this.form.regionRules[i]
        if (!row.provinceIds || !row.provinceIds.length) {
          continue
        }
        if (!this.validateRuleBlock(row, "指定地区 " + (i + 1))) {
          return null
        }
        regionRules.push({
          provinceIds: row.provinceIds,
          firstUnit: row.firstUnit,
          firstFee: row.firstFee,
          addUnit: row.addUnit,
          addFee: row.addFee,
          freeThreshold: row.freeThreshold || undefined
        })
      }
      payload.regionRules = regionRules
      return payload
    },
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (!valid) {
          return
        }
        const payload = this.buildSubmitPayload()
        if (!payload) {
          return
        }
        const submitFn = payload.templateId != null ? updateFreightTemplate : addFreightTemplate
        submitFn(payload).then(() => {
          this.$modal.msgSuccess(payload.templateId != null ? "修改成功" : "添加成功")
          this.dialogOpen = false
          this.getList()
        })
      })
    },
    cancelForm() {
      this.dialogOpen = false
      this.resetFormData()
    },
    handleDelete(row) {
      const templateIds = row && row.templateId ? row.templateId : this.ids
      if (!templateIds || (Array.isArray(templateIds) && !templateIds.length)) {
        return
      }
      const idStr = Array.isArray(templateIds) ? templateIds.join(",") : templateIds
      this.$modal.confirm("确认删除所选运费模版？已被商品引用的模版无法删除。").then(() => {
        return delFreightTemplate(idStr)
      }).then(() => {
        this.$modal.msgSuccess("删除成功")
        this.getList()
      }).catch(() => {})
    }
  }
}
</script>

<style scoped lang="scss">
.default-tag {
  margin-left: 6px;
}
.freight-form {
  max-height: 65vh;
  overflow-y: auto;
  padding-right: 8px;
}
.section-title {
  font-weight: 600;
  color: #303133;
  margin: 12px 0 8px;
  padding-left: 8px;
  border-left: 3px solid #409EFF;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.rule-row {
  margin-bottom: 4px;
}
.region-block {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 12px 12px 4px;
  margin-bottom: 12px;
  background: #fafafa;
}
.region-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.region-label {
  font-weight: 600;
  color: #606266;
}
.form-tip,
.empty-tip {
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
}
.empty-tip {
  margin-bottom: 12px;
}
</style>
