//index.js
//获取应用实例
const app = getApp();
const {
    warn,
    request
} = require("../../utils/util.js");
const log = require("../../utils/log.js");
const { shortTail, logWeapp } = require("../../utils/htyWeappLog.js");

// 0 => 已注册用户 1 => 新用户(已授权) 2 => 匿名用户(拒绝授权)
// keep synchronous with types.ts file in htymusic
const UserStates = {
    Registered: 2,
    Authorized: 1,
    Anonymous: 0
}

const logInstance = (instance, label) => {
  Object.entries(instance.data).forEach(([key, value]) => {
    log.info(label + key, value);
  });
};

const statusName = (status) => {
    if (status === UserStates.Registered) return 'Registered'
    if (status === UserStates.Authorized) return 'Authorized'
    if (status === UserStates.Anonymous) return 'Anonymous'
    return String(status)
}

const setUrl = (instance, status) => {
    logInstance(instance, 'set url');
    logWeapp('setUrl', { status: statusName(status), unionidTail: shortTail(instance.data.unionid), ready: true })
    let { unionid, meta, openid, tongzhi_id, page_path } = instance.data;
    let params = [
        'unionid=' + unionid, "openid=" + openid, "ts=" + app.globalData.timestamp, 'status=' + status
    ];
    if (meta) {
        let {nickName, avatarUrl} = meta;
        params.push('nickName=' + nickName, 'avatarUrl=' + avatarUrl);
    }
    // add scene value to check if nav by wx message
    params.push("scene=" + app.globalData.scene)
    if (tongzhi_id) {
        params.push('tongzhi_id=' + tongzhi_id);
    }
    if (page_path) {
      params.push('page_path=' + page_path);
    }
    log.info('set-url', params.join("&"))
    instance.setData({
        ready: true,
        url: `${app.globalData.server}?${params.join('&')}`
    })
}

const login_with_unionid = (instance) => {
    wx.showLoading();

    let unionid = wx.getStorageSync('unionid')

    logWeapp('login_with_unionid_start', { unionidTail: shortTail(unionid) })

    wx.removeStorageSync('token')
    request({
        url: `${app.globalData.api}/api/v1/uc/login2_with_unionid`,
        method: 'GET',
        header: { HtyHost: app.globalData.domain, unionid },
        success: function (res) {
            var statusCode = res.statusCode
            var body = res.data || {}
            var r = body.r
            var d = body.d
            var e = body.e
            if (r)  {
                logWeapp('login_with_unionid_ok', {
                    httpStatus: statusCode,
                    tokenLen: typeof d === 'string' ? d.length : 0,
                    unionidTail: shortTail(unionid)
                })
                wx.setStorageSync('token', d)
                instance.setData({token: d}, () => setUrl(instance, UserStates.Registered))
            } else {
                var meta = wx.getStorageSync('user-meta');
                logWeapp('login_with_unionid_fail', {
                    httpStatus: statusCode,
                    r: r,
                    e: String(e || '').slice(0, 300),
                    hasMeta: !!meta,
                    unionidTail: shortTail(unionid)
                })
                if (meta) {
                    instance.setData({meta}, () => setUrl(instance, UserStates.Authorized))
                } else {
                    logWeapp('login_with_unionid_stuck_native', {
                        reason: 'r_false_no_meta',
                        hint: 'shows_start_button_until_getUserProfile'
                    })
                }
            }
        },
        fail: function (err) {
            logWeapp('login_with_unionid_request_fail', { err: String(err && err.errMsg ? err.errMsg : err).slice(0, 300) })
        },
        complete: function() {
            wx.hideLoading()
        }
    })
}

const login = (instance) => {
    logInstance(instance, "login start -> ")
    wx.showLoading();
    wx.removeStorageSync('unionid')
    wx.login({
        success: function ({ code, errMsg }) {
            log.info("login succeed -> code: ", code);
            if (code) {
                log.info('wx login code...', code);
                request({
                    url: `${app.globalData.api}/api/v1/uc/wx_login`,
                    method: 'POST',
                    header: { 'HtyHost': app.globalData.domain },
                    data: { code },
                    success: function (res) {
                        var statusCode = res.statusCode
                        var body = res.data || {}
                        var r = body.r
                        var d = body.d
                        var e = body.e
                        if (r) {
                            let { unionid, openid } = d;
                            logWeapp('wx_login_ok', {
                                httpStatus: statusCode,
                                unionidTail: shortTail(unionid),
                                openidTail: shortTail(openid)
                            })
                            if (unionid) {
                                wx.setStorageSync("unionid", unionid);
                                wx.setStorageSync("openid", openid);
                                instance.setData({unionid, openid}, () => login_with_unionid(instance));
                            } else {
                                warn("微信登录失败！")
                                logWeapp('wx_login_ok_but_no_unionid', { httpStatus: statusCode })
                            }
                        } else {
                            warn(e);
                            logWeapp('wx_login_fail', { httpStatus: statusCode, e: String(e || '').slice(0, 300) });
                        }
                    },
                    fail: function (err) {
                        logWeapp('wx_login_request_fail', { err: String(err && err.errMsg ? err.errMsg : err).slice(0, 300) })
                    },
                });
            } else {
                log.info('获取用户登录态失败！' + errMsg);
            }
        },
        complete: function() {
            wx.hideLoading()
        }
    });
};

const init = (instance, {unionid, token}) => {
  logInstance(instance, "init -> ");
  var tokenLen = token ? String(token).length : 0
  if (unionid) {
      if (token) {
        logWeapp('init_branch', {
            branch: 'unionid_and_token_skip_api',
            unionidTail: shortTail(unionid),
            tokenLen: tokenLen,
            note: 'webview_gets_status_Registered_without_validating_token_here'
        })
        setUrl(instance, UserStates.Registered)
      } else {
        logWeapp('init_branch', { branch: 'unionid_no_token_login_with_unionid', unionidTail: shortTail(unionid) })
        login_with_unionid(instance)
      }
  } else {
    logWeapp('init_branch', { branch: 'no_unionid_wx_login' })
    login(instance)
  }
}

Page({
    data: {
        url: '', ready: false, timestamp: 0, meta: null,
        token: '', openid: '', tongzhi_id: '', page_path: ''
    },
    getUserProfile() {
        let instance = this;
        logWeapp('getUserProfile_start', {})
        wx.getUserProfile({
            desc: '请求获取您的微信信息',
            success: function({userInfo}) {
                wx.setStorageSync('user-meta', userInfo);
                logWeapp('getUserProfile_ok', { nickLen: userInfo && userInfo.nickName ? String(userInfo.nickName).length : 0 })
                instance.setData({meta: userInfo}, () => setUrl(instance, UserStates.Authorized))
            },
            fail: function(err) {
                console.log('get profile error...', err);
                logWeapp('getUserProfile_fail', { err: String(err && err.errMsg ? err.errMsg : err).slice(0, 200) })
                setUrl(instance, UserStates.Anonymous)
            }
        });

    },
    onShareAppMessage({from, target, webViewUrl}) {
        log.info("share", [from, target, webViewUrl].join(" | "))
        let pathname = webViewUrl.replace(app.globalData.server, '');
        // 分享勿带 WebView 入口里的 unionid/openid/status 等，避免接收方串号
        if (pathname && pathname !== '/') {
          try {
            const q = pathname.indexOf('?')
            let base = pathname
            let search = ''
            if (q === 0) {
              base = '/'
              search = pathname.slice(1)
            } else if (q > 0) {
              base = pathname.slice(0, q) || '/'
              search = pathname.slice(q + 1)
            }
            if (search) {
              const sp = new URLSearchParams(search)
              ;['unionid', 'openid', 'status', 'nickName', 'avatarUrl', 'ts', 'scene'].forEach((k) => sp.delete(k))
              const rest = sp.toString()
              pathname = rest ? `${base}?${rest}` : (base || '/')
            }
          } catch (e) {
            log.info('share strip query skip', e)
          }
          pathname = pathname === '/' ? '/' : encodeURIComponent(pathname)
        }
        const promise = new Promise(resolve => {
          setTimeout(() => {
            resolve({
              title: '慧添翼课后辅导系统',
              path: `/pages/index/index?page_path=${pathname}`
            })
          }, 2000)
        })
        return {
            title: '慧添翼课后辅导系统',
            path: `/pages/index/index?page_path=${pathname}`,
            promise
        }
    },
    onLoad (options) {
        log.info('load-options', options)
        this.setData({
          tongzhi_id: options.hty_tongzhi_id || "",
          page_path: options.page_path
        })
    },
    onShow() {
        logInstance(this, 'on show')
        let { unionid, openid, meta, token } = this.data;
        unionid = unionid || wx.getStorageSync("unionid");
        openid = openid || wx.getStorageSync('openid');
        meta = meta || wx.getStorageSync('user-meta');
        token = token || wx.getStorageSync('token');
        logWeapp('onShow_storage', {
            unionidTail: shortTail(unionid),
            openidTail: shortTail(openid),
            tokenLen: token ? String(token).length : 0,
            hasMeta: !!meta,
            readyBefore: this.data.ready,
            scene: app.globalData.scene,
            page_path: this.data.page_path ? 'yes' : ''
        })
        this.setData({unionid, openid, meta, token}, () => init(this, this.data));        
    }
});
