<script setup lang="ts">
import { XMessage, useAudio } from '@/hooks'
import Sidebar from './components/UserCenterSidebar.vue'
import { debounce } from '@/hooks'
import { userStore, globalStore } from '@/stores'
import { storeToRefs } from 'pinia'
import { $sleep } from '@/utils'
import userApi from '@/api/system/user'

const props = defineProps<{
  modelValue: boolean
}>()
const emits = defineEmits(['update:modelValue'])

const OSS_URL = import.meta.env.VITE_OSS_URL
const bg = `url(${OSS_URL}/urm/exchange_fireworks.png) 100%/cover no-repeat`
const receiveReward = `${OSS_URL}/sound/receive_reward.mp3`

const { getUserInfo } = userStore()
const { userInfo } = storeToRefs(userStore())
const { system } = globalStore()

// 侧边栏
const config = [
  { id: 0, name: '头像' },
  { id: 1, name: '昵称' },
  { id: 2, name: '性别' },
  { id: 3, name: '昵称框' },
  { id: 4, name: '头像框' },
]
const active = ref(0)

// 头像列表
const avatarList = ref<anyObj[]>([])

// 设置的各种url
const setUrl = ref<anyObj>({})

// 修改昵称
const nickname = ref('')
const errorMsg = ref('')

async function editName() {
  if (!canChangeNickName.value) return XMessage.error(`钻石不足，请通过学习获取钻石哦！`, true)
  await userApi.useDiamondChangeNickName({ newNickName: nickname.value })
  userInfo.value.nickName = nickname.value
  userInfo.value.nickNameChangeCardCount--
  XMessage.success('昵称修改成功')
}

function onCheck() {
  if (!canChangeNickName.value) {
    XMessage.error(`钻石不足，请通过学习获取钻石哦！`, true)
  }
}

// 切换回昵称页面时显示原来的昵称
function handleChangeSidebar(item: anyObj) {
  showExchangeBtn.value = false
  if (item.id === 0) previewConfig.avatarUrl && (showExchangeBtn.value = true)
  if (item.id === 3) previewConfig.nicknameBg && (showExchangeBtn.value = true)
  if (item.id === 4) previewConfig.avatarFrameUrl && (showExchangeBtn.value = true)
  if (item.id === 1) {
    nickname.value = userInfo.value.nickName
  }
}

// 修改性别
function editSex(sex: 1 | 2) {
  if (userInfo.value.sex === sex) return
  userApi.updateUserSex({ sex })
  userInfo.value.sex = sex
}

const debounceEditSex = debounce(editSex, 500)

// 头像框列表
const avatarFrameList = ref<anyObj[]>([])

// 昵称框列表
const nickFrameList = ref<anyObj[]>([])

const nicknameBg = computed(
  () =>
    previewConfig.nicknameBg ||
    userInfo.value?.personInUsePersonalities.find((i: anyObj) => i.remark === 4)
      ?.personalInfoResourceUrl,
)

const showPreviewDia = ref(false)
const diaData = ref<anyObj>({})
const showExchange = ref(false)
const showExchangeBtn = ref(false)
// 预览修改
const _previewConfig = {
  avatarUrl: '',
  avatarFrameUrl: '',
  nicknameBg: '',
}
const TYPE_AVATAR = 0
const TYPE_NICKNAME = 1
const TYPE_GENDER = 2
const TYPE_NICKNAME_FRAME = 3
const TYPE_AVATAR_FRAME = 4

const REMARK_AVATAR = 1
const REMARK_AVATAR_FRAME = 2
const REMARK_NICKNAME_FRAME = 4

const SELECTED = 1
const UNSELECTED = 0

const MALE = 1
const FEMALE = 2

const lastSelectData = reactive<anyObj>({})
const lastSelectType = ref<0 | 3 | 4>(0)
const previewConfig = reactive({ ..._previewConfig })
const previewConfigChange = debounce((item: anyObj, type: 0 | 3 | 4) => {
  if (item.useStatus) return
  lastSelectData[type] = item
  lastSelectType.value = type
  // 预览模式
  if (type === TYPE_AVATAR) {
    avatarList.value.forEach(item => (item.useStatus = UNSELECTED))
    previewConfig.avatarUrl = item.personalInfoResourceUrl
  } else if (type === TYPE_NICKNAME_FRAME) {
    nickFrameList.value.forEach(item => (item.useStatus = UNSELECTED))
    previewConfig.nicknameBg = item.personalInfoResourceUrl
  } else {
    avatarFrameList.value.forEach(item => (item.useStatus = UNSELECTED))
    previewConfig.avatarFrameUrl = item.personalInfoResourceUrl
  }

  if (item.lockStatus) {
    // 未解锁的头像
    showExchangeBtn.value = true
  } else {
    // 已经解锁的头像
    showExchangeBtn.value = false
    changeUserConfig(item, type)
  }
  item.useStatus = SELECTED
}, 300)

// 修改头像/头像框/昵称框
async function changeUserConfig(item: anyObj, type: 0 | 3 | 4) {
  userApi.updatePersonalConfig({ unlockId: item.unlockId }).then((_: any) => {
    if (type === TYPE_AVATAR) {
      setUrl.value.avatar = item.resourceUrl
    } else if (type === TYPE_NICKNAME_FRAME) {
      setUrl.value.nickname_frame = item.resourceUrl
    } else {
      setUrl.value.avatar_frame = item.resourceUrl
    }
  })
  // updatePersonalConfig({ unlockId: item.unlockId }).then(res => {
  //   getUserInfo().then(res => {
  //     if (type === 0) {
  //       previewConfig.avatarUrl = ''
  //     } else if (type === 3) {
  //       previewConfig.nicknameBg = ''
  //     } else {
  //       previewConfig.avatarFrameUrl = ''
  //     }
  //     switch (item.remark) {
  //       case 1:
  //         initHead()
  //         break
  //       case 2:
  //         initBorder()
  //         break
  //       case 4:
  //         initNkBorder()
  //         break
  //     }
  //   })
  // })
  // await updatePersonalConfig({ unlockId: item.unlockId })
  // await getUserInfo()
  // console.log('changeUserConfig', item);
  //
  // if (type === 0) {
  //     previewConfig.avatarUrl = ''
  // } else if (type === 3) {
  //     previewConfig.nicknameBg = ''
  // } else {
  //     previewConfig.avatarFrameUrl = ''
  // }
}

function onExchange() {
  showPreviewDia.value = true
  // showExchange.value = false;
  diaData.value = lastSelectData[active.value]
}

async function onOk() {
  // if (showExchange.value) return (showPreviewDia.value = false);
  if (userInfo.value.diamond < lastSelectData[active.value].currencyNum) {
    XMessage.error(`钻石不足，请通过学习获取钻石哦！`, true)
    return
  }
  const { data: res } = await userApi.exchangeVirtualItem({ id: diaData.value.id })
  // showExchange.value = true;
  // 清空状态
  // switch (lastSelectType.value) {
  //     case 0:
  //         previewConfig.avatarUrl = '';
  //         break;
  //     case 3:
  //         previewConfig.nicknameBg = '';
  //         break;
  //     case 4:
  //         previewConfig.avatarFrameUrl = '';
  //         break;
  // }
  lastSelectData[active.value].unlockId = res.data
  lastSelectData[active.value].useStatus = UNSELECTED
  changeUserConfig(lastSelectData[active.value], lastSelectType.value).then(_ => {
    useAudio({
      url: receiveReward,
      autoplay: true,
      volume: system.volume.effectsVolume / 100,
    })
    showExchangeBtn.value = false
    switch (diaData.value.remark) {
      case REMARK_AVATAR:
        initAvatar()
        break
      case REMARK_AVATAR_FRAME:
        initAvatarFrame()
        break
      case REMARK_NICKNAME_FRAME:
        initNicknameFrame()
        break
    }
    showPreviewDia.value = false
    XMessage.success('兑换成功')
  })
}

// const debounceChangeUserConfig = debounce(changeUserConfig, 300)

const canChangeNickName = computed(() => Number(userInfo.value.diamond) >= 2000)

watch(
  () => props.modelValue,
  async newVal => {
    if (newVal) Object.assign(previewConfig, _previewConfig)
    // 弹窗打开和关闭时更新userInfo
    await getUserInfo()
    nickname.value = userInfo.value.nickName
    if (!newVal) {
      avatarList.value.forEach(item => {
        if (item.resourceUrl === setUrl.value.avatar) {
          item.useStatus = SELECTED
        } else {
          item.useStatus = UNSELECTED
        }
      })
      avatarFrameList.value.forEach(item => {
        if (item.resourceUrl === setUrl.value.avatar_frame) {
          item.useStatus = SELECTED
        } else {
          item.useStatus = UNSELECTED
        }
      })
      nickFrameList.value.forEach(item => {
        if (item.resourceUrl === setUrl.value.nickname_frame) {
          item.useStatus = SELECTED
        } else {
          item.useStatus = UNSELECTED
        }
      })
    }
  },
)

function initAvatar() {
  userApi.getUnlockInfoByRemark(REMARK_AVATAR).then(({ data: res }: any) => {
    // 头像列表
    if (res.code === 200) {
      avatarList.value = res.data
      res.data.forEach((item: any) => {
        if (!item.useStatus) return
        setUrl.value.avatar = item.resourceUrl
      })
    }
  })
}

function initAvatarFrame() {
  userApi.getUnlockInfoByRemark(REMARK_AVATAR_FRAME).then(({ data: res }: any) => {
    // 头像框列表
    if (res.code === 200) {
      avatarFrameList.value = res.data

      res.data.forEach((item: any) => {
        if (!item.useStatus) return
        setUrl.value.avatar_frame = item.resourceUrl
      })
    }
  })
}

function initNicknameFrame() {
  userApi.getUnlockInfoByRemark(REMARK_NICKNAME_FRAME).then(({ data: res }: any) => {
    // 昵称框列表
    if (res.code === 200) {
      nickFrameList.value = res.data

      res.data.forEach((item: any) => {
        if (!item.useStatus) return
        setUrl.value.nickname_frame = item.resourceUrl
      })
    }
  })
}

onMounted(async () => {
  // fix: 延迟加载数据，并发高安卓会卡顿
  await $sleep(2000)
  initAvatar()
  initAvatarFrame()
  initNicknameFrame()
})

// onActivated()
</script>
<template>
  <XLDia
    class="userInfoDia"
    :modelValue="modelValue"
    @update:modelValue="emits('update:modelValue', $event)"
  >
    <template #title>
      <!-- <user-figure
        class="user"
        :personal-list="userInfo.personInUsePersonalities"
        :sex="userInfo.sex"
        :nickname="userInfo.nickName"
      /> -->
      <div class="user">
        <UserHead
          size="88"
          :head="previewConfig.avatarUrl"
          :border="previewConfig.avatarFrameUrl"
          :personalList="userInfo.personInUsePersonalities"
        />
        <Icon class="sex" :name="userInfo.sex === 1 ? 'boy_icon' : 'girl_icon'" size="48"></Icon>
        <div
          class="nickname"
          :style="{
            'background-image': `url(${nicknameBg})`,
          }"
        >
          <LineFont class="name" :text="userInfo.nickName" size="28" border="6" />
        </div>
      </div>
      <div class="exchange-btn">
        <mj-button
          v-if="
            [TYPE_AVATAR, TYPE_NICKNAME_FRAME, TYPE_AVATAR_FRAME].includes(active as any) &&
            showExchangeBtn
          "
          type="warn"
          tilt
          @click="onExchange"
        >
          兑换
        </mj-button>
      </div>
    </template>
    <div class="left-sidebar">
      <Sidebar v-model="active" :config="config" @handleChange="handleChangeSidebar"></Sidebar>
    </div>
    <div class="left-main">
      <!-- 修改头像 -->
      <div v-if="active === TYPE_AVATAR" class="left-main-box avatar">
        <div class="list hidden_scroll avatar-list">
          <div
            v-for="i in avatarList"
            :key="i.id"
            :class="{
              'list-item': true,
              pointer: true,
              active: i.useStatus,
            }"
            @click="previewConfigChange(i, TYPE_AVATAR)"
          >
            <img :src="i.resourceUrl" />
            <Icon v-show="i.useStatus" name="circle_check" class="icon" width="56"></Icon>
            <!-- <Icon v-show="i.lockStatus" name="lock" class="lock-icon" width="48"></Icon> -->
            <div v-show="i.lockStatus" class="lock-icon">
              <Icon name="diamond" size="26" />
              {{ i.currencyNum }}
            </div>
          </div>
        </div>
      </div>
      <!-- 修改昵称 -->
      <div v-else-if="active === TYPE_NICKNAME" class="nickName-box left-main-box">
        <div class="input-box" @click="onCheck">
          <div class="error-msg">{{ errorMsg }}</div>
          <input v-model="nickname" :maxlength="8" @focus="errorMsg = ''" />
        </div>
        <div class="tips">
          本次改名将消耗
          <Icon name="diamond" size="48" />
          2000
        </div>
        <div class="btn">
          <mj-button
            type="info"
            :disabled="!canChangeNickName"
            :width="272"
            :size="32"
            @click="editName()"
          >
            确认修改
          </mj-button>
        </div>
      </div>
      <!-- 修改性别 -->
      <div v-else-if="active === TYPE_GENDER" class="sex-box left-main-box">
        <div class="sex-item">
          <div
            :class="['sex-icon', 'male', 'pointer', userInfo.sex === MALE ? 'active' : '']"
            @click="debounceEditSex(MALE)"
          >
            <Icon name="male" width="158"></Icon>
          </div>
          <span class="text">男</span>
        </div>
        <div class="sex-item">
          <div
            :class="['sex-icon', 'female', 'pointer', userInfo.sex === FEMALE ? 'active' : '']"
            @click="debounceEditSex(FEMALE)"
          >
            <Icon name="female" width="158"></Icon>
          </div>
          <span class="text">女</span>
        </div>
      </div>
      <!-- 修改昵称框 -->
      <div v-else-if="active === TYPE_NICKNAME_FRAME" class="left-main-box nick_frame">
        <div class="list hidden_scroll nick_frame-list">
          <div
            v-for="i in nickFrameList"
            :key="i.id"
            :class="{
              'list-item': true,
              pointer: true,
              active: i.useStatus,
            }"
            @click="previewConfigChange(i, TYPE_NICKNAME_FRAME)"
          >
            <div class="img-box">
              <img :src="i.resourceUrl" />
            </div>

            <Icon v-show="i.useStatus" name="circle_check" class="icon" width="56"></Icon>
            <!-- <Icon v-show="i.lockStatus" name="lock" class="lock-icon" width="48"></Icon> -->
            <div v-show="i.lockStatus" class="lock-icon">
              <Icon name="diamond" size="26" />
              {{ i.currencyNum }}
            </div>
          </div>
        </div>
      </div>
      <!-- 修改头像框 -->
      <div v-else-if="active === TYPE_AVATAR_FRAME" class="left-main-box avatar_frame">
        <div class="list hidden_scroll avatar_frame-list">
          <div
            v-for="i in avatarFrameList"
            :key="i.id"
            :class="{
              'list-item': true,
              pointer: true,
              active: i.useStatus,
            }"
            @click="previewConfigChange(i, TYPE_AVATAR_FRAME)"
          >
            <img :src="i.resourceUrl" />

            <Icon v-show="i.useStatus" name="circle_check" class="icon" width="56"></Icon>
            <!-- <Icon v-show="i.lockStatus" name="lock" class="lock-icon" width="48"></Icon> -->
            <div v-show="i.lockStatus" class="lock-icon">
              <Icon name="diamond" size="26" />
              {{ i.currencyNum }}
            </div>
          </div>
        </div>
      </div>
    </div>
  </XLDia>
  <mj-dialog
    v-model="showPreviewDia"
    :title="showExchange ? '兑换成功' : '兑换'"
    :hide-footer="true"
    :ok="onOk"
  >
    <div
      :class="{
        'preview-box': true,
        ex: showExchange,
      }"
      :style="{
        '--bg': bg,
      }"
    >
      <img
        :class="{
          'preview-img': true,
          'preview-head': diaData.remark === 1,
          border: diaData.remark !== 1,
        }"
        :src="diaData.remark === 4 ? diaData.resourceUrl : diaData.personalInfoResourceUrl"
      />
    </div>
    <template #footer>
      <div style="text-align: center">
        <mj-button v-if="!showExchange" type="warn" tilt width="320" @click="onOk">
          <Icon name="diamond" size="48" />
          {{ diaData.currencyNum }}
        </mj-button>
        <mj-button v-else type="success" tilt @click="showPreviewDia = false">确定</mj-button>
      </div>
    </template>
  </mj-dialog>
</template>

<style scoped lang="scss">
.userInfoDia {
  :deep(.xl-dia-main) {
    padding: 2.5vh 56px 2.5vh 10px;
    display: flex;
  }

  :deep(.xl-dia-box) {
    width: 1680px;
    height: 73.67vh;
    position: absolute;
    top: 20vh;

    .title {
      top: -12.67vh;

      .user {
        height: 11vh;
        display: flex;
        padding: 0 36px;
        align-items: center;
        gap: $space-4;

        .x-user-head {
          margin-top: 1.67vh;
        }

        .sex {
          margin-top: 3.33vh;
        }

        .nickname {
          width: 29.67vh;
          height: 10vh;
          display: flex;
          padding: 1.33vh 24px 0;
          background-repeat: no-repeat;
          background-size: 100% 100%;
          position: relative;
          box-sizing: border-box;
          @include single_ellipsis;

          .x-line-font {
            position: absolute;
            bottom: 1.75vh;
            left: 50%;
            transform: translateX(-50%);
          }
        }
      }
    }

    .exchange-btn {
      position: absolute;
      left: 1300px;
      top: 2.5vh;
    }
  }
}

.preview-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  position: relative;

  &.ex {
    &::before {
      content: '';
      display: block;
      background: var(--bg);
      width: 49.67vh;
      height: 19.83vh;
      position: absolute;
      top: -0.83vh;
      left: 50%;
      transform: translateX(-50%);
      background-size: 100% 100%;
    }

    .preview-img {
      width: 16.67vh;
      height: 16.67vh;
    }
  }

  .preview-img {
    width: 22.67vh;
    height: 22.67vh;
    margin-bottom: $space-3_h;

    &.border {
      border-radius: 0.67vh;
      border: 0.5vh solid #fff;
      background: #edf1f5;
      box-shadow: 0 0.33vh 0.33vh 0 rgba(0, 0, 0, 0.15);
    }
  }

  .preview-head {
    border: 0.25vh solid #323834;
    border-radius: 50%;
    background: #fffef0;
    box-shadow: 0 0.42vh 0.42vh 0 #00000026;
  }

  .tips {
    margin-bottom: $space-4_h;
    text-align: center;
    font-size: 2.33vh;
    font-style: normal;
    font-weight: 600;
    height: 4vh;
    display: flex;
    align-items: center;

    .x-icon {
      margin: 0 $space-2;
    }
  }
}

.left-sidebar {
  width: 20vh;
  height: 68.67vh;
  margin-right: 40px;
  margin-left: 20px;
  flex-shrink: 0;

  :deep(.sidebar-item) {
    height: 13.83vh;
    line-height: 7.5vh;

    &.active {
      background-position: center 1.33vh;
    }
  }
}

$avatar_wh: 13.67vh;
$nick_frame_wh: 15.33vh;
$avatar_frame_wh: 14vh;

.left-main {
  flex: 1;
  position: relative;

  &-box {
    width: 100%;
    display: flex;
    justify-content: center;
    height: 100%;

    .list {
      height: 100%;
      width: 100%;
      display: flex;
      justify-content: center;
      flex-wrap: wrap;
      gap: 3vh 4vh;

      .list-item {
        display: flex;
        justify-content: center;
        align-items: center;
        position: relative;

        .icon {
          position: absolute;
          top: 0;
          right: 0;
        }

        .lock-icon {
          display: flex;
          align-items: center;
          position: absolute;
          bottom: 2vh;
          left: 50%;
          transform: translate(-50%);
          padding: 0.5vh 12px;
          background: rgba(0, 0, 0, 0.45);
          border-radius: 3.75vh;
          color: #ffffff;
          font-family: $font-special;
          font-size: 1.5vh;

          .x-icon {
            margin-right: 4px;
          }
        }
      }
    }
  }

  .nickName-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .input-box {
      background-color: #b9d1ea;
      // box-shadow: 0px 0px 6px 0px #4c749e inset;
      width: 504px;
      height: 6.67vh;
      border-radius: 6.67vh;
      overflow: hidden;
      padding: 0 24px;
      margin-bottom: 4.83vh;
      position: relative;
      overflow: visible;
      z-index: 1;

      .error-msg {
        color: #f00a0a;
        font-family: 'Alibaba Health Font 2.0 CN';
        font-size: 2vh;
        font-style: normal;
        font-weight: 600;
        line-height: 3.5vh; /* 175% */
        position: absolute;
        top: -3.5vh;
        left: 48px;
      }

      input {
        width: 100%;
        height: 100%;
        background-color: transparent;
        outline: none;
        color: #fff;
        text-align: center;
        text-shadow: 0 0.17vh 0.17vh #4c749e;
        font-family: $font-special;
        font-size: 2.67vh;
        font-style: normal;
        font-weight: 400;
        line-height: 4vh; /* 150% */
      }
    }

    .tips {
      color: #999;
      text-align: center;
      font-family: 'Alibaba Health Font 2.0 CN';
      font-size: 2vh;
      font-style: normal;
      font-weight: 600;
      height: 4vh;
      margin-bottom: $space-2_h;
      display: flex;
      align-items: center;

      .x-icon {
        margin: 0 $space-2;
      }
    }
  }

  .sex-box {
    display: flex;
    align-items: center;
    justify-content: center;

    .sex-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;

      .text {
        color: $font-color;
        text-align: center;
        font-family: $font-special;
        font-size: 6vh;
        font-style: normal;
        font-weight: 400;
        line-height: 9vh; /* 150% */
        margin-top: 2vh;
      }
    }

    .sex-icon {
      box-sizing: content-box;
      width: 20vh;
      height: 20vh;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      border-radius: 50%;
      border: 0.67vh #fff solid;
      margin: 0 60px;
      position: relative;

      &.male {
        background-color: #18d6ff;
      }

      &.female {
        background-color: #f07097;
      }

      &::before {
        content: '';
        background-color: transparent;
        width: 22.67vh;
        height: 22.67vh;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        border-radius: 50%;
        z-index: -1;
      }

      &.active {
        &::before {
          background-color: #fef854;
        }
      }
    }
  }

  .avatar {
    &-list {
      // grid-template-columns: repeat(7, 15vh);
      // grid-template-rows: 15vh;
      // grid-auto-rows: 15vh;

      .list-item {
        width: $avatar_wh;
        height: $avatar_wh;
        border-radius: 50%;

        &.active {
          background-color: #fef854;
          box-shadow: 0 0.42vh 0.42vh 0 #00000026;

          img {
            border-color: transparent;
            box-shadow: none;
          }
        }

        img {
          width: $avatar_wh;
          height: $avatar_wh;
          border: 0.25vh solid #323834;
          border-radius: 50%;
          background: #fffef0;
          box-shadow: 0 0.42vh 0.42vh 0 #00000026;
        }
      }
    }
  }

  .avatar_frame {
    &-list {
      .list-item {
        width: $avatar_frame_wh;
        height: $avatar_frame_wh;
        border: 0.17vh solid #fff;
        background-color: #ecf1f4;
        border-radius: 1vh;
        position: relative;

        img {
          background-color: #ecf1f4;
          width: $avatar_frame_wh;
          height: $avatar_frame_wh;
        }

        &.active {
          background-color: #fef854;
        }
      }
    }
  }

  .nick_frame {
    &-list {
      .list-item {
        width: $nick_frame_wh;
        height: $nick_frame_wh;
        border: 0.17vh solid #fff;
        background-color: #ecf1f4;
        border-radius: 1vh;
        position: relative;
        overflow: hidden;
        padding: 1.33vh;

        .img-box {
          background-color: #ecf1f4;
          width: 14vh;
          height: 14vh;
          display: flex;
          justify-content: center;
          align-items: center;
        }

        img {
          width: 168px;
          height: 14vh;
        }

        &.active {
          background-color: #fef854;
        }
      }
    }
  }
}
</style>
