<template>
  <el-form ref="formRef" class="el-form--filter" :model="queryParams" :rules="formRules" :show-message="false">
    <slot name="before"></slot>
    <template v-for="(item, index) in option.filters" :key="index">
      <template v-if="item.visibility?.() ?? true">
        <slot :name="item.field" :item="item">
          <el-form-item :label="item.label" :prop="item.field">
            <el-select :placeholder="item.placeholder ?? t('common.pleasechoice')" v-model="item.value"
              :multiple="item.multiple" collapse-tags clearable @change="item.onChange" :style="handleStyle(item.width)"
              v-if="item.options">
              <el-option v-for="option in item.options()" :key="option.value" :value="option.value"
                :label="option.label" />
            </el-select>
            <el-input :placeholder="item.placeholder ?? t('common.pleaseenter')" v-model="item.value"
              :style="handleStyle(item.width)" v-else />
          </el-form-item>
        </slot>
      </template>
    </template>
    <slot name="after"></slot>
    <el-form-item v-if="option.filters.length && option.buttons">
      <el-button :class="item.className" v-for="(item, index) in option.buttons" :key="index" :disabled="loading"
        @click="handleButtonClick(item)">{{ item.label }}
      </el-button>
    </el-form-item>
    <slot></slot>
  </el-form>
</template>

<script lang="ts" setup>
import { shallowRef, PropType, computed } from 'vue'
import { FormInstance, FormRules } from 'element-plus'
import { FilterOption, ActionButton } from '@/hooks/datatable-v2/types'
import { i18n } from '@/stores'

const { global: { t } } = i18n

const props = defineProps({
  option: {
    type: Object as PropType<FilterOption<any, any>>,
    default: () => ({}),
  },
  loading: {
    type: Boolean,
    default: false
  },
  rules: {
    type: Object as PropType<FormRules>,
    default: () => ({}),
  }
})

const formRef = shallowRef<FormInstance>()
const queryParams = computed(() => Object.fromEntries(props.option.filters.map(e => [e.field, e.value])))

// 表单验证规则
const formRules = computed<FormRules>(() => {
  const rules = props.option.filters.reduce<FormRules>((pre, cur) => {
    if (cur.required) {
      pre[cur.field] = [{ required: true }]
    }
    return pre
  }, {})

  return { ...rules, ...props.rules }
})

const handleStyle = (width?: number) => {
  const style: Partial<CSSStyleDeclaration> = {}
  if (width) {
    style.width = width + 'px'
  }
  return style
}

const handleButtonClick = ({ validateEvent = true, onClick }: ActionButton) => {
  if (validateEvent) {
    formRef.value?.validate((isValid) => {
      if (isValid) {
        onClick()
      }
    })
  } else {
    onClick()
    setTimeout(() => formRef.value?.resetFields(), 0)
  }
}
</script>