<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app';
import { ref } from 'vue';
import globalConfig from '@/config/global';
import * as ww from '@wecom/jssdk';
import {
  checkExternalUserInGroup,
  getCachedWecomVisitorProfile,
  syncExternalVisitorProfile,
} from '@/api/wecom';
import type { WecomVisitorProfile } from '@/api/wecom/types';

const AUTH_PAGE = '/pages/index/index'

const getCodeFromLocation = () => {
  if (typeof window === 'undefined') return ''

  const searchParams = new URLSearchParams(window.location.search)
  return searchParams.get('code') || ''
}

const stripOAuthCodeFromUrl = () => {
  if (typeof window === 'undefined') return
  const url = new URL(window.location.href)
  const hadOAuthParams = url.searchParams.has('code') || url.searchParams.has('state')
  if (!hadOAuthParams) return
  url.searchParams.delete('code')
  url.searchParams.delete('state')
  const nextSearch = url.searchParams.toString()
  const next = `${url.pathname}${nextSearch ? `?${nextSearch}` : ''}${url.hash}`
  window.history.replaceState({}, '', next)
}

const externalUserid = ref('');
const unionidValue = ref('');
const ownerId = ref('');
const internalUserGetPopupVisible = ref(false);
const internalUserGetJsonText = ref('');

const applyVisitorFromSyncResult = (result: Awaited<ReturnType<typeof syncExternalVisitorProfile>>) => {
  externalUserid.value = result.externalUserId
  unionidValue.value = result.profile?.unionid || ''
}

const applyVisitorFromCachedProfile = (profile: WecomVisitorProfile) => {
  externalUserid.value = profile.externalUserId || ''
  unionidValue.value = profile.unionid || ''
}

const resolveExternalChatId = () =>
  new Promise<string>((resolve, reject) => {
    ww.register({
      corpId: globalConfig.corpid,
      agentId: globalConfig.agentId,
      jsApiList: ['getCurExternalChat'],
    });

    ww.getCurExternalChat({
      success(res) {
        if (res?.chatId) {
          resolve(res.chatId);
          return;
        }
        reject(new Error('chatId missing'));
      },
      fail(err) {
        reject(err);
      },
    });
  });

const tryPrefetchOwnerInBackground = async () => {
  if (!unionidValue.value) return
  try {
    const chatId = await resolveExternalChatId();
    const outcome = await checkExternalUserInGroup(chatId, unionidValue.value);
    ownerId.value = outcome.ownerUserId;
  } catch {
    ownerId.value = '';
  }
};

const bootstrapWithCode = async (code: string) => {
  const result = await syncExternalVisitorProfile(code)
  if (!result.profile) {
    throw new Error('identity incomplete')
  }
  applyVisitorFromSyncResult(result)
  if (result.internalUserRaw) {
    internalUserGetJsonText.value = JSON.stringify(result.internalUserRaw, null, 2)
    internalUserGetPopupVisible.value = true
  }
}

const cacheLooksUsable = (cached: WecomVisitorProfile | null): cached is WecomVisitorProfile =>
  !!cached &&
  !!(cached.name || cached.mobile || cached.internalUserid || cached.externalUserId || cached.unionid)

const goReauthorize = () => {
  uni.reLaunch({ url: AUTH_PAGE })
}

onLoad(async (option) => {
  const code = (option && option.code) || getCodeFromLocation()

  if (code) {
    try {
      await bootstrapWithCode(code)
      void tryPrefetchOwnerInBackground()
    } catch {
      const cached = getCachedWecomVisitorProfile()
      if (cacheLooksUsable(cached)) {
        applyVisitorFromCachedProfile(cached)
        void tryPrefetchOwnerInBackground()
      } else {
        goReauthorize()
      }
    } finally {
      stripOAuthCodeFromUrl()
    }
    return
  }

  const cached = getCachedWecomVisitorProfile()
  if (cacheLooksUsable(cached)) {
    applyVisitorFromCachedProfile(cached)
    void tryPrefetchOwnerInBackground()
    return
  }

  goReauthorize()
})

const getQuestionPage = () => {
  const ownerQuery = ownerId.value ? `?owner=${encodeURIComponent(ownerId.value)}` : ''
  uni.navigateTo({
    url: `/subPages/pages/reportProblems/index${ownerQuery}`
  })
}
</script>

<template>
  <view class="box">
    <img class="box_bg_top" src="@/assets/bg_top.png" alt="" srcset="">
    <view class="container">
      <div class="shadow question-box" @click="getQuestionPage">
        <img class="box_img" src="@/assets/1.png" alt="" srcset="">
        <div class="box_title">问题上报</div>
      </div>
      <navigator url="/subPages/pages/reportServer/index" class="shadow">
        <img class="box_img" src="@/assets/2.png" alt="" srcset="">
        <div class="box_title">服务事项</div>
      </navigator>
      <navigator url="/subPages/pages/questions/index" class="shadow">
        <img class="box_img" src="@/assets/3.png" alt="" srcset="">
        <div class="box_title">问答库</div>
      </navigator>
    </view>
    <img class="box_bg_bottom" src="@/assets/bg_bottom.png" alt="" srcset="">

    <van-popup v-model:show="internalUserGetPopupVisible" round closeable class="user-get-popup">
      <view class="user-get-popup__header">getuserdetail 返回</view>
      <scroll-view scroll-y class="user-get-popup__content">
        <text selectable class="user-get-popup__json">{{ internalUserGetJsonText }}</text>
      </scroll-view>
    </van-popup>
  </view>

</template>

<style lang="scss" scoped>
.box{
  position: relative;
  width: 100%;
  height: 100vh;
  background: #f6f6f6;
  &_bg_top{
    width: 100%;
    position: absolute;
    top: 0;
  }
  &_bg_bottom{
    position: absolute;
    bottom: 0;
    width: 100%;
  }
  &_title{
    font-size: 16px;
    font-weight: bold;
    color: #333;
    text-align: center;
  }
  &_img{
    width: 88px;
    height: 88px;
  }
}

.container {
  padding: 5%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 20px;
  position: absolute;
  top: 130px;
  z-index: 1;
}

.container uni-navigator {
  border-radius: 8px;
  padding: 5%;
  height: 0;
  padding-bottom: 100%;
  position: relative;
  display: flex;
  justify-content: center;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  background: #fff;
}

.container uni-navigator::before {
  content: "";
  display: block;
  padding-top: 90%;
}

.container uni-navigator-content {
  position: absolute;
  top: 0; 
  left: 0; 
  right: 0; 
  bottom: 0; 
  display: flex; 
  align-items: center; 
  justify-content: center; 
}
.question-box {
  border-radius: 8px;
  padding: 5%;
  height: 0;
  padding-bottom: 100%;
  position: relative;
  display: flex;
  justify-content: center;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  background: #fff;
  flex-wrap: wrap;
  .box_title {
    width: 100%;
  }
}

.user-get-popup {
  width: 88vw;
  max-height: 75vh;
  padding: 20px 16px 16px;
  box-sizing: border-box;

  &__header {
    margin-bottom: 12px;
    padding-right: 24px;
    font-size: 16px;
    font-weight: 600;
    color: #333;
  }

  &__content {
    max-height: 60vh;
    background: #f7f8fa;
    border-radius: 8px;
    padding: 12px;
    box-sizing: border-box;
  }

  &__json {
    display: block;
    white-space: pre-wrap;
    word-break: break-all;
    font-size: 12px;
    line-height: 1.6;
    color: #333;
  }
}
</style>
