<template>
  <div
    v-if="!contactSearchingStatus"
    :class="['tui-contact-list', !isPC && 'tui-contact-list-h5']"
  >
    <view v-if="!currentContactListKey">
      <view class="top-list_box">
        <view
          v-for="(contactListObj, key) in contactListMap"
          :key="key"
          class="tui-contact-list-item"
        >
          <header
            class="tui-contact-list-item-header"
            @click="toggleCurrentContactList(key)"
          >
            <view class="tui-contact-list-item-header-left">
              <Icon
                v-if="contactListObj.icon"
                :file="contactListObj.icon"
                size="96rpx"
              />
              <span
                v-if="contactListObj.unreadCount"
                class="tui-contact-list-item-header-left-unread"
              >
                {{ contactListObj.unreadCount }}
              </span>
            </view>
            <view class="tui-contact-list-item-header-right">
              <text>
                {{ contactListObj.title }}
              </text>
              <!-- <Icon
                :file="currentContactListKey === key ? downSVG : rightSVG"
                size="20px"
              /> -->
            </view>
          </header>
        </view>
      </view>
      <FriendList @enterConversation="selectFriend" />
    </view>
    <template v-else>
      <li
        v-for="contactListItem in contactListMap[currentContactListKey]
          .list"
        :key="contactListItem.renderKey"
        class="tui-contact-list-item-main-item"
        :class="['selected']"
        @click="selectItem(contactListItem)"
      >
        <ContactListItem
          :key="contactListItem.renderKey"
          :item="deepCopy(contactListItem)"
        />
      </li>
    </template>
  </div>

  <ul v-else-if="contactSearchingStatus" class="tui-contact-list">
    <li
      v-for="(item, key) in contactSearchResult"
      :key="key"
      class="tui-contact-list-item"
    >
      <div v-if="item.list[0]" class="tui-contact-search-list">
        <div class="tui-contact-search-list-title">
          {{ TUITranslateService.t(`TUIContact.${item.label}`) }}
        </div>
        <div
          v-for="(listItem, index) in item.list"
          :key="index"
          class="tui-contact-search-list-item"
          :class="['selected']"
          @click="selectItem(listItem)"
        >
          <ContactListItem
            :item="listItem"
            :display-online-status="false"
          />
        </div>
      </div>
    </li>
    <div
      v-if="isContactSearchNoResult"
      class="tui-contact-search-list-default"
    >
      {{ TUITranslateService.t('TUIContact.无搜索结果') }}
    </div>
  </ul>
</template>
<script setup lang="ts">
  import {
    TUITranslateService,
    TUIStore,
    StoreName,
    TUIFriendService,
    TUIUserService
  } from '@tencentcloud/chat-uikit-engine-lite'
  import TUICore, { TUIConstants } from '@tencentcloud/tui-core-lite'
  import {
    ref,
    computed,
    onMounted,
    onUnmounted,
    provide
  } from '../../../adapter-vue'
  import { isPC } from '../../../utils/env'
  import { deepCopy } from '../../TUIChat/utils/utils'

  import Icon from '../../common/Icon.vue'
  import ContactListItem from './contact-list-item/index.vue'
  import FriendList from './components/FriendList.vue'

  import downSVG from '../../../assets/icon/down-icon.svg'
  import rightSVG from '../../../assets/icon/right-icon.svg'
  import newContactsSVG from '../../../assets/icon/friend-request-icon.svg'
  import groupSVG from '../../../assets/icon/my-group-chat.svg'
  import blackListSVG from '../../../assets/icon/blacklist-icon.svg'
  import addFrienIcon from '../../../assets/icon/add-frien-icon.svg'

  import type {
    IContactList,
    IContactSearchResult,
    IBlackListUserItem,
    IUserStatus,
    IUserStatusMap,
    IContactInfoType
  } from '../../../interface'
  import type {
    IGroupModel,
    Friend,
    FriendApplication
  } from '@tencentcloud/chat-uikit-engine-lite'
  import { navigateTo } from '../../../../utils/router'

  const currentContactListKey = ref<keyof IContactList>('')
  const currentContactInfo = ref<IContactInfoType>({} as IContactInfoType)
  const contactListMap = ref<IContactList>({
    friendApplicationList: {
      icon: newContactsSVG,
      key: 'friendApplicationList',
      title: '好友请求',
      list: [] as FriendApplication[],
      unreadCount: 0
    },
    currentContactSearchingStatus: {
      icon: addFrienIcon,
      key: 'currentContactSearchingStatus',
      title: '添加好友',
      list: [] as IGroupModel[]
    },
    groupList: {
      icon: groupSVG,
      key: 'groupList',
      title: '我的群聊',
      list: [] as IGroupModel[]
    },
    blackList: {
      icon: blackListSVG,
      key: 'blackList',
      title: '黑名单',
      list: [] as IBlackListUserItem[]
    }
  })

  const contactSearchingStatus = ref<boolean>(false)
  const contactSearchResult = ref<IContactSearchResult>()
  const displayOnlineStatus = ref<boolean>(false)
  const userOnlineStatusMap = ref<IUserStatusMap>()

  const isContactSearchNoResult = computed(
    (): boolean =>
      !contactSearchResult?.value?.user?.list[0] &&
      !contactSearchResult?.value?.group?.list[0]
  )

  onMounted(() => {
    TUIStore.watch(StoreName.APP, {
      enabledCustomerServicePlugin:
        onCustomerServiceCommercialPluginUpdated
    })

    TUIStore.watch(StoreName.GRP, {
      groupList: onGroupListUpdated
    })

    TUIStore.watch(StoreName.USER, {
      userBlacklist: onUserBlacklistUpdated,
      displayOnlineStatus: onDisplayOnlineStatusUpdated,
      userStatusList: onUserStatusListUpdated
    })

    TUIStore.watch(StoreName.FRIEND, {
      friendApplicationList: onFriendApplicationListUpdated,
      friendApplicationUnreadCount: onFriendApplicationUnreadCountUpdated
    })

    TUIStore.watch(StoreName.CUSTOM, {
      currentContactSearchingStatus:
        onCurrentContactSearchingStatusUpdated,
      currentContactSearchResult: onCurrentContactSearchResultUpdated,
      currentContactListKey: onCurrentContactListKeyUpdated,
      currentContactInfo: onCurrentContactInfoUpdated
    })
  })

  onUnmounted(() => {
    TUIStore.unwatch(StoreName.APP, {
      enabledCustomerServicePlugin:
        onCustomerServiceCommercialPluginUpdated
    })

    TUIStore.unwatch(StoreName.GRP, {
      groupList: onGroupListUpdated
    })

    TUIStore.unwatch(StoreName.USER, {
      userBlacklist: onUserBlacklistUpdated,
      displayOnlineStatus: onDisplayOnlineStatusUpdated,
      userStatusList: onUserStatusListUpdated
    })

    TUIStore.unwatch(StoreName.FRIEND, {
      friendApplicationList: onFriendApplicationListUpdated,
      friendApplicationUnreadCount: onFriendApplicationUnreadCountUpdated
    })

    TUIStore.unwatch(StoreName.CUSTOM, {
      currentContactSearchingStatus:
        onCurrentContactSearchingStatusUpdated,
      currentContactSearchResult: onCurrentContactSearchResultUpdated,
      currentContactListKey: onCurrentContactListKeyUpdated,
      currentContactInfo: onCurrentContactInfoUpdated
    })
  })

  function toggleCurrentContactList(key: keyof IContactList) {
    if (key === 'currentContactSearchingStatus') {
      navigateTo('/pages/adduser/index')
      // TUIStore.update(StoreName.CUSTOM, key, true)
      return
    }
    if (currentContactListKey.value === key) {
      currentContactListKey.value = ''
      currentContactInfo.value = {} as IContactInfoType
      TUIStore.update(StoreName.CUSTOM, 'currentContactListKey', '')
      TUIStore.update(
        StoreName.CUSTOM,
        'currentContactInfo',
        {} as IContactInfoType
      )
    } else {
      currentContactListKey.value = key
      TUIStore.update(StoreName.CUSTOM, 'currentContactListKey', key)
      if (key === 'friendApplicationList') {
        TUIFriendService.setFriendApplicationRead()
      }
    }
  }

  function selectItem(item: any) {
    currentContactInfo.value = item
    // For a result in the search list, before viewing the contactInfo details,
    // it is necessary to update the data for the "already in the group list/already in the friend list" situation to obtain more detailed information
    if (contactSearchingStatus.value) {
      let targetListItem
      if ((currentContactInfo.value as Friend)?.userID) {
        targetListItem = contactListMap.value?.friendList?.list?.find(
          (item: IContactInfoType) =>
            (item as Friend)?.userID ===
            (currentContactInfo.value as Friend)?.userID
        )
      } else if ((currentContactInfo.value as IGroupModel)?.groupID) {
        targetListItem = contactListMap.value?.groupList?.list?.find(
          (item: IContactInfoType) =>
            (item as IGroupModel)?.groupID ===
            (currentContactInfo.value as IGroupModel)?.groupID
        )
      }
      if (targetListItem) {
        currentContactInfo.value = targetListItem
      }
    }
    TUIStore.update(
      StoreName.CUSTOM,
      'currentContactInfo',
      currentContactInfo.value
    )
  }

  const selectFriend = (item: any) => {
    navigateTo('/pages/adduser/details', { id: item.userID, type: '1' })
    // TUIStore.update(
    //   StoreName.CUSTOM,
    //   'currentContactListKey',
    //   'friendList'
    // )
    // selectItem(item)
  }

  function onDisplayOnlineStatusUpdated(status: boolean) {
    displayOnlineStatus.value = status
  }

  function onUserStatusListUpdated(list: Map<string, IUserStatus>) {
    if (list?.size > 0) {
      userOnlineStatusMap.value = Object.fromEntries(list?.entries())
    }
  }

  function onCustomerServiceCommercialPluginUpdated(isEnabled: boolean) {
    if (!isEnabled) {
      return
    }

    // After the customer purchases the customer service plug-in,
    // the engine updates the enabledCustomerServicePlugin to true through the commercial capability bit.
    const contactListExtensionID =
      TUIConstants.TUIContact.EXTENSION.CONTACT_LIST.EXT_ID
    const tuiContactExtensionList = TUICore.getExtensionList(
      contactListExtensionID
    )

    const customerData = tuiContactExtensionList.find(
      (extension: any) => {
        const { name, accountList = [] } = extension.data || {}
        return name === 'customer' && accountList.length > 0
      }
    )

    if (customerData) {
      const { data, text } = customerData
      const { accountList } = (data || {}) as { accountList: string[] }

      TUIUserService.getUserProfile({ userIDList: accountList })
        .then(res => {
          if (res.data.length > 0) {
            const customerList = {
              title: text,
              list: res.data.map((item: any, index: number) => ({
                ...item,
                renderKey: generateRenderKey('customerList', item, index),
                infoKeyList: [],
                btnKeyList: ['enterC2CConversation']
              })),
              key: 'customerList'
            }
            contactListMap.value = {
              ...contactListMap.value,
              customerList
            }
          }
        })
        .catch(() => {})
    }
  }

  function onGroupListUpdated(groupList: IGroupModel[]) {
    updateContactListMap('groupList', groupList)
  }

  function onUserBlacklistUpdated(userBlacklist: IBlackListUserItem[]) {
    updateContactListMap('blackList', userBlacklist)
  }

  function onFriendApplicationUnreadCountUpdated(
    friendApplicationUnreadCount: number
  ) {
    contactListMap.value.friendApplicationList.unreadCount =
      friendApplicationUnreadCount
  }

  function onFriendApplicationListUpdated(
    friendApplicationList: FriendApplication[]
  ) {
    updateContactListMap('friendApplicationList', friendApplicationList)
  }

  function updateContactListMap(
    key: keyof IContactList,
    list: IContactInfoType[]
  ) {
    contactListMap.value[key].list = list
    contactListMap.value[key].list.map(
      (item: IContactInfoType, index: number) =>
        (item.renderKey = generateRenderKey(key, item, index))
    )
    updateCurrentContactInfoFromList(contactListMap.value[key].list, key)
  }

  function updateCurrentContactInfoFromList(
    list: IContactInfoType[],
    type: keyof IContactList
  ) {
    if (
      !(currentContactInfo.value as Friend)?.userID &&
      !(currentContactInfo.value as IGroupModel)?.groupID
    ) {
      return
    }
    if (
      type === currentContactListKey.value ||
      contactSearchingStatus.value
    ) {
      currentContactInfo.value =
        list?.find(
          (item: any) =>
            (item?.groupID &&
              item?.groupID ===
                (currentContactInfo.value as IGroupModel)?.groupID) ||
            (item?.userID &&
              item?.userID ===
                (currentContactInfo.value as Friend)?.userID)
        ) || ({} as IContactInfoType)
      TUIStore.update(
        StoreName.CUSTOM,
        'currentContactInfo',
        currentContactInfo.value
      )
    }
  }

  function generateRenderKey(
    contactListMapKey: keyof IContactList,
    contactInfo: IContactInfoType,
    index: number
  ) {
    return `${contactListMapKey}-${
      (contactInfo as Friend).userID ||
      (contactInfo as IGroupModel).groupID ||
      `index${index}`
    }`
  }

  function onCurrentContactSearchResultUpdated(
    searchResult: IContactSearchResult
  ) {
    contactSearchResult.value = searchResult
  }

  function onCurrentContactSearchingStatusUpdated(
    searchingStatus: boolean
  ) {
    contactSearchingStatus.value = searchingStatus
    TUIStore.update(
      StoreName.CUSTOM,
      'currentContactInfo',
      {} as IContactInfoType
    )
    TUIStore.update(StoreName.CUSTOM, 'currentContactListKey', '')
  }

  function onCurrentContactInfoUpdated(contactInfo: IContactInfoType) {
    currentContactInfo.value = contactInfo
  }

  function onCurrentContactListKeyUpdated(contactListKey: string) {
    currentContactListKey.value = contactListKey
  }

  provide('userOnlineStatusMap', userOnlineStatusMap)
</script>

<style lang="scss" scoped src="./style/index.scss"></style>

<style lang="scss" scoped>
  uni-page-body,
  html,
  body,
  page {
    width: 100% !important;
    height: 100% !important;
    overflow: hidden;
  }

  .tui-contact-search-list-title {
    padding: 16rpx 0;
  }

  .tui-contact-list-item-header {
    &::after {
      display: none !important;
    }
  }

  .top-list_box {
    display: flex;
    justify-content: space-between;
    padding: 32rpx 50rpx;
    .tui-contact-list-item {
      .tui-contact-list-item-header {
        padding: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        &:active {
          background: none !important;
        }
      }
    }
  }
</style>
