import Vue from 'vue'
import Vuex from 'vuex'
import perState from 'vuex-persistedstate'
import http from '../common/axios'
import CryptoJS from '../utils/crypto-js'
import qs from 'qs'

Vue.use(Vuex)
let agentSignURL = "", apiList = []
const store = new Vuex.Store({
  state: {
    token: "",
    corpId: "",
    baseURL: "",
    openUser: {},
    dicts: [],
    user: {},
    config: {}
  },
  mutations: {
    login(state, token) {
      state.token = token
    },
    logout(state) {
      state.token = ""
      state.openUser = {}
    },
    setUser(state, user) {
      state.user = user
    },
    setOpenUser(state, user) {
      state.openUser = user
    },
    getConfig(state, params) {
      state.config = params
    },
    bindAccount(state, params) {
      //具备解决二次登录,绑定手机,token等问题
      // http.post("/admin/user/cpBindByPhone", params, {
      http.post("/auth/wechatcp/token", {customerLogin: 1, ...params}, {
        headers: {
          Authorization: "Basic d2VjaGF0OndlY2hhdA=="
        },
        withoutToken: true
      }).then(res => {
        if (res?.access_token) {
          params?.then(res)
        } else alert(res)
      }).catch(err => alert(err))
    },
    setDicts(state, payload) {
      if (payload) {
        payload.map(p => {
          if (state.dicts.some(d => d.key == p.key)) {
            const index = state.dicts.findIndex(d => d.key == p.key)
            state.dicts.splice(index, 1)
            state.dicts.push(p)
          } else {
            state.dicts.push(p)
          }
        })
      }
    },
    redirectCode(state, url = location.href) {
      let REDIRECT_URI = encodeURIComponent(url),
          corpid = state.corpId
      const redirectTo = cid => {
        location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base#wechat_redirect'
        .replace(/CORPID/g, cid)
        .replace(/REDIRECT_URI/g, REDIRECT_URI)
      }
      if (corpid) {
        redirectTo(corpid)
      } else {
        store.dispatch("agentSign").then(() => {
          corpid = state.corpId
          redirectTo(corpid)
        })
      }
    },
    initWaterMarker(state) {
      const waterMarked = document.querySelector('#waterMarker')
      if (!waterMarked && state.user?.name) {
        const waterMarker = document.createElement('div')
        for (let i = 0; i < 200; i++) {
          let markerItem = document.createElement('div')
          markerItem.style.fontSize = '14px'
          markerItem.style.padding = '30px'
          markerItem.style.height = '80px'
          markerItem.style.transform = 'rotate(-20deg)'
          markerItem.style.flexShrink = '0'
          markerItem.innerText = state.user?.name + state.user?.phone?.slice(-4) || "未授权"

          waterMarker.appendChild(markerItem)
        }
        if (waterMarker) {
          waterMarker.id = 'waterMarker'
          waterMarker.style.position = 'absolute'
          waterMarker.style.display = 'flex'
          waterMarker.style.flexWrap = 'wrap'
          waterMarker.style.overflow = 'hidden'
          waterMarker.style.justifyContent = 'space-between'
          waterMarker.style.alignContent = 'flex-start'
          waterMarker.style.zIndex = '2'
          waterMarker.style.top = '0'
          waterMarker.style.color = 'rgba(153,153,153,.2)'
          waterMarker.style.width = '100%'
          waterMarker.style.height = '100%'
          waterMarker.style.pointerEvents = 'none'
          document.querySelector('uni-page-body')?.appendChild(waterMarker)
        }
      }
      //   canvas 方案
      //   const HiDPICanvas = (w, h, ratio) => {
      //         const PIXEL_RATIO = () => {
      //           const c = document.createElement("canvas"),
      //               ctx = c.getContext("2d"),
      //               dpr = window.devicePixelRatio || 1,
      //               bsr = ctx['webkitBackingStorePixelRatio'] ||
      //                   ctx['mozBackingStorePixelRatio'] ||
      //                   ctx['msBackingStorePixelRatio'] ||
      //                   ctx['oBackingStorePixelRatio'] ||
      //                   ctx['backingStorePixelRatio'] || 1;
      //
      //           return dpr / bsr;
      //         }
      //         if (!ratio) {
      //           ratio = PIXEL_RATIO();
      //         }
      //         const can = document.createElement("canvas");
      //         can.width = w * ratio;
      //         can.height = h * ratio;
      //         can.style.width = w + "px";
      //         can.style.height = h + "px";
      //         can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
      //         return can
      //       }
      //   if (!waterMarked && state.user?.name) {
      //     const canvas = HiDPICanvas(100, 40)
      //     canvas.style.display = 'none';
      //     let ctx = canvas.getContext("2d")
      //     ctx.rotate(-20 * Math.PI / 180);
      //     ctx.fillStyle = 'rgba(153,153,153,.3)';
      //     ctx.textAlign = 'left';
      //     ctx.textBaseline = 'middle';
      //     ctx.font = "lighter 7px 'Microsoft YaHei UI',sans-serif"
      //     ctx.fillText(state.user?.name + state.user?.phone?.slice(-4) || "未授权", 0, 30);
      //     const waterMarker = document.createElement('div')
      //     if (waterMarker) {
      //       waterMarker.id = 'waterMarker'
      //       waterMarker.style.position = 'absolute'
      //       waterMarker.style.zIndex = '2'
      //       waterMarker.style.top = '0'
      //       waterMarker.style.width = '100%'
      //       waterMarker.style.height = '100%'
      //       waterMarker.style.pointerEvents = 'none'
      //       waterMarker.style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")"
      //       document.querySelector('uni-page-body').appendChild(waterMarker)
      //     }
      //   }
    }
  },
  actions: {
    getToken(state, params) {
      const encryptByDES = password => {
        let isIos = uni.getSystemInfoSync().system.toUpperCase == 'ios'
        let key = "thanks,villcloud"
        let iv = CryptoJS.enc.Latin1.parse(key)
        let encrypted = CryptoJS.AES.encrypt(password, iv, {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.ZeroPadding
        })
        if (isIos) {
          return encodeURIComponent(encrypted.toString());
        } else {
          return encrypted.toString();
        }
      }
      return new Promise((resolve, reject) => {
        http.post("/auth/oauth/token", null, {
          withoutToken: true,
          params: {
            ...params, grant_type: 'password',
            password: encryptByDES(params.password)
          },
          headers: {
            Authorization: "Basic d2VjaGF0OndlY2hhdA=="
          }
        }).then(res => {
          if (res?.access_token) {
            state.commit("login", [res?.token_type, res?.access_token].join(" ").trim())
            state.dispatch("getAccount")
            resolve()
          }
        }).catch(err => {
          uni.showToast({title: err, icon: 'none'})
          reject()
        })
      })
    },
    getCode(store, url) {
      if (store.state.config?.corpid) {
        store.commit('redirectCode', url)
      } else {
        store.dispatch('agentSign').then(() => {
          store.commit('redirectCode', url)
        })
      }
    },
    getAccount(state) {
      //获取企业微信后台账号信息
      return http.post("/admin/user/detail-phone").then(res => {
        if (res?.code == 0) {
          state.commit('setUser', res.data)
        }
      })
    },
    getUserInfo(state, code) {
      if (code) {
        return http.post("/app/wxcp/portal/getUserInfo", null, {
          params: {code}, withoutToken: true
        }).then(res => {
          if (res?.code == 0) {
            state.commit("setOpenUser", res.data)
          }
        })
      } else {
        return http.post("/app/wxcp/wxuser/getUserInfoByToken")
        .then(res => {
          if (res?.code == 0) {
            state.commit("setOpenUser", res.data)
          }
        })
      }
    },
    agentSign(state, params) {
      let url = window.location.href,
          {corpId, suiteId} = state.state.config
      if (agentSignURL == url) {
        return Promise.resolve()
      } else {
        agentSignURL = url
        if (qs.parse(location.search)?.corpId) {
          params = {
            corpId: qs.parse(location.search).corpId
          }
        } else {
          params = params || {corpId, suiteId}
        }
        return http.post("/app/wxcp/portal/agentSign", null, {
          params: {...params, url}
        }).then(res => {
          if (res?.data) {
            let config = {
              ...params,
              debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
              beta: true,// 必须这么写，否则wx.invoke调用形式的jsapi会有问题
              corpid: res.data.corpid, // 必填，企业微信的corpid，必须与当前登录的企业一致
              agentid: res.data.agentId, // 必填，企业微信的应用id （e.g. 1000247）
              timestamp: Number(res.data.timestamp), // 必填，生成签名的时间戳
              nonceStr: res.data.nonceStr, // 必填，生成签名的随机串
              signature: res.data.signature,// 必填，签名，见 附录-JS-SDK使用权限签名算法
              ...res.data,
            }
            state.commit("getConfig", config)
            return config
          }
        }).catch(err => {
          console.error(err)
        })
      }
    },
    injectJWeixin(state, ops) {
      const inject = (jsApiList, config = state.state.config) => new Promise((resolve, reject) => {
        setTimeout(() => {
          let sdk = wx?.agentConfig ? wx : jWeixin
          sdk?.agentConfig({
            ...config, jsApiList,
            success: res => resolve(res),
            fail: err => {
              console.error(err)
              reject(err)
            }
          })
        }, 500)
      })
      return new Promise((resolve, reject) => {
        state.dispatch("agentSign").then(config => {
          if (typeof ops == "object") {
            ops?.map(api => {
              if (!apiList?.includes(api)) apiList.push(api)
            })
          } else {
            if (!apiList?.includes(ops)) apiList.push(ops)
          }
          inject(apiList, config).then(r => resolve(r)).catch(err => reject(err))
        })
      })
    },
    wxInvoke(state, op) {
      setTimeout(() => {
        let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
        sdk?.invoke(op?.[0], op?.[1], op?.[2])
      }, 500)
    },
    previewFile(state, op) {
      if (window.navigator.userAgent.indexOf("Windows NT") > -1) {
        uni.showToast({
          title: "企业微信暂不支持PC端的预览文件!",
          icon: 'none'
        })
      } else {
        state.dispatch("injectJWeixin", "previewFile").then(() => {
          setTimeout(() => {
            let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
            sdk?.invoke('previewFile', {...op}, res => {
              console.log(res)
            })
          }, 500)
        })
      }
    },
    closeAgent(state) {
      state.dispatch("injectJWeixin", "closeWindow").then(() => {
        setTimeout(() => {
          let sdk = typeof wx?.closeWindow == 'function' ? wx : jWeixin
          sdk?.closeWindow()
        }, 500)
      })
    },
    selectEnterpriseContact(state, params) {
      return new Promise(resolve => {
        state.dispatch("injectJWeixin", "selectEnterpriseContact").then(() => {
          setTimeout(() => {
            let sdk = typeof wx?.invoke == 'function' ? wx : jWeixin
            sdk?.invoke("selectEnterpriseContact", {
              fromDepartmentId: -1,
              mode: "multi",
              type: ["user"],
              ...params
            }, res => {
              if (res.err_msg == "selectEnterpriseContact:ok") {
                if (typeof res.result == 'string') {
                  res.result = JSON.parse(res.result)
                }
                resolve(res.result)
              }
            })
          }, 500)
        })
      })
    },
  },
  getters: {
    getDict: state => key => {
      if (key && state.dicts.length > 0) {
        return state.dicts.find(e => e.key == key)
      }
      return null
    }
  },
  plugins: [perState({
    storage: {
      getItem: key => uni.getStorageSync(key),
      setItem: (key, value) => uni.setStorageSync(key, value),
      removeItem: key => uni.removeStorageSync(key)
    }
  })]
})

export default store
