<template>
  <div class="px-[16px] pb-[16px] pt-[4px] bg-white">
    <!-- 筛选框区域 && 按钮 -->
    <div class="flex">
      <div class="flex-1">
        <div class="flex flex-wrap">
          <div class="mr-[8px] mt-[12px]" v-for="item in filterData" :key="item.prop">
            <t-input
              v-model="item.str"
              clearable
              v-bind="item.$attrs"
              :placeholder="item.label"
              :style="{ width: (item.width || 160) + 'px' }"
              v-if="item.type === 'input'"
            >
              <template #suffix-icon>
                <SearchIcon />
              </template>
            </t-input>
            <t-select
              v-model="item.str"
              :placeholder="item.label"
              clearable
              v-bind="item.$attrs"
              :style="{ width: (item.width || 160) + 'px' }"
              v-if="item.type === 'select' && item.selectData"
            >
              <t-option v-for="opt in item.selectData" :key="opt.value" :value="opt.value" :label="opt.label" />
            </t-select>
            <t-select
              v-model="item.values"
              v-bind="item.$attrs"
              :placeholder="item.label"
              clearable
              multiple
              filterable
              :min-collapsed-num="minCollapsedNum"
              :style="{ width: (item.width || 160) + 'px' }"
              v-if="item.type === 'multiple-select' && item.selectData"
            >
              <t-option v-for="opt in item.selectData" :key="opt.value" :value="opt.value" :label="opt.label" />
            </t-select>
            <t-date-picker
              v-model="item.str"
              allow-input
              clearable
              :placeholder="item.label"
              v-bind="item.$attrs"
              :style="{ width: (item.width || 160) + 'px' }"
              v-if="item.type === 'date'"
            />
          </div>
        </div>
        <!-- 筛选结果区域 -->
        <transition>
          <div class="mt-[4px] flex flex-wrap max-h-[100vh] min-h-[36px]" v-if="isShowFilterResult">
            <div v-for="item in filterData" :key="item.prop">
              <div class="flex items-center mr-[16px] mt-[12px]" v-if="item.str || item.values?.length">
                <div class="text-font-gray-3">{{ item.label }}：</div>
                <template v-if="['select', 'input', 'date'].includes(item.type)">
                  <t-tag :closable="!item.closable" @close="filterResultClose(item)">{{
                    returnFilterResult(item)
                  }}</t-tag>
                </template>
                <template v-else-if="item.type === 'multiple-select'">
                  <t-tag
                    :closable="!item.closable"
                    v-for="itx in item.values"
                    :key="itx"
                    class="mr-[8px]"
                    @close="filterMultipleResultClose(item, itx)"
                  >
                    {{ returnMultipleResult(item, itx) }}
                  </t-tag>
                </template>
              </div>
            </div>
          </div>
        </transition>
      </div>

      <div class="flex flex-col w-[60px] mt-[12px] ml-[88px]">
        <t-button theme="default" variant="base" class="bg-btn" @click="handleFilterSearch">查询</t-button>
        <t-button
          v-show="isShowFilterResult"
          theme="default"
          variant="outline"
          class="!mt-[12px] !clear-btn"
          @click="handleClear"
        >
          清空
        </t-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts" generic="T">
import { SelectProps } from 'tdesign-vue-next'
import { filterItemProp } from './interface/index'
defineOptions({ name: 'PageFilters' })

interface PageFiltersProps {
  filterConditions: filterItemProp[]
}

const props = withDefaults(defineProps<PageFiltersProps>(), {
  filterConditions: () => []
})

const filterData = ref<filterItemProp[]>([])
const minCollapsedNum: SelectProps['minCollapsedNum'] = 1

// 判断是否显示筛选结果区域
const isShowFilterResult = computed(() => filterData.value.find((v: filterItemProp) => v.str || v.values?.length))

// 筛选结果区域-关闭(select, input)
const filterResultClose = (item: filterItemProp) => {
  item.str = ''
}

// 清空
const handleClear = () => {
  filterData.value.flatMap((item: filterItemProp) => {
    item.str = ''
    item.values = []
  })
  emit('clear')
}

// 展示筛选内容的结果(select、input)
const returnFilterResult = (item: filterItemProp) => {
  if (item.type === 'select' && item.selectData) {
    const label = item.selectData.find(v => v.value === item.str)
    if (label) return label.label
  }
  return item.str
}

// 展示筛选内容的结果(multiple-select)
const returnMultipleResult = (item: filterItemProp, itx: string | number) => {
  const label = item.selectData?.find(val => val.value === itx)?.label
  return label
}

// 删除筛选结果区域(multiple-select)
const filterMultipleResultClose = (item: filterItemProp, itx: string | number) => {
  item.values = item.values?.filter(v => v !== itx)
}

// 搜索方法
interface DynamicType {
  [key: string]: any
}
const filterParams: DynamicType = reactive({})

const emit = defineEmits<{
  'on-filter': [filter: DynamicType['filter']]
  'on-search': [filter: DynamicType['filter']]
  clear: []
}>()

const handleFilterSearch = () => {
  resetFilterConditions()
  emit('on-filter', filterParams as DynamicType)
}

const resetFilterConditions = () => {
  filterData.value.forEach((item: filterItemProp) => {
    if (item.type === 'multiple-select') {
      filterParams[item.prop] = item.values
    } else filterParams[item.prop] = item.str
  })
  return filterParams
}

watch(
  () => props.filterConditions,
  (val: filterItemProp[]) => {
    filterData.value = val
  },
  {
    deep: true,
    immediate: true
  }
)

watch(
  () => filterData,
  () => {
    resetFilterConditions()
    emit('on-search', filterParams as DynamicType)
  },
  {
    deep: true
  }
)

defineExpose<DynamicType>({
  resetFilterConditions
})
</script>

<style lang="less" scoped>
.v-enter-active,
.v-leave-active {
  transition: all 0.3s ease;
  overflow: hidden;
}

.v-enter-from,
.v-leave-to {
  max-height: 0;
  min-height: 0;
  height: 0;
}

:deep(.t-tag--default) {
  cursor: pointer;
  background-color: var(--td-gray-color-1);

  &:hover {
    background-color: var(--td-brand-color-1);
  }
}

.fliter {
  min-width: 500px;

  &-left {
    width: 200px;
    border-right: 1px solid var(--td-gray-color-2);
  }

  &-right {
    flex: 1;
    padding: 0 12px;
  }

  &-bottom {
    padding: 8px;
    border-top: 1px solid var(--td-gray-color-2);
  }
}

.bg-btn {
  background-color: var(--td-gray-color-1);
}

.clear-btn {
  border-color: var(--td-gray-color-2);
}
</style>
