<template>
  <div class="app-container supply-dashboard-page">
    <div class="page-header">
      <h2><i class="el-icon-setting"></i> &#x6743;&#x91CD;&#x914D;&#x7F6E;&#x7BA1;&#x7406;</h2>
      <p class="page-desc">&#x8C03;&#x6574;&#x4F9B;&#x5E94;&#x76D1;&#x6D4B;&#x8BC4;&#x5206;&#x5361;&#x7684;&#x7EFC;&#x5408;&#x8BC4;&#x5206;&#x6743;&#x91CD;&#x548C;&#x8BC4;&#x5206;&#x89C4;&#x5219;&#x53C2;&#x6570;</p>
    </div>

    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span><i class="el-icon-edit-outline"></i> &#x8BC4;&#x5206;&#x5361;&#x6743;&#x91CD;&#x914D;&#x7F6E;</span>
      </div>

      <el-form :model="weights" :rules="rules" ref="weightsForm" label-width="120px">
        <el-form-item :label="labels.costWeight" prop="cost">
          <el-slider v-model="weights.cost" :step="0.01" :min="0" :max="1" show-input @change="onConfigChange" />
        </el-form-item>
        <el-form-item :label="labels.deliveryWeight" prop="delivery">
          <el-slider v-model="weights.delivery" :step="0.01" :min="0" :max="1" show-input @change="onConfigChange" />
        </el-form-item>
        <el-form-item :label="labels.termWeight" prop="term">
          <el-slider v-model="weights.term" :step="0.01" :min="0" :max="1" show-input @change="onConfigChange" />
        </el-form-item>
        <el-form-item :label="labels.qualityWeight" prop="quality">
          <el-slider v-model="weights.quality" :step="0.01" :min="0" :max="1" show-input @change="onConfigChange" />
        </el-form-item>

        <el-form-item>
          <div class="weight-summary" :class="{ invalid: !isValidTotal }">
            <p>&#x7EFC;&#x5408;&#x5206; = &#x6210;&#x672C;&#x5206; x {{ percent(weights.cost) }} + &#x4EA4;&#x4ED8;&#x5206; x {{ percent(weights.delivery) }} + &#x8D26;&#x671F;&#x5206; x {{ percent(weights.term) }} + &#x8D28;&#x91CF;&#x5206; x {{ percent(weights.quality) }}</p>
            <p>&#x6743;&#x91CD;&#x603B;&#x548C;: {{ totalWeight.toFixed(2) }}</p>
            <p v-if="!isValidTotal" class="warning">&#x6743;&#x91CD;&#x603B;&#x548C;&#x5FC5;&#x987B;&#x4E3A; 1</p>
          </div>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span><i class="el-icon-data-line"></i> &#x8BC4;&#x5206;&#x89C4;&#x5219;&#x53C2;&#x6570;&#x914D;&#x7F6E;</span>
      </div>

      <div class="weight-info">
        &#x5F53;&#x524D;&#x914D;&#x7F6E;&#xFF1A;&#x6210;&#x672C; {{ percent(weights.cost) }} | &#x4EA4;&#x4ED8; {{ percent(weights.delivery) }} | &#x8D26;&#x671F; {{ percent(weights.term) }} | &#x8D28;&#x91CF; {{ percent(weights.quality) }}
      </div>

      <el-row :gutter="20" class="rule-grid">
        <el-col :xs="24" :sm="12" :lg="6">
          <div class="rule-box cost-box">
            <div class="rule-title">&#x6210;&#x672C;&#x7EF4;&#x5EA6;</div>
            <div class="rule-desc">&#x6309;&#x4EF7;&#x683C;&#x6392;&#x540D;&#x8F6C;&#x6362;&#x4E3A;&#x6210;&#x672C;&#x5206;</div>
            <div class="rule-field" v-for="item in costRuleItems" :key="item.key">
              <span>{{ item.label }}</span>
              <el-input-number v-model="scoreRules[item.key]" :min="0" :max="100" :step="1" size="mini" @change="onConfigChange" />
            </div>
          </div>
        </el-col>

        <el-col :xs="24" :sm="12" :lg="6">
          <div class="rule-box delivery-box">
            <div class="rule-title">&#x4EA4;&#x4ED8;&#x7EF4;&#x5EA6;</div>
            <div class="rule-desc">&#x8BC4;&#x5206;&#x5361;&#x5F53;&#x524D;&#x53EF;&#x8BA1;&#x7B97;&#x51C6;&#x65F6;&#x7387;&#x548C;&#x6570;&#x91CF;&#x6EE1;&#x8DB3;&#x7387;</div>
            <div class="rule-field">
              <span>D1-&#x51C6;&#x65F6;&#x7387;&#x6743;&#x91CD;</span>
              <el-input-number v-model="scoreRules.deliveryOnTimeWeight" :min="0" :max="1" :step="0.05" size="mini" @change="onConfigChange" />
            </div>
            <div class="rule-field">
              <span>D4-&#x6570;&#x91CF;&#x6EE1;&#x8DB3;&#x7387;&#x6743;&#x91CD;</span>
              <el-input-number v-model="scoreRules.deliveryFulfillmentWeight" :min="0" :max="1" :step="0.05" size="mini" @change="onConfigChange" />
            </div>
            <div class="sub-summary" :class="{ invalid: !isValidDeliveryRules }">
              &#x4EA4;&#x4ED8;&#x5B50;&#x9879;&#x603B;&#x548C;&#xFF1A;{{ deliveryRuleTotal.toFixed(2) }}
            </div>
          </div>
        </el-col>

        <el-col :xs="24" :sm="12" :lg="6">
          <div class="rule-box term-box">
            <div class="rule-title">&#x8D26;&#x671F;&#x7EF4;&#x5EA6;</div>
            <div class="rule-desc">&#x8D26;&#x671F;&#x5929;&#x6570;&#x8FBE;&#x5230;&#x9608;&#x503C;&#x540E;&#x83B7;&#x5F97;&#x5BF9;&#x5E94;&#x5206;&#x6570;</div>
            <div class="term-row" v-for="item in termRuleItems" :key="item.daysKey">
              <el-input-number v-model="scoreRules[item.daysKey]" :min="0" :step="5" size="mini" @change="onConfigChange" />
              <span>&#x5929;&#xFF1A;</span>
              <el-input-number v-model="scoreRules[item.scoreKey]" :min="0" :max="100" :step="5" size="mini" @change="onConfigChange" />
              <span>&#x5206;</span>
            </div>
            <div class="term-row">
              <span>&lt; &#x6700;&#x4F4E;&#x9608;&#x503C;&#xFF1A;</span>
              <el-input-number v-model="scoreRules.termDefaultScore" :min="0" :max="100" :step="5" size="mini" @change="onConfigChange" />
              <span>&#x5206;</span>
            </div>
          </div>
        </el-col>

        <el-col :xs="24" :sm="12" :lg="6">
          <div class="rule-box quality-box">
            <div class="rule-title">&#x8D28;&#x91CF;&#x7EF4;&#x5EA6;</div>
            <div class="rule-desc">QA&#x5408;&#x683C;&#x7387;&#x8FDB;&#x5165;&#x8D28;&#x91CF;&#x5206;&#xFF0C;&#x53EF;&#x8C03;&#x9884;&#x8B66;&#x7EBF;&#x548C;&#x7F3A;&#x7701;&#x5206;</div>
            <div class="rule-field">
              <span>QA&#x9884;&#x8B66;&#x7EBF;</span>
              <el-input-number v-model="scoreRules.qualityWarningRate" :min="0" :max="1" :step="0.01" size="mini" @change="onConfigChange" />
            </div>
            <div class="rule-field">
              <span>&#x65E0;QA&#x6570;&#x636E;&#x9ED8;&#x8BA4;&#x5206;</span>
              <el-input-number v-model="scoreRules.qualityDefaultScore" :min="0" :max="100" :step="5" size="mini" @change="onConfigChange" />
            </div>
            <div class="formula-line">&#x8D28;&#x91CF;&#x5206; = QA&#x5408;&#x683C;&#x7387; x 100</div>
            <div class="formula-line">QA&#x5408;&#x683C;&#x7387; &lt; {{ percent(scoreRules.qualityWarningRate) }} &#x89E6;&#x53D1;&#x8D28;&#x91CF;&#x9884;&#x8B66;</div>
          </div>
        </el-col>
      </el-row>

      <div class="action-row">
        <el-button type="primary" :disabled="!canSave || loading" @click="updateWeights">&#x4FDD;&#x5B58;&#x914D;&#x7F6E;</el-button>
        <el-button @click="resetWeights">&#x6062;&#x590D;&#x9ED8;&#x8BA4;</el-button>
      </div>

      <div v-if="message" class="el-alert" :class="'el-alert--' + (isError ? 'error' : 'success')">
        <div class="el-alert__content"><span class="el-alert__description">{{ message }}</span></div>
      </div>
    </el-card>
  </div>
</template>

<script>
import { getWeightsConfig, updateWeightsConfig } from '@/api/supply'

const defaultWeights = { cost: 0.30, delivery: 0.30, term: 0.15, quality: 0.25 }
const defaultScoreRules = {
  costRank1Score: 100,
  costRank2Score: 90,
  costRank3Score: 80,
  costRank4Score: 60,
  deliveryOnTimeWeight: 0.70,
  deliveryFulfillmentWeight: 0.30,
  termExcellentDays: 90,
  termGoodDays: 60,
  termNormalDays: 45,
  termShortDays: 30,
  termExcellentScore: 100,
  termGoodScore: 90,
  termNormalScore: 80,
  termShortScore: 60,
  termDefaultScore: 40,
  qualityWarningRate: 0.95,
  qualityDefaultScore: 80
}

export default {
  name: 'SupplyWeightsConfig',
  data() {
    const rule = [
      { required: true, message: '\u8bf7\u8f93\u5165\u6743\u91cd', trigger: 'blur' },
      { type: 'number', min: 0, max: 1, message: '\u6743\u91cd\u5e94\u57280\u52301\u4e4b\u95f4', trigger: 'blur' }
    ]
    return {
      weights: { ...defaultWeights },
      scoreRules: { ...defaultScoreRules },
      labels: {
        costWeight: '\u6210\u672c\u6743\u91cd',
        deliveryWeight: '\u4ea4\u4ed8\u6743\u91cd',
        termWeight: '\u8d26\u671f\u6743\u91cd',
        qualityWeight: '\u8d28\u91cf\u6743\u91cd'
      },
      costRuleItems: [
        { key: 'costRank1Score', label: '\u7b2c1\u540d' },
        { key: 'costRank2Score', label: '\u7b2c2\u540d' },
        { key: 'costRank3Score', label: '\u7b2c3\u540d' },
        { key: 'costRank4Score', label: '\u7b2c4\u540d' }
      ],
      termRuleItems: [
        { daysKey: 'termExcellentDays', scoreKey: 'termExcellentScore' },
        { daysKey: 'termGoodDays', scoreKey: 'termGoodScore' },
        { daysKey: 'termNormalDays', scoreKey: 'termNormalScore' },
        { daysKey: 'termShortDays', scoreKey: 'termShortScore' }
      ],
      loading: false,
      message: '',
      isError: false,
      rules: { cost: rule, delivery: rule, term: rule, quality: rule }
    }
  },
  computed: {
    totalWeight() {
      return this.weights.cost + this.weights.delivery + this.weights.term + this.weights.quality
    },
    isValidTotal() {
      return Math.abs(this.totalWeight - 1) <= 0.001
    },
    deliveryRuleTotal() {
      return this.scoreRules.deliveryOnTimeWeight + this.scoreRules.deliveryFulfillmentWeight
    },
    isValidDeliveryRules() {
      return Math.abs(this.deliveryRuleTotal - 1) <= 0.001
    },
    canSave() {
      return this.isValidTotal && this.isValidDeliveryRules
    }
  },
  created() {
    this.fetchWeights()
  },
  methods: {
    normalizeWeights(data) {
      const source = data && data.data ? data.data : data
      const weightsSource = source && source.weights ? source.weights : source
      return {
        cost: this.pickNumber(weightsSource, defaultWeights.cost, ['\u6210\u672c', 'cost_weight', 'costWeight', '\u6210\u672c\u6743\u91cd']),
        delivery: this.pickNumber(weightsSource, defaultWeights.delivery, ['\u4ea4\u4ed8', 'delivery_weight', 'deliveryWeight', '\u4ea4\u4ed8\u6743\u91cd']),
        term: this.pickNumber(weightsSource, defaultWeights.term, ['\u8d26\u671f', 'term_weight', 'termWeight', 'payment_weight', '\u8d26\u671f\u6743\u91cd']),
        quality: this.pickNumber(weightsSource, defaultWeights.quality, ['\u8d28\u91cf', 'quality_weight', 'qualityWeight', '\u8d28\u91cf\u6743\u91cd'])
      }
    },
    normalizeRules(data) {
      const source = data && data.data ? data.data : data
      const rulesSource = source && source.rules ? source.rules : {}
      const next = { ...defaultScoreRules }
      Object.keys(next).forEach(key => {
        next[key] = this.pickNumber(rulesSource, next[key], [key])
      })
      return next
    },
    pickNumber(source, fallback, keys) {
      if (!source) return fallback
      for (let i = 0; i < keys.length; i++) {
        const value = source[keys[i]]
        if (value !== undefined && value !== null && value !== '') {
          return Number(value)
        }
      }
      return fallback
    },
    toPayload() {
      return {
        '\u6210\u672c': this.weights.cost,
        '\u4ea4\u4ed8': this.weights.delivery,
        '\u8d26\u671f': this.weights.term,
        '\u8d28\u91cf': this.weights.quality,
        costWeight: this.weights.cost,
        deliveryWeight: this.weights.delivery,
        termWeight: this.weights.term,
        qualityWeight: this.weights.quality,
        rules: { ...this.scoreRules }
      }
    },
    async fetchWeights() {
      this.loading = true
      try {
        const response = await getWeightsConfig()
        this.weights = this.normalizeWeights(response)
        this.scoreRules = this.normalizeRules(response)
        this.message = ''
      } catch (err) {
        console.error(err)
        this.weights = { ...defaultWeights }
        this.scoreRules = { ...defaultScoreRules }
        this.message = '\u6743\u91cd\u63a5\u53e3\u6682\u65f6\u4e0d\u53ef\u7528\uff0c\u5df2\u4f7f\u7528\u9ed8\u8ba4\u914d\u7f6e'
        this.isError = false
      } finally {
        this.loading = false
      }
    },
    async updateWeights() {
      if (!this.canSave) {
        this.message = !this.isValidTotal ? '\u6743\u91cd\u603b\u548c\u5fc5\u987b\u4e3a1' : '\u4ea4\u4ed8\u5b50\u9879\u6743\u91cd\u603b\u548c\u5fc5\u987b\u4e3a1'
        this.isError = true
        this.$modal.msgError(this.message)
        return
      }
      try {
        const response = await updateWeightsConfig(this.toPayload())
        this.weights = this.normalizeWeights(response)
        this.scoreRules = this.normalizeRules(response)
        this.message = '\u914d\u7f6e\u66f4\u65b0\u6210\u529f'
        this.isError = false
        this.$modal.msgSuccess(this.message)
      } catch (err) {
        console.error(err)
        this.message = err.message || '\u914d\u7f6e\u66f4\u65b0\u5931\u8d25'
        this.isError = true
        this.$modal.msgError(this.message)
      }
    },
    resetWeights() {
      this.weights = { ...defaultWeights }
      this.scoreRules = { ...defaultScoreRules }
      this.message = ''
      this.isError = false
    },
    onConfigChange() {
      this.message = ''
      this.isError = false
    },
    percent(value) {
      return `${(Number(value || 0) * 100).toFixed(0)}%`
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container { padding: 20px; }
.page-header { margin-bottom: 20px; h2 { font-size: 24px; font-weight: 600; color: #303133; margin-bottom: 8px; i { margin-right: 8px; color: #409eff; } } .page-desc { color: #909399; font-size: 14px; margin: 0; } }
.box-card { margin-bottom: 20px; }
.weight-summary { margin: 20px 0; padding: 15px; background: #f8f9fa; border-radius: 4px; border-left: 4px solid #409eff; p { margin: 0 0 5px 0; font-size: 14px; color: #606266; } &.invalid { border-left-color: #f56c6c; } .warning { color: #f56c6c; font-weight: 500; } }
.weight-info { margin-bottom: 18px; color: #606266; font-size: 14px; }
.rule-grid { margin-bottom: 18px; }
.rule-box { padding: 18px 20px; background: #f8f9fb; border-radius: 8px; min-height: 278px; border: 1px solid #edf1f7; }
.rule-title { color: #001a45; font-size: 15px; font-weight: 600; margin-bottom: 8px; }
.rule-desc { color: #7d8aa6; font-size: 12px; line-height: 1.5; min-height: 36px; margin-bottom: 12px; }
.rule-field { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; color: #59667f; font-size: 13px; }
.term-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; color: #59667f; font-size: 13px; }
.term-row .el-input-number { width: 84px; }
.rule-field .el-input-number { width: 112px; }
.sub-summary { margin-top: 12px; padding: 8px 10px; border-radius: 6px; background: #eef6ff; color: #2468d6; font-size: 13px; }
.sub-summary.invalid { background: #fff1f0; color: #f56c6c; }
.formula-line { color: #7d8aa6; font-size: 13px; line-height: 1.7; }
.action-row { margin-top: 8px; }
.el-alert { margin-top: 15px; padding: 10px 16px; border-radius: 4px; }
</style>
