<script setup lang="ts">
import { computed, ref } from 'vue';

import { Button, Card, Space } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';

defineOptions({
  name: 'DataSearch',
});

const props = defineProps<{
  columns: any[];
  modelValue: any[];
}>();

const emit = defineEmits<{
  'update:modelValue': [value: any[]];
  'search': [];
  'reset': [];
}>();

const searchConditions = ref<any[]>([]);

// 操作符选项
const operatorOptions = [
  { label: '等于', value: '=' },
  { label: '不等于', value: '!=' },
  { label: '大于', value: '>' },
  { label: '大于等于', value: '>=' },
  { label: '小于', value: '<' },
  { label: '小于等于', value: '<=' },
  { label: '包含', value: 'like' },
  { label: '不包含', value: 'not like' },
  { label: '为空', value: 'is null' },
  { label: '不为空', value: 'is not null' },
  { label: '在范围内', value: 'in' },
  { label: '不在范围内', value: 'not in' },
  { label: '之间', value: 'between' },
];

// 字段选项
const fieldOptions = computed(() => {
  return props.columns.map((col) => ({
    label: `${col.name}${col.comment ? ` (${col.comment})` : ''}`,
    value: col.name,
  }));
});

// 添加查询条件
const addCondition = () => {
  searchConditions.value.push({
    field: '',
    operator: '=',
    value: '',
    value2: '', // for BETWEEN
    logic: searchConditions.value.length > 0 ? 'AND' : 'AND',
  });
};

// 删除查询条件
const removeCondition = (index: number) => {
  searchConditions.value.splice(index, 1);
};

// 搜索
const handleSearch = () => {
  const conditions = searchConditions.value
    .filter((cond) => cond.field && cond.operator)
    .map((cond) => {
      const condition: any = {
        field: cond.field,
        operator: cond.operator,
      };

      // 处理不需要值的操作符
      if (['is null', 'is not null'].includes(cond.operator)) {
        // 这些操作符不需要值
      } else if (cond.operator === 'between') {
        condition.value = [cond.value, cond.value2];
      } else if (['in', 'not in'].includes(cond.operator)) {
        // 将逗号分隔的字符串转换为数组
        condition.value = cond.value
          ? cond.value
              .split(',')
              .map((v: string) => v.trim())
              .filter((v: string) => v)
          : [];
      } else {
        condition.value = cond.value;
      }

      if (cond.logic) {
        condition.logic = cond.logic;
      }

      return condition;
    });

  emit('update:modelValue', conditions);
  emit('search');
};

// 重置
const handleReset = () => {
  searchConditions.value = [];
  emit('update:modelValue', []);
  emit('reset');
};

// 判断操作符是否需要值
const needsValue = (operator: string) => {
  return !['is null', 'is not null'].includes(operator);
};

// 判断操作符是否需要两个值（BETWEEN）
const needsTwoValues = (operator: string) => {
  return operator === 'between';
};

// 判断操作符是否需要数组值（IN）
const needsArrayValue = (operator: string) => {
  return ['in', 'not in'].includes(operator);
};
</script>

<template>
  <Card title="高级搜索" class="mb-4" size="small">
    <div class="space-y-3">
      <div v-for="(condition, index) in searchConditions" :key="index" class="flex items-start gap-2">
        <!-- 逻辑连接符 -->
        <div v-if="index > 0" class="w-16 pt-1">
          <select
            v-model="condition.logic"
            class="w-full rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
          >
            <option value="AND">AND</option>
            <option value="OR">OR</option>
          </select>
        </div>

        <!-- 字段选择 -->
        <div class="flex-1">
          <select
            v-model="condition.field"
            class="w-full rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
          >
            <option value="">请选择字段</option>
            <option v-for="field in fieldOptions" :key="field.value" :value="field.value">
              {{ field.label }}
            </option>
          </select>
        </div>

        <!-- 操作符选择 -->
        <div class="w-32">
          <select
            v-model="condition.operator"
            class="w-full rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
          >
            <option v-for="op in operatorOptions" :key="op.value" :value="op.value">
              {{ op.label }}
            </option>
          </select>
        </div>

        <!-- 值输入 -->
        <div v-if="needsValue(condition.operator)" class="flex-1">
          <template v-if="needsTwoValues(condition.operator)">
            <div class="flex gap-2">
              <input
                v-model="condition.value"
                type="text"
                placeholder="起始值"
                class="flex-1 rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
              />
              <span class="py-1 text-sm">至</span>
              <input
                v-model="condition.value2"
                type="text"
                placeholder="结束值"
                class="flex-1 rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
              />
            </div>
          </template>
          <template v-else-if="needsArrayValue(condition.operator)">
            <input
              v-model="condition.value"
              type="text"
              placeholder="多个值用逗号分隔，如: 1,2,3"
              class="w-full rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
            />
          </template>
          <template v-else>
            <input
              v-model="condition.value"
              type="text"
              placeholder="请输入值"
              class="w-full rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800"
            />
          </template>
        </div>

        <!-- 删除按钮 -->
        <Button type="text" danger size="small" @click="removeCondition(index)">
          <i class="fa-solid fa-trash"></i>
        </Button>
      </div>

      <!-- 操作按钮 -->
      <div class="flex items-center justify-between">
        <Button type="dashed" size="small" @click="addCondition">
          <i class="fa-solid fa-plus mr-2"></i>添加条件
        </Button>
        <Space>
          <Button size="small" @click="handleReset">重置</Button>
          <Button type="primary" size="small" @click="handleSearch">搜索</Button>
        </Space>
      </div>
    </div>
  </Card>
</template>

<style scoped>
.space-y-3 > * + * {
  margin-top: 0.75rem;
}
</style>
