const BASE_URL = 'http://127.0.0.1:9991/api'

function apiRequest(opts) {
  return new Promise((resolve, reject) => {
    wx.request({
      ...opts,
      success: (res) => resolve(res),
      fail: (err) => reject(err)
    })
  })
}

async function ensureLogin(ctx) {
  const loginRes = await wx.login()
  const code = loginRes.code
  const res = await apiRequest({
    url: `${BASE_URL}/app/users/weixin/login`,
    method: 'POST',
    header: { 'content-type': 'application/json' },
    data: { code }
  })
  const { token, openid, nickname, avatar } = (res && res.data) || {}
  ctx.setData({ token: token || '', openid: openid || '', nickname: nickname || '', avatar: avatar || '' })
  wx.setStorageSync('TOKEN', token || '')
  wx.setStorageSync('OPENID', openid || '')
  return { token: token || '', openid: openid || '' }
}

async function callWithAuth(ctx, opts) {
  let token = ctx.data.token || wx.getStorageSync('TOKEN')
  const res = await apiRequest({
    ...opts,
    header: { ...(opts.header || {}), Authorization: `${token}` }
  })
  if (res && (res.statusCode === 401 || (res.data && res.data.code === 10103))) {
    const info = await ensureLogin(ctx)
    token = info.token
    const retry = await apiRequest({
      ...opts,
      header: { ...(opts.header || {}), Authorization: `${token}` }
    })
    return retry
  }
  return res
}

Page({
  data: { logging: false, paying: false, token: '', openid: '', orderNo: '', nickname: '', avatar: '', transactionId: '' },
  onOrderNoInput(e) { this.setData({ orderNo: e.detail.value }) },
  onTransactionIdInput(e) { this.setData({ transactionId: e.detail.value }) },
  async doLogin() {
    if (this.data.logging) return
    this.setData({ logging: true })
    try {
      await ensureLogin(this)
    } finally {
      this.setData({ logging: false })
    }
  },
  async doPay() {
    const token = this.data.token || wx.getStorageSync('TOKEN')
    const openid = this.data.openid || wx.getStorageSync('OPENID')
    const orderNo = this.data.orderNo
    if (!token) { wx.showToast({ title: '请先登录', icon: 'none' }); return }
    if (!orderNo) { wx.showToast({ title: '请输入订单号', icon: 'none' }); return }
    this.setData({ paying: true })
    try {
      const res = await callWithAuth(this, {
        url: `${BASE_URL}/app/pay/wechat/jsapi/preorder`,
        method: 'POST',
        header: {
          'content-type': 'application/json',
          'Authorization': `${token}`
        },
        data: { order_no: orderNo, openid }
      })
      const p = (res && res.data) || {}
      await wx.requestPayment({
        timeStamp: String(p.timeStamp),
        nonceStr: p.nonceStr,
        package: p.package,
        signType: p.signType,
        paySign: p.paySign
      })
      wx.showToast({ title: '支付成功' })
    } catch (e) {
      wx.showToast({ title: '支付失败', icon: 'none' })
    } finally {
      this.setData({ paying: false })
    }
  }
  ,
  async doCreateOrder() {
    const token = this.data.token || wx.getStorageSync('TOKEN')
    if (!token) { wx.showToast({ title: '请先登录', icon: 'none' }); return }
    const res = await callWithAuth(this, {
      url: `${BASE_URL}/app/orders/test/create`,
      method: 'POST',
      header: { 'Authorization': `${token}` }
    })
    const { order_no } = (res && res.data) || {}
    if (order_no) { this.setData({ orderNo: order_no }); wx.showToast({ title: '已生成', icon: 'success' }) }
  },
  async doConfirmReceive() {
    const tx = this.data.transactionId
    if (!tx) { wx.showToast({ title: '请输入交易单号', icon: 'none' }); return }
    try {
      await wx.openBusinessView({
        businessType: 'weappOrderConfirm',
        extraData: { transaction_id: tx }
      })
    } catch (e) {
      wx.showToast({ title: '调起失败', icon: 'none' })
    }
  }
})
