<script lang="ts" setup>
import {
  computed,
  inject,
  nextTick,
  onBeforeMount,
  onMounted,
  reactive,
  ref,
  shallowRef,
  unref,
  watch,
} from 'vue'
import dayjs from 'dayjs'
import { cloneDeep, isEqual } from 'lodash-es'
import { CustomFilterModalVue, FilterModalVue, NewFilterModalVue } from './comp/modals'
import Search from './comp/Search.vue'
import AdvanceFilter from './comp/AdvanceFilter.vue'
import { getViewportOffset } from '@/utils/domUtils'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { useConfig } from '@/store/modules/asideConfig'
import type { Filter } from '/#/home'
import type { AsideEntity } from '@/config/aside'
import { asideMap } from '@/config/aside'
import type { AsideConfig } from '/#/api'
import emitter from '@/utils/mitt'
import { getFilterList } from '@/api/home/main'
import { useKeydown } from '@/hooks/event/useKeydown'

const configStore = useConfig()

// 所有左侧模块的值
const asideValue: Record<keyof typeof asideMap, any> = reactive({})
// 左侧某个模块是否显示: 显示需同时满足系统配置和个人配置
const asideVisible: Partial<Record<keyof AsideConfig, boolean>> = reactive({})
// 当前显示的模块，按照数组顺序显示
const showItems = shallowRef<{ key: string, config: AsideEntity }[]>([])

Object.keys(asideMap).forEach((key) => {
  const entity = asideMap[key]
  const { defaultValue } = entity
  asideValue[key] = defaultValue
})

const filterModalRef: any = ref(null)
const newFilterModalRef = ref(null)
const customModalRef = ref(null)
const customObjRef = ref<any>(null) // 获取高级筛选获取的值
const customTempObjRef = ref<any>(null) // 获取高级筛选获取的值(作对比)
const configFilterRef = ref<any>([]) // 获取排序的值
const AdvanceFilterRef: any = ref(null)

function showModal(modalRef: any) {
  const modal = unref(modalRef)! as any
  modal.showModal()
}

onMounted(() => {
  nextTick(() => {
    computeSlideHeight()
    const tempAsideValue = cloneDeep(asideValue)
    // configStore.setAsideValue(tempAsideValue);
    console.log('asideMap和asideValue', tempAsideValue)
  })
})

const collapse = ref(false)
const mousetrap = inject('mousetrap') as any
mousetrap.bind('[', collapseHandler)

function collapseHandler() {
  collapse.value = !collapse.value
  console.log('执行了啊啊啊啊啊啊啊啊啊啊啊啊', collapse.value)
  configStore.setCollapse(collapse.value)
}

const asideWidth = computed(() => {
  return collapse.value ? 0 : 308
})

const asideHeight = ref(500)
const asideStyle = computed(() => {
  return {
    width: `${asideWidth.value}px`,
    height: `${asideHeight.value}px`,
  }
})

const collapseIcon = computed(() => {
  return collapse.value ? 'expand-cir' : 'collapse-cir'
})

function computeSlideHeight() {
  const headEl = document.querySelector('.aside-header')!
  const { bottomIncludeBody } = getViewportOffset(headEl)
  const height = bottomIncludeBody
  asideHeight.value = height - 24
}

useWindowSizeFn(computeSlideHeight, 280)

onBeforeMount(async () => {
  configStore.fetchConfig()
  configStore.fetchCustomConfig()
})

nextTick(() => {
  configStore.$subscribe(() => {
    const config = configStore.getConfig
    const customConfig = configStore.getCustomConfig
    if (
      configFilterRef.value.length > 0
      && isEqual(configFilterRef.value, configStore.getFilterConfig)
      && customObjRef.value
      && isEqual(customObjRef.value, customTempObjRef.value)
    )
      return

    if (config == null || customConfig == null)
      return
    // console.log("config", config, "customConfig", customConfig);
    /* rao
  const showKeys = [...customConfig].filter(key => !asideMap[key].isDefaultFilter)// 获取customConfig 非isDefaultFilter的选项
  const defaultKeys = Object.keys(asideMap).filter(key => asideMap[key].isDefaultFilter)// 获取asideMap isDefaultFilter的选项
  showKeys.unshift(...defaultKeys)
  */

    const sortKeyList: any = []
    configStore.getFilterConfig.map((item: any) => {
      sortKeyList.push(item?.id)
      return item
    })
    const showKeys = [...sortKeyList]

    Object.keys(config).forEach((key) => {
      if (key.startsWith('iz') && asideMap[key] !== undefined) {
        asideVisible[key]
          = (showKeys.includes(key) || asideMap[key].isDefaultFilter)
          && config[key] === 'Y'
      }
    })
    if (customObjRef.value) {
      // 赋值
      Object.keys(customObjRef.value).map((key) => {
        // TODO hasOwnProperty避免直接调用
        // if (asideMap.hasOwnProperty(key)) {
        if (Object.prototype.hasOwnProperty.call(customObjRef.value, key)) {
          const str = key.toLowerCase()
          // console.log("customObjRef.value[str]1111111111111", customObjRef.value[str]);
          if (str == 'izsimilarity') {
            if (typeof customObjRef.value[str] == 'string')
              customObjRef.value[str] = customObjRef.value[str].split(',')

            asideValue[key] = customObjRef.value[str] // 赋值
            console.log('相似度2222222222', asideValue[key])
          }
          else if (str == 'izyear') {
            if (typeof customObjRef.value[str] == 'string') {
              const time = customObjRef.value[str].split('-')
              time[0] = new Date(time[0]).getTime()
              time[1] = new Date(time[1]).getTime()
              customObjRef.value[str] = time
            }
            asideValue[key] = customObjRef.value[str] // 赋值
            console.log('时间2222222222', asideValue[key])
          }
          else if (
            str != 'izsimilarity'
            && str != 'izyear'
            && customObjRef.value[str]
          ) {
            console.log('customObjRef.value[str]222222', customObjRef.value[str])
            // let list = customObjRef.value[str].split(',');
            // console.log("list222222", list);
            asideValue[key] = customObjRef.value[str] // 赋值
          }
          else {
            asideValue[key] = null
          }
          // asideMap[str].defaultValue = customObjRef.value[str];// 赋值
        }
        return key
      })
      customTempObjRef.value = customObjRef.value
      console.log('asideValue直接处理后的结果', asideValue)
      console.log('customTempObjRef.value', customTempObjRef.value)
      const tempobj = cloneDeep(asideValue)
      console.log('tempObj', tempobj)
      configStore.setAsideValue(tempobj)
    }
    // console.log("showKeys", showKeys);
    const items = showKeys.reduce((acc, key) => {
      const currentData = asideMap[key]
      const render = currentData?.render
      if (render !== false) {
        const str = key?.toLowerCase()

        const o = {
          key: str,
          config: asideMap[str],
        }
        return [...acc, o]
      }
      else {
        return acc
      }
    }, [])
    console.log('showItems=================================', items)
    showItems.value = items
    configFilterRef.value = configStore.getFilterConfig
  })
})
const asideEnter = ref(false)

const showCollapse = computed(() => {
  return collapse.value ? true : asideEnter.value
})

const showSearch = ref(false)

function setShowSearch(value: boolean) {
  showSearch.value = value
}
function newFilterOk() {
  filterModalRef.value.query(
    filterModalRef.value.pagination.page,
    filterModalRef.value.pagination.pageSize,
  )
  filterModalRef.value.closeModal()
}

// 滚动容器，让key对应模块处于可视区域
function scrollHandler(key: string) {
  const element = document.querySelector(`#${key}`)
  element?.scrollIntoView(true)
}

// 选择某个过滤配置，刷新图片墙 -> 筛选搜索条件
async function filterHandler(searchId: string) {
  // emitter.emit('filter', searchId)
  const res = await getFilterList({ userSearchId: searchId })
  // console.log("顾虑结果", res);
  if (res.code == 'OK') {
    const obj = res.data
    customObjRef.value = res.data
    const showKeys: any[] = []
    Object.keys(obj).map((key) => {
      // TODO hasOwnProperty避免直接调用
      // if (asideMap.hasOwnProperty(key)) {
      if (Object.prototype.hasOwnProperty.call(asideMap, key))
        showKeys.push(key)

      return key
    })
    // console.log(showKeys);
    configStore.setCustomConfig(showKeys)
  }
}

function editFilter(filter: any) {
  const modal = unref(newFilterModalRef)! as any
  modal.showModal()
  modal.edit(filter)
}

function updateComponent(key, e) {
  console.log('跟新值', key, e)
  console.log('tempAsideValue跟新值', configStore.getAsideValue, asideValue)
  // let tempAsideValue = configStore.getAsideValue || asideValue;
  const tempobj = cloneDeep(asideValue)
  console.log(tempobj, 'tempobj')
  tempobj[key] = e
  console.log(tempobj, 'tempobj After')
  customObjRef.value = tempobj
  // asideValue = Object.assign({}, asideValue, tempobj);
  console.log('asideValue跟新值', tempobj)
  configStore.setAsideValue(tempobj)
}

function handleOk(item: any) {
  console.log('handleOk', item)
  if (item) {
    AdvanceFilterRef.value.setCurrentlySelectedAdvanced(item.searchname)
    filterHandler(item.id)
  }
  else {
    AdvanceFilterRef.value.setCurrentlySelectedAdvanced('高级筛选')
    filterHandler('')
  }
}
useKeydown('s', () => setShowSearch(true))
// watch(asideValue, (newVal) => {
//   console.log("asideValue处理后", newVal);
//   configStore.setAsideValue(newVal)
// }, { deep: true })
</script>

<template>
  <div
    class="aside"
    :style="asideStyle"
    @mouseenter="asideEnter = true"
    @mouseleave="asideEnter = false"
  >
    <div v-show="showCollapse" class="aside-collapse">
      <div class="aside-collapse-btn" @click="collapseHandler">
        <SvgIcon :name="collapseIcon" size="40" />
      </div>
    </div>
    <n-scrollbar trigger="none">
      <div class="aside-header">
        <!-- 搜索跳转模块 -->
        <Search
          v-show="showSearch"
          @select="scrollHandler"
          @close="setShowSearch(false)"
        />
        <!-- 高级筛选 -->
        <AdvanceFilter
          v-show="!showSearch"
          ref="AdvanceFilterRef"
          :type="0"
          @select="filterHandler"
          @update:search="setShowSearch(true)"
          @show-custom="showModal(customModalRef)"
          @show-filter="showModal(filterModalRef)"
        />
      </div>

      <component
        :is="item.config?.component"
        v-for="item in showItems"
        :id="item.key"
        :key="item.key"
        v-model:value="asideValue[item.key]"
        :label="item.config?.label"
        @update:value="(e) => updateComponent(item.key, e)"
      />

      <!-- 过滤列表 -->
      <FilterModalVue
        ref="filterModalRef"
        @edit-filter="editFilter"
        @show-new-filter="showModal(newFilterModalRef)"
        @handle-ok="handleOk"
      />
      <!-- 新增过滤 -->
      <NewFilterModalVue ref="newFilterModalRef" @on-ok="newFilterOk" />
      <!-- 筛选 -->
      <CustomFilterModalVue ref="customModalRef" />
    </n-scrollbar>
  </div>
</template>

<style lang="less" scoped>
.aside {
  display: flex;
  position: relative;
  flex-direction: column;
  background: #fff;
  border: 1px solid #efeff5;
  border-radius: 3px;
  box-sizing: border-box;
   margin-left: 16px;

  &-header {
    padding: 10px;
    width: 100%;
    border-bottom: 1px solid #e8e8e8;
    margin-bottom: 15px;
    height: 58px;
  }

  &-divider {
    width: 100%;
    height: 1px;
    background-color: #e8e8e8;
  }

  &-collapse {
    width: 2px;
    height: 100%;
    background: #507afd;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 18;
  }

  &-collapse-btn {
    position: absolute;
    cursor: pointer;
    width: 40px;
    height: 40px;
    top: calc(15%);
    right: -20px;
  }

  ::v-deep(.n-collapse
      .n-collapse-item.n-collapse-item--right-arrow-placement
      .n-collapse-item__header
      .n-collapse-item-arrow) {
    margin-left: 8px;
  }

  ::v-deep(.n-collapse
      .n-collapse-item
      .n-collapse-item__header
      .n-collapse-item__header-main) {
    font-weight: bold;
    justify-content: space-between;
  }

  ::v-deep(.n-collapse .n-collapse-item .n-collapse-item__header) {
    padding: 0px;
  }

  ::v-deep(.n-collapse .n-collapse-item:not(:first-child)) {
    border-top: 0px;
  }

  ::v-deep(.n-collapse
      .n-collapse-item
      .n-collapse-item__content-wrapper
      .n-collapse-item__content-inner) {
    padding-top: 10px;
  }

  ::v-deep(.n-scrollbar
      > .n-scrollbar-rail.n-scrollbar-rail--vertical
      > .n-scrollbar-rail__scrollbar, .n-scrollbar
      + .n-scrollbar-rail.n-scrollbar-rail--vertical
      > .n-scrollbar-rail__scrollbar) {
    width: 0px;
  }
}
</style>
