<script setup lang="ts">
import { onMounted, watch } from 'vue'

const props = defineProps<{
  url: string
  title?: string
  desc?: string
  imgUrl?: string
}>()

// 仅在客户端挂载后执行，避免 SSR 阶段访问 window/location
onMounted(async () => {
  try {
    await loadWxSdk()
    const { appId, timestamp, nonceStr, signature } = await getWxConfig()
    setupShare(appId, timestamp, nonceStr, signature)
  } catch (err) {
    console.error('[WxShare] init error:', err)
  }
})

// 路径变化时，重新获取签名并刷新分享数据（适配 SPA 场景）
watch(() => props.url, async (newUrl, oldUrl) => {
  if (!newUrl || newUrl === oldUrl) return
  try {
    await loadWxSdk()
    const { appId, timestamp, nonceStr, signature } = await getWxConfig()
    setupShare(appId, timestamp, nonceStr, signature)
  } catch (err) {
    console.error('[WxShare] reconfig error:', err)
  }
})

type WeChat = {
  config: (cfg: {
    debug?: boolean
    appId: string
    timestamp: number
    nonceStr: string
    signature: string
    jsApiList: string[]
  }) => void
  ready: (cb: () => void) => void
  error: (cb: (e: unknown) => void) => void
  updateTimelineShareData: (opts: { title: string, link: string, imgUrl: string, success?: () => void }) => void
  updateAppMessageShareData: (opts: { title: string, desc: string, link: string, imgUrl: string, success?: () => void }) => void
}

function getWx(): WeChat | undefined {
  if (typeof window === 'undefined') return undefined
  const w = window as unknown as { wx?: WeChat }
  return w.wx
}

function loadWxSdk(): Promise<void> {
  if (typeof window === 'undefined') return Promise.resolve()
  if (getWx()) return Promise.resolve()
  return new Promise((resolve, reject) => {
    const existing = document.getElementById('wx-jssdk') as HTMLScriptElement | null
    if (existing && getWx()) return resolve()
    const script = existing ?? document.createElement('script')
    if (!existing) {
      script.id = 'wx-jssdk'
      script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js'
      script.async = true
      script.onload = () => resolve()
      script.onerror = () => reject(new Error('Failed to load jweixin.js'))
      document.head.appendChild(script)
    } else {
      script.onload = () => resolve()
      script.onerror = () => reject(new Error('Failed to load jweixin.js'))
    }
  })
}

async function getWxConfig(): Promise<{ appId: string, timestamp: number, nonceStr: string, signature: string }> {
  const currentUrl = encodeURIComponent((location.href.split('#')[0]) || location.href)
  return await $fetch('/api/wechat/wx-config', { params: { url: currentUrl } })
}

function setupShare(appId: string, timestamp: number, nonceStr: string, signature: string) {
  const wx = getWx()
  if (!wx) return
  const shareTitle = props.title || document.title || ''
  const shareDesc = props.desc || document.title || ''
  const shareLink = props.url
  const shareImg = props.imgUrl || '/images/default-blog.jpg'

  wx.config({
    debug: false,
    appId,
    timestamp,
    nonceStr,
    signature,
    jsApiList: ['updateTimelineShareData', 'updateAppMessageShareData']
  })

  wx.ready(() => {
    console.log('[WxShare] wx.ready')
    wx.updateTimelineShareData({
      title: shareTitle,
      link: shareLink,
      imgUrl: shareImg,
      success: () => {}
    })
    wx.updateAppMessageShareData({
      title: shareTitle,
      desc: shareDesc,
      link: shareLink,
      imgUrl: shareImg,
      success: () => {}
    })
  })

  wx.error((e) => {
    console.error('[WxShare] wx.error:', e)
  })
}
</script>

<template>
  <div style="display: none" />
  <!-- 该组件无可视内容，仅用于初始化微信分享 -->
</template>
