<script lang="ts" setup>
import { getAllfieldList, getfieldList, setFilter } from '@/api/home/filter'
import { asideMap } from '@/config/aside'
import { useConfig } from '@/store/modules/asideConfig'
import { useUser } from "@/store/modules/user"
import { debounce, difference, cloneDeep } from 'lodash-es'
import { computed, defineOptions, onMounted, ref, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'


defineOptions({ name: 'CustomFilterModal' })

const show = ref(false)
const configStore = useConfig()
const checkAll = ref(false)
const selectIds = ref<string[]>([])

function showModal() {
  show.value = true

  // 重置左右列表数据
  const config = configStore.getConfig
  const customConfig = configStore.getCustomConfig

  if (config == null || customConfig == null)
    return
  const { showList, hideList } = generatList(config, customConfig)
  console.log("showList", showList);
  onList.value = showList
  offList.value = hideList
  // 重置全选状态
  checkAll.value = hideList.every(item => item.checked);
  // 重置输入框查询条件
  offKeyword.value = ''
  onKeyword.value = ''
}

function closeModal() {
  show.value = false
}

// 左侧隐藏列表
const offList = ref<any[]>([])
// 右侧显示列表
const onList = ref<any[]>([])

const allCount = computed(() => {
  return `全部筛选(共${offList.value.length}个)`
})

const selectCount = computed(() => {
  return `全部筛选(共${onList.value.length}个)`
})

defineExpose({
  showModal,
})

function generateDefaultList(config) {
  return Object.keys(asideMap).reduce((acc, key) => {
    const { label, isDefaultFilter } = asideMap[key]

    // 个人配置开启且系统配置开启
    if (isDefaultFilter && config[key] === 'Y') {
      const config = {
        id: key,
        name: label || '未配置',
        fix: true,
        checked: true,
      }
      return [...acc, config]
    }
    else {
      return acc
    }
  }, [])
}

function generatList(config, customConfig) {
  const keys = Object.keys(config)
  let onList: object[] = []
  const offList: object[] = []
  const showKeys = [...customConfig]

  for (const key of keys) {
    if (!key.startsWith('iz') || config[key] === 'N' || asideMap[key] === undefined)
      continue

    const name = asideMap[key]?.label
    const isDefaultFilter = asideMap[key]?.isDefaultFilter

    // 系统配置为Y，且不是默认配置
    if (!isDefaultFilter) {
      const isChecked = asideMap[key].isDefaultFilter || showKeys.includes(key)

      offList.push({
        id: key,
        name: name || '未配置',
        fix: isDefaultFilter,
        checked: isChecked,
      })
      if (isChecked && selectIds.value.indexOf(key) === -1) {
        isChecked && selectIds.value.push(key)
      }
    }
  }

  onList = showKeys.reduce((acc, key) => {
    const isDefaultFilter = asideMap[key]?.isDefaultFilter

    // 也需要系统配置开启（可能个人开启后，系统配置关闭） && 把默认显示的过滤掉(理论上不会出现这种情况)
    if (config[key] === 'Y' && isDefaultFilter === false) {
      const config = {
        id: key,
        name: asideMap[key].label || '未配置',
        fix: asideMap[key].isDefaultFilter,
      }
      return [...acc, config]
    }
    else {
      return acc
    }
  }, [])

  const fixedList = generateDefaultList(config)
  offList.unshift(...fixedList)
  onList.unshift(...fixedList)
  // onList按照customConfig排序
  let tempOnList = cloneDeep(onList);
  let sortList: any = [];
  customConfig.map(key => {
    let tempItem = tempOnList.find(item => item.id == key);
    sortList.push(tempItem);
  });
  // return { showList: onList, hideList: offList }
  return { showList: sortList, hideList: offList }
}

configStore.$subscribe(() => {
  const config = configStore.getConfig
  const customConfig = configStore.getCustomConfig

  if (config == null || customConfig == null)
    return

  const { showList, hideList } = generatList(config, customConfig)
  onList.value = showList
  offList.value = hideList
})

async function handleSumbit(e: MouseEvent) {
  e.preventDefault()
  const param = onList.value.map((item) => {
    return item.id
  }).join(',')

  await setFilter({ searchcount: param, type: 0 })
  configStore.fetchCustomConfig()
  closeModal()
}

function onCheckAllChange(value) {
  const ids: string[] = []

  for (const item of offList.value) {
    if (!item.fix) {
      item.checked = value
      ids.push(item.id)
    }
  }

  selectIds.value = value ? ids : []
}

function onCheckChange(checked: any, item: any) {
  const index = selectIds.value.indexOf(item.id)

  item.checked = checked

  if (index === -1 && checked)
    selectIds.value.push(item.id)
  else
    index !== -1 && selectIds.value.splice(index, 1)
  
  checkAll.value = offList.value.every(item => item.checked);
}

const showIds = computed(() => {
  return onList.value.map((item) => {
    return item.id
  })
})

watch(
  () => selectIds.value.length,
  (newVal, oldVal) => {
    if (newVal === oldVal)
      return

    const action = newVal > oldVal ? 'add' : 'remove'
    const diff = action === 'add' ? difference(selectIds.value, showIds.value) : difference(showIds.value, selectIds.value)

    if (diff.length === 0)
      return

    if (action === 'add') {
      for (const item of offList.value) {
        if (!item.fix && diff.includes(item.id)) {
          if (item.checked) {
            onList.value.push({
              id: item.id,
              name: item.name || '未配置',
              fix: item.fix || false,
            })
          }
        }
      }
    }
    else {
      const list = onList.value
      for (let index = 0; index < list.length; index++) {
        const item = list[index]
        if (!item.fix && diff.includes(item.id)) {
          list.splice(index, 1)
          index--
        }
      }
    }
  },
)

watch(
  () => showIds.value.length,
  (newVal, oldVal) => {
    if (newVal === oldVal)
      return

    const diff = difference(selectIds.value, showIds.value)

    if (diff.length === 0)
      return

    for (const item of offList.value) {
      if (!item.fix && diff.includes(item.id)) {
        const index = selectIds.value.indexOf(item.id)
        item.checked = false
        selectIds.value.splice(index, 1)
      }
    }
  },
)

function clearDragSource() {
  onList.value = onList.value.filter((item) => {
    return item.fix === true
  })
}

function removeHandler(id: string) {
  const index = onList.value.findIndex((item) => {
    return item.id === id
  })

  if (index !== -1)
    onList.value.splice(index, 1)
}

const offKeyword = ref('')
const onKeyword = ref('')

const leftInputHandler = debounce((keyword) => {
  offKeyword.value = keyword
}, 300)

const rightInputHandler = debounce((keyword) => {
  onKeyword.value = keyword
}, 300)

async function getfield() {
  let res;
  res = await getAllfieldList(3)
  const userStore = useUser();
  const userInfo = userStore.getUserInfo;
  res = await getfieldList(3, userInfo.id)
}
function onMove(e) {
  // 这里的e表示即将停靠的元素。
  if (e?.related?.className?.indexOf('fix') !== -1) {
    return false;
  }
}

onMounted(() => {
  getfield();
})

</script>

<template>
  <n-modal v-model:show="show" transform-origin="center" :mask-closable="false">
    <n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
      <div class="wrapper">
        <span class="wrapper-title">自定义筛选</span>
        <div class="wrapper-bar">
          <div class="wrapper-info">
            <span :style="{ 'margin-left': '18px' }">筛选项信息</span>
          </div>
        </div>

        <n-grid cols="24" class="mt-4 proCard" responsive="screen" :x-gap="24">
          <n-grid-item span="11">
            <NCard
              :title="allCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
              :bordered="false"
            >
              <div class="input_wrap">
                <n-input placeholder="搜索关键词" @input="leftInputHandler">
                  <template #suffix>
                    <SvgIcon size="14px" name="magnifying-1-color999" />
                  </template>
                </n-input>
                <n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;">
                  <div class="draggable-ul">
                    <div class="draggable-li">
                      <n-checkbox v-model:checked="checkAll" label="全选" @update:checked="onCheckAllChange" :indeterminate="!checkAll"/>
                    </div>
                    <div
                      v-for="item in offList" v-show="item.name.includes(offKeyword)" :key="item.id" :class="{ 'disable-check': item.fix }"
                      class="draggable-li"
                    >
                      <n-checkbox
                        v-model:checked="item.checked" :label="item.name" :disabled="item.fix"
                        @update:checked="onCheckChange($event, item)"
                      />
                    </div>
                  </div>
                </n-scrollbar>
              </div>
            </NCard>
          </n-grid-item>
          <n-grid-item style="display: flex;align-items: center;" span="2">
            <SvgIcon size="20" name="switchsvg" />
          </n-grid-item>
          <n-grid-item span="11">
            <NCard
              :title="selectCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
              :bordered="false"
            >
              <template #header-extra>
                <span class="textbtnStyle" @click="clearDragSource">清空</span>
              </template>
              <div class="input_wrap">
                <n-input placeholder="搜索关键词" @input="rightInputHandler">
                  <template #suffix>
                    <SvgIcon size="14px" name="magnifying-1-color999" />
                  </template>
                </n-input>
                <n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll">
                  <VueDraggable v-model="onList" class="draggable-ul" :animation="150" group="shared" >
                    <div v-for="item in onList" v-show="item.name.includes(onKeyword)" :key="item.id" :draggable="true" class="cursor-move draggable-li">
                      <SvgIcon  name="drag" size="24" />
                      <span class="ml-2">{{ item.name }}</span>
                      <SvgIcon v-if="!item.fix"  size="16px" style="display:block;margin-left: auto;cursor: pointer;"
                        name="clear" @click="removeHandler(item.id)" />
                    </div>
                  </VueDraggable>
                </n-scrollbar>
              </div>
            </NCard>
          </n-grid-item>
        </n-grid>
      </div>
      <template #footer>
        <div class="wrapper-footer">
          <n-button type="info" @click="handleSumbit">
            确定
          </n-button>
          <n-button secondary style="margin-left:15px; border: 1px solid #CAD2DD;" @click="closeModal">
            取消
          </n-button>
        </div>
      </template>
    </n-card>
  </n-modal>
</template>

<style lang="less" scoped>
.wrapper {
  display: flex;
  flex-direction: column;

  &-title {
    font-weight: bold;
    font-size: 16px;
  }

  &-bar {
    background-color: #f8f8f8 !important;
    width: calc(100% + 12px);
    margin-top: 20px;
    color: #333333;
  }

  &-footer {
    display: flex;
    justify-content: flex-end;
    .n-button--info-type{
      background: #507AFD !important;
    }
    .n-button--default-type{
      background: #fff !important;
      color: #333333;
    }
  }

  &-info {
    font-weight: bold;
    position: relative;
    font-size: 14px;

    &:before {
      background-color: #1980FF;
      content: "";
      width: 5px;
      border-radius: 2px;
      top: 0;
      bottom: 0;
      position: absolute;
    }
  }
}

.dragcardStyle {
  --n-padding-bottom: 0px !important;
  --n-padding-left: 0px !important;
  ::v-deep(.n-card__content) {
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
}

.cardstyle {
  width: 620px;
  height: 800px;
  --n-padding-bottom: 20px;
  --n-padding-left: 24px;
  // background-color: #f8f8f8 !important;
}

.textbtnStyle {
  cursor: pointer;
  color: #1980FF;
}

.draggable-ul {
  width: 100%;
  overflow: hidden;

  .draggable-li {
    width: 100%;
    padding: 10px 16px;
    color: #333;
    border-bottom: 1px solid #efeff5;
    display: flex;
    align-items: center;
  }

  .fix {
    cursor: default !important;
  }

  .disable-check {
    color: gainsboro;
  }
}

::v-deep(.n-card.n-card--content-segmented > .n-card__content:not(:first-child)) {
  border: 0px;
}

::v-deep(.n-card > .n-card-header) {
  --n-padding-top: 0px;
  --n-padding-bottom: 12px;
}
::v-deep(.n-card > .n-card-header .n-card-header__main){
  font-weight: lighter !important;
  font-size: 14px;
  color: #666;
}
::v-deep(.n-scrollbar){
  border-left: 1px solid #cad2dd !important;
  border-right: 1px solid #cad2dd !important;
  border-bottom: 1px solid #E8E8E8 !important;
  border-top: 1px solid #E8E8E8 !important;
}
::v-deep(.n-card__content){
  padding: 20px 24px  0 24px !important;
}
::v-deep(.n-card__footer){
  padding: 0 24px 16px 24px !important;
}
::v-deep(.n-input .n-input-wrapper){
  height: 44px !important;
  border: 1px solid #cad2dd !important;
  border-bottom: none !important;
  // margin-bottom: -3px;
  .n-input__input input{
    height: 44px !important;
  }
}
::v-deep(.n-button--info-type){
  background: #507AFD !important;
}
</style>
