<template>
  <section class="chart-filter-editor">
    <div v-for="(filter, index) in filters" :key="index" class="filter-row">
      <el-select
        :model-value="filter.field || ''"
        filterable
        placeholder="字段"
        @change="updateFilter(index, { field: $event })"
      >
        <el-option
          v-for="column in columns"
          :key="fieldKey(column)"
          :label="column.columnComment || column.javaField || column.columnName"
          :value="fieldKey(column)"
        />
      </el-select>

      <el-select
        :model-value="filter.operator || 'eq'"
        placeholder="运算符"
        @change="updateFilter(index, { operator: $event, value: defaultValue($event) })"
      >
        <el-option v-for="item in operators" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>

      <template v-if="filter.operator === 'between'">
        <el-input
          :model-value="arrayValue(filter.value)[0]"
          placeholder="开始值"
          @input="updateArrayValue(index, 0, $event)"
        />
        <el-input
          :model-value="arrayValue(filter.value)[1]"
          placeholder="结束值"
          @input="updateArrayValue(index, 1, $event)"
        />
      </template>
      <el-input
        v-else-if="filter.operator === 'in'"
        :model-value="arrayValue(filter.value).join(',')"
        placeholder="多个值用逗号分隔"
        @input="updateFilter(index, { value: splitValues($event) })"
      />
      <el-input
        v-else-if="!noValueOperators.includes(filter.operator)"
        :model-value="filter.value ?? ''"
        placeholder="筛选值"
        @input="updateFilter(index, { value: $event })"
      />
      <span v-else class="filter-no-value">无需填写值</span>

      <el-button type="danger" link @click="removeFilter(index)">删除</el-button>
    </div>

    <el-button :disabled="filters.length >= 10" @click="addFilter">+ 添加条件</el-button>
  </section>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  modelValue: { type: Array, default: () => [] },
  columns: { type: Array, default: () => [] }
})

const emit = defineEmits(['update:modelValue'])

const operators = [
  { value: 'eq', label: '等于' },
  { value: 'ne', label: '不等于' },
  { value: 'gt', label: '大于' },
  { value: 'gte', label: '大于等于' },
  { value: 'lt', label: '小于' },
  { value: 'lte', label: '小于等于' },
  { value: 'between', label: '区间' },
  { value: 'in', label: '包含任一' },
  { value: 'is_null', label: '为空' },
  { value: 'is_not_null', label: '不为空' }
]
const noValueOperators = ['is_null', 'is_not_null']
const filters = computed(() => props.modelValue || [])

function addFilter() {
  if (filters.value.length >= 10) return
  emit('update:modelValue', filters.value.concat({
    field: '',
    operator: 'eq',
    value: ''
  }))
}

function updateFilter(index, patch) {
  emit('update:modelValue', filters.value.map((filter, currentIndex) => (
    currentIndex === index ? { ...filter, ...patch } : filter
  )))
}

function removeFilter(index) {
  emit('update:modelValue', filters.value.filter((_, currentIndex) => currentIndex !== index))
}

function updateArrayValue(index, valueIndex, value) {
  const next = arrayValue(filters.value[index]?.value)
  next[valueIndex] = value
  updateFilter(index, { value: next })
}

function defaultValue(operator) {
  if (operator === 'between') return ['', '']
  if (operator === 'in') return []
  if (noValueOperators.includes(operator)) return null
  return ''
}

function arrayValue(value) {
  if (Array.isArray(value)) return value.slice()
  return value === null || value === undefined || value === '' ? [] : [value]
}

function splitValues(value) {
  return String(value || '')
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean)
}

function fieldKey(column) {
  return column?.javaField || column?.columnName || ''
}
</script>

<style scoped lang="scss">
.chart-filter-editor {
  display: grid;
  gap: 10px;
}

.filter-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(110px, 0.8fr) minmax(120px, 1fr) auto;
  gap: 8px;
  align-items: center;
}

.filter-row:has(input[placeholder="开始值"]) {
  grid-template-columns: minmax(110px, 1fr) minmax(100px, 0.8fr) minmax(90px, 0.8fr) minmax(90px, 0.8fr) auto;
}

.filter-no-value {
  color: #98a2b3;
  font-size: 12px;
}

@media (max-width: 720px) {
  .filter-row,
  .filter-row:has(input[placeholder="开始值"]) {
    grid-template-columns: 1fr;
  }
}
</style>
