<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
import { debounce } from 'lodash-es'
import { asideMap } from '@/config/aside'
import { favorite, getConditionList, unfavorite } from '@/api/home/filter'
import type { Filter, FilterEntity } from '/#/home'

defineOptions({ name: 'AdvanceFilter' })

const emit = defineEmits<{
  (e: 'show-filter'): void
  (e: 'show-custom'): void
  (e: 'update:search'): void
  (e: 'select', filterList: Filter[])
}>()

const data = ref<FilterEntity[]>([])
let loading = false
let lastPostion = 0
let canloadMore = true
const el = ref<HTMLDivElement | null>(null)
const popover = ref<ComponentRef | null>(null)
const pagination = reactive({
  pageNo: 1,
  pageSize: 10,
})

onMounted(() => {
  data.value = generateDefaultConfig()
})

// 默认的过滤配置
function generateDefaultConfig(): FilterEntity[] {
  return Object.keys(asideMap).reduce((acc, key) => {
    const { label, defaultValue, isDefaultFilter } = asideMap[key]

    if (isDefaultFilter === true) {
      const config = {
        name: label,
        favorite: false,
        isDefaultFilter,
        filterList: [{
          key,
          value: defaultValue,
        }],
      }
      return [...acc, config]
    }
    else {
      return acc
    }
  }, [])
}

useInfiniteScroll(
  el as any,
  () => {
    loadMore()
  },
  { distance: 10, interval: 3000, canLoadMore: () => canloadMore },
)

async function loadMore() {
  if (loading || el.value == null)
    return

  lastPostion = el.value!.scrollTop
  const more = await featchList()

  if (more.length === 0)
    return

  data.value.push(...more)
  el.value?.scrollTo(0, lastPostion)
}

async function featchList() {
  loading = true
  try {
    const result = await getConditionList({ ...pagination })
    const { data, pageCount } = result
    pagination.pageNo += 1
    canloadMore = pageCount >= pagination.pageNo
    const entityList = generateFilterEntityList(data)
    return entityList
  }
  catch (error) {
    return []
  }
  finally {
    loading = false
  }
}

// 转换服务器数据格式
function generateFilterEntityList(data) {
  const filterEntityList = data.map((item) => {
    const { searchname, iztop, ocrUsersearchchildList, id } = item

    const list = ocrUsersearchchildList.map((item) => {
      const { searchfield, searchvalue } = item

      return {
        key: searchfield,
        value: searchvalue,
      }
    })

    return {
      id,
      name: searchname,
      favorite: iztop,
      isDefaultFilter: false,
      filterList: list,
    }
  })

  return filterEntityList
}

function selectHandler(item: FilterEntity) {
  (popover.value as any).setShow(false)
  emit('select', item.filterList)
}

const inputHandler = debounce((keyword) => {
  // 调用后端接口，搜索
}, 300)

function favoriteHandler(event: MouseEvent, item: any) {
  event.stopImmediatePropagation()
  event.stopPropagation()

  const { isDefaultFilter, id } = item

  if (!isDefaultFilter) {
    item.favorite = true
    favorite(id)
  }
}

function unFavoriteHandler(event: MouseEvent, item) {
  event.stopImmediatePropagation()
  event.stopPropagation()

  const { isDefaultFilter, id } = item

  if (!isDefaultFilter) {
    item.favorite = false
    unfavorite(id)
  }
}
</script>

<template>
  <div class="wrapper">
    <div class="wrapper-left">
      <svg-icon name="shield" size="32" />
      <n-popover
        ref="popover" :style="{ padding: '0px' }" style="width: 248px" :show-arrow="false"
        placement="bottom-start" trigger="click"
      >
        <template #trigger>
          <div class="wrapper-left-dropdown">
            <span>高级筛选</span>
            <SvgIcon :style="{ marginLeft: '5px' }" name="down" size="14" />
          </div>
        </template>
        <n-spin :show="loading">
          <div class="wrapper-left-popover">
            <n-input :style="{ '--n-border': '0px' }" placeholder="请输入关键字" @input="inputHandler">
              <template #prefix>
                <SvgIcon size="14px" name="magnifying-1" />
              </template>
              <template #suffix>
                <SvgIcon size="14px" style="cursor: pointer;" name="setting" @click="emit('show-filter')" />
              </template>
            </n-input>
            <ul ref="el" class="wrapper-left-list">
              <li v-for="(item, index) in data" :key="index" style="display: flex;align-items: center;" @click="selectHandler(item)">
                <SvgIcon v-if="item.favorite && !item.isDefaultFilter" name="favorite-fill" color="#fd9b0a" size="18" @click="unFavoriteHandler($event, item)" />
                <SvgIcon v-else-if="!item.favorite && !item.isDefaultFilter" name="favorite-unfill" size="18" @click="favoriteHandler($event, item)" />
                {{ item.name }}
              </li>
            </ul>
          </div>
        </n-spin>
      </n-popover>
    </div>
    <div class="wrapper-right">
      <SvgIcon style="display: block;cursor: pointer;" size="18" name="magnifying-1" @click="emit('update:search')" />
      <SvgIcon style="display: block;cursor: pointer;margin-left: 10px;" size="18" name="filter" @click="emit('show-custom')" />
    </div>
  </div>
</template>

<style lang="less" scoped>
.wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;

  &-left {
    display: flex;
    align-items: center;

    &-dropdown {
      display: flex;
      flex-direction: row;
      align-items: center;
      margin-left: 12px;
      cursor: pointer;
    }

    &-popvoer {
      background: #ffffff;
      border-radius: 2px;
      box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.15);
    }

    &-list {
      border-top: 1px solid #eeeeee;
      padding: 9px 0px;
      height: 200px;
      overflow-x: hidden;
      overflow-y: auto;
      scrollbar-width: none; /* firefox */
      -ms-overflow-style: none; /* IE 10+ */

      &::-webkit-scrollbar{
        display: none;
      }

      li {
        font-size: 14px;
        line-height: 22px;
        padding: 5px 12px;

        &:hover {
          background-color: #f3f8ff;
        }
      }
    }
  }

  &-right {
    display: flex;
    align-items: center;
  }
}
</style>
