import regeneratorRuntime, { async } from './runtime';
import './polyfill'
import api from './api.js'
import extend from './util.js'
import {
  md5
} from './md5.js'

let app = null;
setTimeout(_ => app = getApp())

const getcitycode = (province, city) => {

  let code = '',
    clist = citycode.find(x => x["省"] == province.replace(/.$/, ''))
  if (clist && clist["市"]) {
    let c = clist["市"].find(x => x["市名"] == city.replace(/.$/, ''))
    if (c) code = c['编码']

  }
  return code;
}
const pvw = doc => {

  wx.showLoading({
    title: '文件加载中...',
    mask: true
  })
  wx.downloadFile({
    url: doc,
    success: ({
      tempFilePath: filePath
    }) => {
      wx.openDocument({
        filePath
      })

    },
    fail: _ => showTip("文件下载失败"),
    complete: () => {
      wx.hideLoading()
    }
  })
}

function pvw_native({
  currentTarget: {
    dataset: {
      doc
    }
  }
}) {
  pvw(doc)
}
const formatTime = date => {

  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}


const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}

function getHello() {
  let now = new Date(),
    hour = now.getHours(),
    hello;
  if (hour < 6) {
    hello = "凌晨好";
  } else if (hour < 9) {
    hello = "早上好！";
  } else if (hour < 12) {
    hello = "上午好！";
  } else if (hour < 14) {
    hello = "中午好！";
  } else if (hour < 17) {
    hello = "下午好！";
  } else if (hour < 19) {
    hello = "傍晚好！";
  } else if (hour < 22) {
    hello = "晚上好！";
  } else {
    hello = "夜里好！";
  }
  return hello;
}

function getCurrentDate() {
  var date = new Date();
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  var day = date.getDate();
  var hour = date.getHours();
  var minute = date.getMinutes();
  if (month >= 1 && month <= 9) {
    month = "0" + month;
  }
  if (day >= 0 && day <= 9) {
    day = "0" + day;
  }
  if (hour >= 0 && hour <= 9) {
    hour = "0" + hour;
  }
  if (minute >= 0 && minute <= 9) {
    minute = "0" + minute;
  }
  var data = {
    date: year + '-' + month + '-' + day,
    time: hour + ':' + minute
  }
  return data;
}

//时间判断
function getApplyTime(time) {
  var timeStamp = time.replace('T', ' ');
  timeStamp = new Date(timeStamp.replace(/-/g, '/')).getTime();
  var timeStampNow = new Date().getTime();
  var str = (timeStampNow - timeStamp) / 1000 / 60;
  var applyTime = '';
  var newDate = new Date(time.replace('T', ' '));
  if (str <= 1) {
    applyTime = '1分钟前';
  }
  if (str > 1 && str < 60) {
    applyTime = parseInt(str) + '分钟前';
  }
  if (str >= 60 && str < 60 * 24) {
    applyTime = parseInt(str / 60) + '小时前';
  }
  if (str >= 60 * 24 && str <= 60 * 24 * 2) {
    applyTime = '昨天';
  }
  if (str > 60 * 24 * 2 && str <= 60 * 24 * 5) {
    applyTime = parseInt(str / 60 / 24) + '天前';
  }
  if (str > 60 * 24 * 5 && str <= 60 * 24 * 365) {
    applyTime = time.slice(5, 10);
  }
  if (str > 60 * 24 * 365) {
    applyTime = time.slice(0, 10);
  }
  return applyTime;
}

function navigate(url, t) {
  if (!url) return;
  app.globalData.url_param = param2Obj(url)
  return new Promise(success => {
    if (t) return wx[t]({
      url,
      success
    })
    wx.navigateTo({
      url,
      success,
      fail: _ => wx.redirectTo({
        url,
        success,
        fail: _ => wx.switchTab({
          url,
          success
        })
      })
    })
  })

};

function navigate_native({
  currentTarget: {
    dataset: {
      url,
      t
    }
  }
}) {
  return navigate(url, t)
}

function navigate_auth_native({
  currentTarget: {
    dataset: {
      url,
      t
    }
  }
}) {

  return _auth()._err || navigate(url, t)
}



function showTip(title) {
  wx.showToast({
    title,
    icon: 'none'
  })
}



function telephone_native({
  currentTarget: {
    dataset: {
      num: phoneNumber
    }
  }
}) {
  wx.makePhoneCall({
    phoneNumber
  })
}
const login_err = {
  _err: {
    errmsg: '用户未登录',
    errno: 401,
    status: false
  }
},
  _auth = ({ loginTip = true, realNameTip = false } = {}) => {
    if (realNameTip) {
      if (_auth()._err) return
      if (app.globalData.userInfo && app.globalData.userInfo.isRealname == "2") {
        wx.showModal({
          title: '您尚未实名认证',
          content: '是否立即前往用户信息进行认证',
          success: ({ confirm }) => confirm && navigate('/pages/user/myInfo/index')
        })
        return {
          _err: {
            errmsg: '用户未实名认证',
            errno: 401,//后台尚未验证实名 没有相对应的errno
            status: false
          }
        }
      }

    }
    if (app.globalData.userId) return app.globalData.userId
    loginTip && wx.showModal({
      title: '提示',
      content: '帐号未登录，是否跳转至登录页面',
      showCancel: true,
      success: ({
        confirm
      }) => confirm && goLogin()
    })
    wx.hideLoading()
    return login_err
  },
  goLogin = () => navigate('/pages/login/index'),
  goHome = () => navigate('/pages/home/index', 'switchTab'),
  goSuccess = (type, id) => navigate(`/pages/success/index?type=${type}&id=${id}`, 'reLaunch'),

  request = async ({
    url,
    data = {},
    method = "get",
    loading = false,
    loadingMsg = '',
    realNameTip = false,
    loadingHide = true
  }) => {
    wx.showNavigationBarLoading()
    loading && wx.showLoading({
      title: loadingMsg || '网络请求中...',
      mask: true
    })
    if (realNameTip) {
      let { _err } = _auth({ realNameTip })
      if (_err) return _err
    }
    return await new Promise((resolve, reject) => wx.request({
      url,
      data,
      method,
      success({
        data
      }) {
        let {
          errmsg,
          errno = 0,
          errcode = 0, //兼容第三方接口
          data: _data = data
        } = data
        if (errcode || errno)
          return reject({
            errmsg,
            errno: errno || errcode
          })
        return resolve(_data || { _err: null })
      },
      fail: reject,
      complete() {
        wx.hideNavigationBarLoading()
        loading && loadingHide && wx.hideLoading()
      }
    })).catch(({
      errmsg,
      errno = -100
    }) => {
      let status = false; //标记错误信息是否需要调用者处理
      switch (errno) {
        case -1:
          showTip('系统发生未知错误 请稍后重试')
          break
        case 401:
          goLogin()
          break
        case 402://缺少参数
        case 503://签名校验错误
          showTip('api接口请求失败')
          break
        case 501://验证码错误
        case 505://查询不到验证码
          showTip('短信验证码验证失败')
          break
        case -100:
          showTip('网络请求失败')
          break
        default:
          status = true
      }
      return {
        _err: {
          errmsg,
          errno,
          status
        }
      }
    })
  },

  get = async (url, data, options) => await request({ url, data, ...options }),
  post = async (url, data, options) => await get(url, data, { ...options, method: "post" }),
  get_auth = async (url, data, options = {}) => {
    let userId = _auth(options)
    if (userId._err) return userId
    return await get(url, Object.assign({}, data, { userId }), options)
  },
  post_auth = async (url, data, options) => await get_auth(url, data, { ...options, method: "post" }),
  getUserInfo = async ({ realNameTip, loading, loadingHide = true } = {}) => {
    if (!app.globalData.userInfo) {
      let { user, _err } = await get_auth(api.getUser, null, { loading, loadingHide, loadingMsg: '获取用户信息中...', })
      if (_err) {
        logout()
        return _err.status ? _auth() : { _err }
      }
      let { identity, userName, lUsername, lInstitutionName, pPhone, lPhone, isRealname, pDocumentNum, lInstitutionNum, pDocumentType, lInstitutionType } = app.globalData.userInfo = user,
        type = identity == '0'
      //用户中心显示 -- 主要区别在于法人身份下用户中心显示公司名称或未实名 其他情况下显示法人名称
      user.viewName = type ? userName : isRealname == "1" ? lInstitutionName : '未实名'
      // 其他页面显示
      user.name = type ? userName : lUsername
      user.phone = type ? pPhone : lPhone
      user.num = type ? pDocumentNum : lInstitutionNum
      user.phone = type ? pPhone : lPhone
      user.code_type = type ? pDocumentType : lInstitutionType
    }
    app.globalData.userInfo && realNameTip && _auth({ realNameTip })
    return app.globalData.userInfo || {}
  },
  param2Obj = url => {
    const [, search] = url.split('?')
    return search ?
      JSON.parse(`{"${decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"')}"}`) : {}
  },
  get_global_param = () => {
    let t = app.globalData.url_param || {}
    app.globalData.url_param = {}
    return t;
  },
  isPhone = s => /^[1][3,4,5,6,7,8][0-9]{9}$/.test(s),
  isEmail = s => /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(s),
  form_verify = (data, verify = data.verify) => Object.keys(verify).map(k => {
    const v = data[k] || "", t = verify[k]
    if (t instanceof Function) return t(v, data)
    if (!v.length) return t
  }).filter(x => x)[0],
  getWeatherInfo = async () => {
    if (!app.globalData.weather) {
      let { wea, tem1, tem2, win, win_speed, wea_img, _err } = await get('https://www.tianqiapi.com/api/?version=v6&cityid=101180916&appid=37466447&appsecret=SjV4LAvH')
      if (_err) return _err.status && showTip('天气信息加载失败') // 免费的第三方接口 终归是靠不住的
      app.globalData.weather = {
        text: ` ${wea}  ${tem2}℃~${tem1}℃  ${win}${win_speed}`,
        img: wea_img && `https://xuesax.com/tianqiapi/skin/pitaya/${wea_img}.png`
      }
    }
    return app.globalData.weather
  }, logout = () => {
    app.globalData.userId = 0
    app.globalData.userInfo = null
    // wx.clearStorage()
    wx.removeStorageSync("userId")
  };

function inputChange({
  target: {
    dataset: {
      field
    }
  },
  detail: {
    value
  }
}) {
  this.setData({
    [field]: value
  })
}
function pickerChange({ currentTarget: { dataset: { _index } }, detail: { value } }) {
  this._pickerChange(_index, value | 0)
}

function init(context) {
  const { data } = context
  let timer, t = {}
  context._setData = context.setData.bind(context)
  context.form_verify = value => form_verify(Object.assign(data, value))
  context.setData = x => {
    clearTimeout(timer)
    Object.assign(data, Object.assign(t, x))
    timer = setTimeout(() => t = context._setData({ ...t, _verify: !context.form_verify() }) || {}, 100)
  }
  return context
}
export default {
  regeneratorRuntime,
  api,
  getHello,
  formatTime,
  formatNumber,
  getCurrentDate,
  getApplyTime,
  navigate,
  navigateBack: (delta = 1) => wx.navigateBack({
    delta
  }),
  navigate_native,
  navigate_auth_native,
  goLogin,
  goHome,
  goSuccess,
  showTip,
  telephone_native,
  request: {
    get,
    post,
    get_auth,
    post_auth
  },
  getcitycode,
  pvw,
  pvw_native,
  getUserInfo,
  extend,
  inputChange,
  pickerChange,
  md5,
  get_global_param,
  verify: {
    isPhone,
    isEmail,
    form_verify
  },
  getWeatherInfo,
  logout,
  init,
  appKey: 'ZHLL_MiniPrograms'
}