<template>
  <div class="playback-reward-page" v-loading="loading">
    <div class="tip-message">
      按客户的观看时长（仅录播）阶梯推送直播商品或商品优惠券；下一段观看时长须大于「上一段观看时长 + 显示有效时间」
    </div>

    <div class="reward-switch">
      <span class="switch-label">开启回放推送</span>
      <el-switch v-model="playbackForm.playbackEnabled"></el-switch>
    </div>

    <div v-if="playbackForm.playbackEnabled" class="section-block">
      <div class="section-title">观看时长推送阶梯</div>

      <div class="rule-table-wrap">
        <el-table
          :data="playbackForm.playbackPushRules"
          border
          class="rule-table"
          style="width: 100%;"
        >
          <el-table-column label="阶段" width="100" align="center">
            <template slot-scope="scope">
              第{{ scope.$index + 1 }}段
            </template>
          </el-table-column>

          <el-table-column label="观看时长(分钟)" width="280">
            <template slot-scope="scope">
              <div class="cell-inline">
                <el-input-number
                  v-model="scope.row.watchDuration"
                  :min="getMinWatchDuration(scope.$index)"
                  :precision="0"
                  :step="1"
                  controls-position="right"
                  style="width: 140px;"
                  @change="onWatchDurationChange(scope.$index)"
                />
                <span v-if="scope.$index > 0" class="hint-text">
                  须大于{{ getPrevThreshold(scope.$index) }}分钟
                  <el-popover
                    placement="top"
                    trigger="click"
                    width="260"
                    content="须大于上一段观看时长+显示有效时间"
                  >
                    <i slot="reference" class="el-icon-warning-outline hint-icon" />
                  </el-popover>
                </span>
              </div>
            </template>
          </el-table-column>

          <el-table-column label="推送内容" width="220">
            <template slot-scope="scope">
              <el-select
                v-model="scope.row.pushType"
                style="width: 180px;"
                @change="onPushTypeChange(scope.row)"
              >
                <el-option label="直播商品" value="1" />
                <el-option label="直播商品优惠券" value="2" />
              </el-select>
            </template>
          </el-table-column>

          <el-table-column label="选择商品/优惠券" min-width="360">
            <template slot-scope="scope">
              <el-select
                :key="'target-' + scope.$index + '-' + scope.row.pushType"
                v-model="scope.row.targetId"
                filterable
                clearable
                :placeholder="scope.row.pushType === '2' ? '请选择优惠券' : '请选择直播商品'"
                style="width: 100%; max-width: 420px;"
              >
                <el-option
                  v-for="item in (scope.row.pushType === '2' ? couponList : goodsList)"
                  :key="scope.row.pushType === '2' ? item.couponId : item.goodsId"
                  :label="scope.row.pushType === '2'
                    ? ((item.title || '未命名') + ' (' + item.couponId + ')')
                    : ((item.productName || '未命名') + ' (' + item.goodsId + ')')"
                  :value="scope.row.pushType === '2' ? item.couponId : item.goodsId"
                />
              </el-select>
            </template>
          </el-table-column>

          <el-table-column label="显示有效时间(分钟)" width="220">
            <template slot-scope="scope">
              <el-input-number
                v-model="scope.row.displayDuration"
                :min="1"
                :precision="0"
                :step="1"
                controls-position="right"
                style="width: 140px;"
                @change="onDisplayDurationChange(scope.$index)"
              />
            </template>
          </el-table-column>

          <el-table-column label="操作" width="100" align="center">
            <template slot-scope="scope">
              <el-button
                v-if="playbackForm.playbackPushRules.length > 1"
                type="text"
                class="rule-remove"
                @click="removeRule(scope.$index)"
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="table-actions">
        <el-button type="primary" icon="el-icon-plus" @click="addRule">
          添加下一段
        </el-button>
      </div>

      <div v-if="ruleError" class="rule-error">{{ ruleError }}</div>

      <div class="form-actions">
        <el-button type="primary" @click="savePlaybackReward">保存</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { addConfig, getConfig, updateConfig } from "@/api/live/liveQuestionLive";
import { listLiveGoods } from "@/api/live/liveGoods";
import { listLiveCoupon } from "@/api/live/liveCoupon";

const PLAYBACK_FIELD_KEYS = [
  'playbackEnabled',
  'playbackPushTiming',
  'playbackPushRules'
];

function createDefaultRule() {
  return {
    watchDuration: 10,
    pushType: '1',
    targetId: null,
    displayDuration: 5
  };
}

function createDefaultPlaybackForm() {
  return {
    id: null,
    liveId: null,
    playbackEnabled: false,
    // 固定：达到指定观看时长后推送
    playbackPushTiming: '2',
    playbackPushRules: [createDefaultRule()]
  };
}

export default {
  name: 'PlaybackReward',
  data() {
    return {
      loading: true,
      liveId: null,
      configCache: {},
      playbackForm: createDefaultPlaybackForm(),
      goodsList: [],
      couponList: [],
      ruleError: ''
    };
  },
  watch: {
    '$route.query': {
      handler() {
        this.liveId = this.$route.params.liveId;
        this.playbackForm.liveId = this.liveId;
        if (this.liveId == null) {
          return;
        }
        this.loadOptions();
        this.getLiveConfig();
      },
      immediate: true
    },
    'playbackForm.playbackEnabled': {
      handler(newValue, oldValue) {
        if (oldValue === true && newValue === false && this.liveId) {
          this.autoSaveEnabled();
        }
      }
    }
  },
  methods: {
    createDefaultRule,
    getPrevThreshold(index) {
      if (index <= 0) {
        return 0;
      }
      const prev = this.playbackForm.playbackPushRules[index - 1];
      const watch = Number(prev.watchDuration) || 0;
      const display = Number(prev.displayDuration) || 0;
      return watch + display;
    },
    getMinWatchDuration(index) {
      if (index <= 0) {
        return 1;
      }
      return this.getPrevThreshold(index) + 1;
    },
    onWatchDurationChange(index) {
      this.validateRulesChain(index);
    },
    onDisplayDurationChange(index) {
      this.validateRulesChain(index);
    },
    onPushTypeChange(rule) {
      rule.targetId = null;
    },
    validateRulesChain(fromIndex) {
      const rules = this.playbackForm.playbackPushRules;
      for (let i = Math.max(1, fromIndex + 1); i < rules.length; i++) {
        const min = this.getMinWatchDuration(i);
        if (Number(rules[i].watchDuration) < min) {
          this.$set(rules[i], 'watchDuration', min);
        }
      }
      this.ruleError = this.getRuleValidationError() || '';
    },
    getRuleValidationError() {
      const rules = this.playbackForm.playbackPushRules || [];
      if (!rules.length) {
        return '请至少配置一段推送规则';
      }
      for (let i = 0; i < rules.length; i++) {
        const rule = rules[i];
        if (rule.watchDuration == null || rule.watchDuration === '' || Number(rule.watchDuration) <= 0) {
          return `请填写第 ${i + 1} 段观看时长`;
        }
        if (!rule.pushType) {
          return `请选择第 ${i + 1} 段推送内容`;
        }
        if (rule.targetId == null || rule.targetId === '') {
          return `请选择第 ${i + 1} 段${rule.pushType === '2' ? '优惠券' : '商品'}`;
        }
        if (rule.displayDuration == null || rule.displayDuration === '' || Number(rule.displayDuration) <= 0) {
          return `请填写第 ${i + 1} 段显示有效时间`;
        }
        if (i > 0) {
          const threshold = this.getPrevThreshold(i);
          if (Number(rule.watchDuration) <= threshold) {
            return `第 ${i + 1} 段观看时长须大于 ${threshold} 分钟（上一段观看时长 + 显示有效时间）`;
          }
        }
      }
      return '';
    },
    addRule() {
      const rules = this.playbackForm.playbackPushRules;
      const nextMin = this.getMinWatchDuration(rules.length);
      rules.push({
        watchDuration: nextMin,
        pushType: '1',
        targetId: null,
        displayDuration: 5
      });
      this.ruleError = '';
    },
    removeRule(index) {
      this.playbackForm.playbackPushRules.splice(index, 1);
      this.validateRulesChain(0);
    },
    loadOptions() {
      if (!this.liveId) {
        return;
      }
      listLiveGoods({ liveId: this.liveId, pageNum: 1, pageSize: 999 }).then(res => {
        this.goodsList = res.rows || [];
      });
      listLiveCoupon({ liveId: this.liveId, pageNum: 1, pageSize: 999 }).then(res => {
        this.couponList = res.rows || [];
      });
    },
    pickPlaybackFields(source) {
      const result = {};
      PLAYBACK_FIELD_KEYS.forEach(key => {
        if (source[key] !== undefined) {
          result[key] = source[key];
        }
      });
      return result;
    },
    normalizeRules(rules) {
      if (!Array.isArray(rules) || rules.length === 0) {
        return [createDefaultRule()];
      }
      return rules.map(item => ({
        watchDuration: item.watchDuration != null ? Number(item.watchDuration) : 10,
        pushType: item.pushType != null ? String(item.pushType) : '1',
        targetId: item.targetId != null ? item.targetId : null,
        displayDuration: item.displayDuration != null ? Number(item.displayDuration) : 5
      }));
    },
    buildSubmitData() {
      const playbackFields = this.pickPlaybackFields(this.playbackForm);
      playbackFields.playbackPushTiming = '2';
      playbackFields.playbackPushRules = this.normalizeRules(this.playbackForm.playbackPushRules);
      return Object.assign({}, this.configCache, playbackFields, {
        id: this.playbackForm.id != null ? this.playbackForm.id : this.configCache.id,
        liveId: this.liveId
      });
    },
    getLiveConfig() {
      this.loading = true;
      getConfig(this.liveId).then(response => {
        const defaults = createDefaultPlaybackForm();
        defaults.liveId = this.liveId;
        if (response.code === 200 && response.data != null && response.data.length > 0) {
          const serverData = JSON.parse(response.data);
          this.configCache = Object.assign({}, serverData);
          const playbackFields = this.pickPlaybackFields(serverData);
          this.playbackForm = Object.assign({}, defaults, playbackFields, {
            id: serverData.id != null ? serverData.id : null,
            liveId: this.liveId,
            playbackPushTiming: '2',
            playbackPushRules: this.normalizeRules(playbackFields.playbackPushRules)
          });
        } else {
          this.configCache = {};
          this.playbackForm = defaults;
        }
        this.ruleError = '';
        this.loading = false;
      }).catch(() => {
        this.loading = false;
      });
    },
    autoSaveEnabled() {
      const submitData = this.buildSubmitData();
      const req = this.playbackForm.id == null
        ? addConfig(submitData, this.liveId)
        : updateConfig(submitData, this.liveId);
      req.then(res => {
        if (res.code == 200) {
          this.msgSuccess('已关闭回放推送');
          if (res.data && res.data.id) {
            this.playbackForm.id = res.data.id;
            this.configCache.id = res.data.id;
          }
          this.configCache = Object.assign({}, this.configCache, this.pickPlaybackFields(this.playbackForm));
        }
      }).catch(() => {
        this.playbackForm.playbackEnabled = true;
      });
    },
    savePlaybackReward() {
      const error = this.getRuleValidationError();
      if (error) {
        this.ruleError = error;
        this.$message.error(error);
        return;
      }
      this.ruleError = '';
      const submitData = this.buildSubmitData();
      const req = this.playbackForm.id == null
        ? addConfig(submitData, this.liveId)
        : updateConfig(submitData, this.liveId);
      req.then(res => {
        if (res.code == 200) {
          this.msgSuccess('修改成功');
          if (res.data && res.data.id) {
            this.playbackForm.id = res.data.id;
          }
          this.configCache = Object.assign({}, submitData);
        }
      });
    }
  }
};
</script>

<style scoped>
.playback-reward-page {
  min-height: 100%;
  padding-bottom: 40px;
}

.tip-message {
  padding: 12px 16px;
  background-color: #FFF6F2;
  border-radius: 4px;
  color: #666;
  font-size: 14px;
  margin-bottom: 20px;
}

.reward-switch {
  margin-left: 200px;
  margin-bottom: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  display: flex;
  align-items: center;
}

.reward-switch .switch-label {
  margin-right: 10px;
  font-size: 14px;
  color: #333;
  margin-left: 50px;
}

.section-block {
  background-color: #fff;
  padding: 24px;
  border-radius: 4px;
  margin-left: 20px;
  margin-right: 20px;
  margin-bottom: 20px;
  box-sizing: border-box;
}

.section-block .section-title {
  font-size: 16px;
  color: #333;
  margin-bottom: 20px;
  border-left: 4px solid #409EFF;
  padding-left: 10px;
  line-height: 1;
}

.rule-table-wrap {
  width: 100%;
  overflow-x: auto;
}

.rule-table {
  margin-bottom: 16px;
  font-size: 14px;
}

.rule-table >>> .el-table__header th {
  font-size: 14px;
  padding: 12px 0;
  background: #f5f7fa;
}

.rule-table >>> .el-table__body td {
  padding: 14px 0;
}

.rule-table >>> .el-input__inner,
.rule-table >>> .el-input-number {
  font-size: 14px;
}

.cell-inline {
  display: flex;
  align-items: center;
  gap: 8px;
}

.hint-text {
  color: #909399;
  font-size: 13px;
  white-space: nowrap;
}

.hint-icon {
  margin-left: 4px;
  color: #E6A23C;
  cursor: pointer;
  font-size: 14px;
  vertical-align: middle;
}

.rule-remove {
  color: #F56C6C !important;
  font-size: 14px;
}

.table-actions {
  margin-bottom: 12px;
}

.rule-error {
  color: #F56C6C;
  font-size: 14px;
  margin-top: 10px;
}

.form-actions {
  text-align: center;
  margin-top: 28px;
}

.form-actions .el-button {
  padding: 10px 28px;
  font-size: 14px;
}
</style>
