<template>
  <div class="rule-builder">
    <div class="toolbar">
      <span class="rule-tip">规则组之间为 <b>且</b>；组内关系可切换 且/或</span>
      <el-button
        v-if="!readonly"
        type="primary"
        size="small"
        plain
        @click="addGroup"
      ><el-icon><Plus /></el-icon>新增规则组</el-button>
    </div>

    <div
      v-for="(group, gIndex) in groups"
      :key="group.id"
      class="rule-group"
    >
      <div class="group-header">
        <div class="group-title">
          <span class="group-no">规则组 {{ gIndex + 1 }}</span>
          <span class="group-logic">
            组内关系：
            <el-radio-group
              v-model="group.logic"
              size="small"
              :disabled="readonly"
            >
              <el-radio-button label="AND">且</el-radio-button>
              <el-radio-button label="OR">或</el-radio-button>
            </el-radio-group>
          </span>
        </div>
        <div v-if="!readonly" class="group-actions">
          <el-button size="small" @click="copyGroup(gIndex)"><el-icon><DocumentCopy /></el-icon>复制</el-button>
          <el-button
            size="small"
            type="danger"
            plain
            :disabled="groups.length <= 1"
            @click="removeGroup(gIndex)"
          ><el-icon><Delete /></el-icon>删除</el-button>
        </div>
      </div>

      <div class="rule-list">
        <div
          v-for="(rule, rIndex) in group.rules"
          :key="rule.id"
          class="rule-row"
        >
          <span class="rule-no">{{ rIndex + 1 }}</span>

          <!-- 参数选择 -->
          <el-select
            v-model="rule.paramKey"
            placeholder="选择参数"
            filterable
            size="small"
            style="width: 240px"
            :disabled="readonly"
            @change="onParamChange(rule)"
          >
            <el-option-group
              v-for="grp in paramGroups"
              :key="grp.key"
              :label="grp.label"
            >
              <el-option
                v-for="p in grp.params"
                :key="p.key"
                :label="p.label"
                :value="p.key"
              />
            </el-option-group>
          </el-select>

          <!-- 时间窗口（仅历史值参数显示） -->
          <template v-if="showTimeWindow(rule)">
            <el-select
              v-model="rule.timeWindow.mode"
              size="small"
              style="width: 120px"
              :disabled="readonly"
              @change="onTimeModeChange(rule)"
            >
              <el-option
                v-for="m in timeWindowModes"
                :key="m.value"
                :label="m.label"
                :value="m.value"
              />
            </el-select>

            <el-date-picker
              v-if="rule.timeWindow.mode === 'specificMonth'"
              v-model="rule.timeWindow.month"
              type="month"
              size="small"
              style="width: 140px"
              placeholder="选择月份"
              value-format="YYYY-MM"
              :disabled="readonly"
            />

            <template v-if="rule.timeWindow.mode === 'recentMonths'">
              <el-input-number
                v-model="rule.timeWindow.n"
                :min="1"
                :max="12"
                size="small"
                style="width: 110px"
                :disabled="readonly"
              />
              <span class="inline-label">个月</span>
              <el-select
                v-model="rule.timeWindow.aggregator"
                size="small"
                style="width: 140px"
                :disabled="readonly"
              >
                <el-option
                  v-for="a in aggregatorsFor(rule)"
                  :key="a.value"
                  :label="a.label"
                  :value="a.value"
                />
              </el-select>
              <el-input-number
                v-if="rule.timeWindow.aggregator === 'atLeast'"
                v-model="rule.timeWindow.m"
                :min="1"
                :max="rule.timeWindow.n || 12"
                size="small"
                style="width: 90px"
                :disabled="readonly"
              />
              <span v-if="rule.timeWindow.aggregator === 'atLeast'" class="inline-label">个月</span>
            </template>
          </template>

          <!-- 运算符 -->
          <el-select
            v-model="rule.operator"
            size="small"
            style="width: 140px"
            placeholder="运算符"
            :disabled="!rule.paramKey || readonly"
            @change="onOperatorChange(rule)"
          >
            <el-option
              v-for="op in operatorsFor(rule)"
              :key="op.value"
              :label="op.label"
              :value="op.value"
            />
          </el-select>

          <!-- 比较值：根据 operator & param 动态切换 -->
          <component
            :is="valueComponentFor(rule).is"
            v-if="needValue(rule)"
            v-bind="valueComponentFor(rule).props"
            v-model="rule.value"
            :disabled="readonly"
          >
            <template v-if="valueComponentFor(rule).options">
              <el-option
                v-for="opt in valueComponentFor(rule).options"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              />
            </template>
          </component>

          <!-- 区间 value2 -->
          <template v-if="rule.operator === 'between' && needValue(rule)">
            <span class="inline-label">～</span>
            <component
              :is="valueComponentFor(rule).is"
              v-bind="valueComponentFor(rule).props"
              v-model="rule.value2"
              :disabled="readonly"
            />
          </template>

          <!-- 相对日期：N 日/月/年内 -->
          <template v-if="['withinLast', 'beforeLast'].includes(rule.operator)">
            <el-select
              v-model="rule.unit"
              size="small"
              style="width: 90px"
              :disabled="readonly"
            >
              <el-option label="日" value="day" />
              <el-option label="月" value="month" />
              <el-option label="年" value="year" />
            </el-select>
          </template>

          <!-- 删除规则按钮 -->
          <el-button
            v-if="!readonly"
            class="rule-delete"
            size="small"
            type="text"
            :disabled="group.rules.length <= 1"
            @click="removeRule(gIndex, rIndex)"
          ><el-icon><Close /></el-icon></el-button>
        </div>

        <div v-if="!readonly" class="rule-add">
          <el-button
            size="small"
            plain
            @click="addRule(gIndex)"
          ><el-icon><Plus /></el-icon>新增规则</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ElMessageBox } from 'element-plus'
import {
  PARAM_GROUPS,
  PARAM_MAP,
  PARAM_TYPE,
  TIME_WINDOW_MODES,
  AGGREGATORS_ENUM,
  AGGREGATORS_NUMBER,
  BOOLEAN_OPTIONS,
  getOperatorsByParam,
  needTimeWindow,
  needValueInput
} from '@/config/tagParams'

let uid = 0
const nextId = () => `rb_${Date.now()}_${uid++}`

function makeEmptyRule() {
  return {
    id: nextId(),
    paramKey: '',
    timeWindow: {
      mode: 'current',
      month: '',
      n: 3,
      m: 1,
      aggregator: 'any'
    },
    operator: '',
    value: '',
    value2: '',
    unit: 'day'
  }
}

function makeEmptyGroup() {
  return {
    id: nextId(),
    logic: 'AND',
    rules: [makeEmptyRule()]
  }
}

export default {
  name: 'RuleBuilder',
  props: {
    modelValue: {
      type: Array,
      default: () => []
    },
    readonly: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:modelValue', 'change'],
  data() {
    return {
      paramGroups: PARAM_GROUPS,
      timeWindowModes: TIME_WINDOW_MODES,
      groups: []
    }
  },
  created() {
    if (this.modelValue && this.modelValue.length) {
      this.groups = this.cloneGroups(this.modelValue)
    } else {
      this.groups = [makeEmptyGroup()]
    }
    // 初始化后把规范化后的 groups 同步回父组件一次，
    // 避免父组件持有与子组件引用不一致的数组导致后续 v-model 回流。
    this.$nextTick(() => {
      this.$emit('update:modelValue', this.groups)
    })
  },
  watch: {
    groups: {
      deep: true,
      handler(val) {
        this.$emit('update:modelValue', val)
        this.$emit('change', val)
      }
    }
  },
  methods: {
    cloneGroups(val) {
      return val.map((g) => ({
        id: g.id || nextId(),
        logic: g.logic || 'AND',
        rules: (g.rules || []).map((r) => ({
          ...makeEmptyRule(),
          ...r,
          id: r.id || nextId(),
          timeWindow: {
            ...makeEmptyRule().timeWindow,
            ...(r.timeWindow || {})
          }
        }))
      }))
    },
    addGroup() {
      this.groups.push(makeEmptyGroup())
    },
    removeGroup(index) {
      if (this.groups.length <= 1) return
      ElMessageBox.confirm('确定删除该规则组？', '提示', { type: 'warning' })
        .then(() => this.groups.splice(index, 1))
        .catch(() => {})
    },
    copyGroup(index) {
      const src = this.groups[index]
      const copy = JSON.parse(JSON.stringify(src))
      copy.id = nextId()
      copy.rules = copy.rules.map((r) => ({ ...r, id: nextId() }))
      this.groups.splice(index + 1, 0, copy)
    },
    addRule(gIndex) {
      this.groups[gIndex].rules.push(makeEmptyRule())
    },
    removeRule(gIndex, rIndex) {
      const group = this.groups[gIndex]
      if (group.rules.length <= 1) return
      group.rules.splice(rIndex, 1)
    },
    onParamChange(rule) {
      rule.operator = ''
      rule.value = ''
      rule.value2 = ''
      const param = PARAM_MAP[rule.paramKey]
      if (!param || !param.hasHistory) {
        rule.timeWindow = makeEmptyRule().timeWindow
      }
    },
    onTimeModeChange(rule) {
      if (rule.timeWindow.mode !== 'recentMonths') {
        rule.timeWindow.aggregator = 'any'
      }
    },
    onOperatorChange(rule) {
      rule.value = ''
      rule.value2 = ''
    },
    showTimeWindow(rule) {
      return needTimeWindow(PARAM_MAP[rule.paramKey])
    },
    aggregatorsFor(rule) {
      const param = PARAM_MAP[rule.paramKey]
      if (!param) return AGGREGATORS_ENUM
      if (param.type === PARAM_TYPE.NUMBER) return AGGREGATORS_NUMBER
      if (param.type === PARAM_TYPE.LIST && param.listItemType === PARAM_TYPE.NUMBER) return AGGREGATORS_NUMBER
      return AGGREGATORS_ENUM
    },
    operatorsFor(rule) {
      return getOperatorsByParam(PARAM_MAP[rule.paramKey])
    },
    needValue(rule) {
      if (!rule.operator) return false
      return needValueInput(rule.operator)
    },
    valueComponentFor(rule) {
      const param = PARAM_MAP[rule.paramKey]
      if (!param) return { is: 'el-input', props: { size: 'small', style: 'width: 180px', placeholder: '比较值' } }

      // 推荐关系
      if (param.type === PARAM_TYPE.REFERRAL) {
        if (['includesCustomerId', 'notIncludesCustomerId'].includes(rule.operator)) {
          return {
            is: 'el-input',
            props: { size: 'small', style: 'width: 220px', placeholder: '客户号，多个英文逗号分隔' }
          }
        }
        return {
          is: 'el-input-number',
          props: { size: 'small', style: 'width: 140px', min: 0, controlsPosition: 'right' }
        }
      }

      // Boolean
      if (param.type === PARAM_TYPE.BOOLEAN) {
        return {
          is: 'el-select',
          props: { size: 'small', style: 'width: 120px', placeholder: '请选择' },
          options: BOOLEAN_OPTIONS
        }
      }

      // Date
      if (param.type === PARAM_TYPE.DATE) {
        if (['withinLast', 'beforeLast'].includes(rule.operator)) {
          return {
            is: 'el-input-number',
            props: { size: 'small', style: 'width: 120px', min: 1, controlsPosition: 'right' }
          }
        }
        const isMonth = param.dateFormat === 'YYYY-MM'
        return {
          is: 'el-date-picker',
          props: {
            type: isMonth ? 'month' : 'date',
            size: 'small',
            style: 'width: 160px',
            placeholder: '选择日期',
            valueFormat: isMonth ? 'YYYY-MM' : 'YYYY-MM-DD'
          }
        }
      }

      // 多选枚举
      if (param.multiple && param.options) {
        return {
          is: 'el-select',
          props: {
            multiple: true,
            collapseTags: true,
            size: 'small',
            style: 'width: 280px',
            placeholder: '请选择'
          },
          options: param.options
        }
      }

      // 枚举（单选 或 in/notIn 变多选）
      if (param.options) {
        if (['in', 'notIn'].includes(rule.operator)) {
          return {
            is: 'el-select',
            props: {
              multiple: true,
              collapseTags: true,
              size: 'small',
              style: 'width: 260px',
              placeholder: '请选择'
            },
            options: param.options
          }
        }
        return {
          is: 'el-select',
          props: { size: 'small', style: 'width: 200px', placeholder: '请选择' },
          options: param.options
        }
      }

      // 数值
      if (param.type === PARAM_TYPE.NUMBER || param.type === PARAM_TYPE.LIST) {
        return {
          is: 'el-input-number',
          props: { size: 'small', style: 'width: 160px', controlsPosition: 'right' }
        }
      }

      // 默认文本
      return {
        is: 'el-input',
        props: { size: 'small', style: 'width: 200px', placeholder: '比较值' }
      }
    }
  }
}
</script>

<style scoped>
.rule-builder { display: flex; flex-direction: column; gap: 16px; }

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.rule-tip { color: #909399; font-size: 13px; }
.rule-tip b { color: #F56C6C; margin: 0 2px; }

.rule-group {
  border: 1px solid #ebeef5;
  border-radius: 6px;
  background: #fafbfc;
}
.group-header {
  padding: 10px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px dashed #ebeef5;
  background: #f4f6f8;
  border-radius: 6px 6px 0 0;
}
.group-title { display: flex; align-items: center; gap: 16px; }
.group-no { font-weight: 600; color: #303133; }
.group-logic { color: #606266; font-size: 13px; display: flex; align-items: center; gap: 8px; }
.group-actions { display: flex; gap: 8px; }

.rule-list { padding: 12px 16px; }

.rule-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px dashed #f0f2f5;
}
.rule-row:last-of-type { border-bottom: none; }

.rule-no {
  width: 24px;
  height: 24px;
  line-height: 24px;
  text-align: center;
  background: #ecf5ff;
  color: #409EFF;
  border-radius: 50%;
  font-size: 12px;
  flex-shrink: 0;
}

.inline-label { color: #606266; font-size: 13px; }

.rule-delete { margin-left: auto; color: #F56C6C; }

.rule-add { padding-top: 8px; }
</style>
