import { getRoutesConfig, login, V4Login } from '@vue2-client/services/user'
import { loadRoutes, funcToRouter } from '@vue2-client/utils/routerUtil'
import JSEncrypt from 'jsencrypt'
import { positions } from '@vue2-client/mock/common'
import { timeFix } from '@vue2-client/utils/util'
import { indexedDB } from '@vue2-client/utils/indexedDB'
import Vue from 'vue'
import { message } from 'ant-design-vue'
import {
  ACCESS_TOKEN,
  V4_ACCESS_TOKEN,
  V4_SESSION_KEY,
} from '@vue2-client/store/mutation-types'
import { setAuthorization } from '@vue2-client/utils/request'
import { loginGen } from '@vue2-client/base-client/plugins/GetLoginInfoService'
import { RSA_PRIVATE_KEY } from '@vue2-client/constants/crypto'
import EncryptUtil from '@vue2-client/utils/EncryptUtil'
// 认证类型
const AUTH_TYPE = {
  BEARER: 'Bearer',
  SinglePage: 'SinglePage',
  BASIC: 'basic',
  AUTH1: 'auth1',
  AUTH2: 'auth2',
}

export function checkSingleAuthorization(authType = AUTH_TYPE.BEARER, token) {
  switch (authType) {
    case AUTH_TYPE.BEARER:
      if (localStorage.getItem(V4_ACCESS_TOKEN)) {
        return true
      }
      break
    case AUTH_TYPE.SinglePage:
      return token === localStorage.getItem('SinglePage_TOKEN')
    case AUTH_TYPE.BASIC:
    case AUTH_TYPE.AUTH1:
    case AUTH_TYPE.AUTH2:
    default:
      break
  }
  return false
}

function setSingleAuthorization(auth, authType = AUTH_TYPE.BEARER) {
  switch (authType) {
    case AUTH_TYPE.BEARER:
      localStorage.setItem(V4_ACCESS_TOKEN, 'Bearer ' + auth.token)
      break
    case AUTH_TYPE.BASIC:
    case AUTH_TYPE.AUTH1:
    case AUTH_TYPE.AUTH2:
    default:
      break
  }
}

function setAccessToken(data) {
  if (data) {
    localStorage.setItem(ACCESS_TOKEN, data)
    let timestamp = new Date().getTime() // 当前的时间戳
    timestamp = timestamp + 12 * 60 * 60 * 1000
    // 格式化时间获取年月日, 登陆过期时间
    const dateAfter = new Date(timestamp)
    setSingleAuthorization({ token: data, expireAt: dateAfter })
  }
}

function afterGeneral(result, options) {
  return new Promise((resolve) => {
    const { password, store } = options
    const user = Object.assign(
      {
        id: result.id,
        username: result.ename,
        password: password,
        name: result.name,
        avatar:
          'https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png',
        address: '西安市',
        position: positions[0],
      },
      result
    )
    const setUser = store._mutations['account/setUser'][0]
    const setPermissions = store._mutations['account/setPermissions'][0]
    const setRoles = store._mutations['account/setRoles'][0]
    setUser(user)
    setPermissions([{ id: 'queryForm', operation: ['add', 'edit'] }])
    setRoles([{ id: 'admin', operation: ['add', 'edit', 'delete'] }])
    loadRoutes(funcToRouter(user.functions))
    // 每次重新登录时，清除indexedDB缓存
    indexedDB.clear()
    message.success(timeFix().CN + `，${result.name} 欢迎回来`, 3)
    resolve()
  })
}

function afterLogin(res, options) {
  const { name, password, store, router, pathname } = options
  const setting = store.state.setting
  const loginRes = res.states
  if (loginRes === '登录成功') {
    const encrypt = new JSEncrypt()
    encrypt.setPublicKey(
      'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqPvovSfXcwBbW8cKMCgwqNpsYuzF8RPAPFb7LGsnVo44JhM/xxzDyzoYtdfNmtbIuKVi9PzIsyp6rg+09gbuI6UGwBZ5DWBDBMqv5MPdOF5dCQkB2Bbr5yPfURPENypUz+pBFBg41d+BC+rwRiXELwKy7Y9caD/MtJyHydj8OUwIDAQAB'
    )
    const data = encrypt.encrypt(
      JSON.stringify({ username: name, password: password })
    )
    // 获取路由配置
    getRoutesConfig(data, setting.routeName)
      .then((result) => {
        Vue.$login
          .login(result)
          .then(() => {
            // V3任何情况首位加入资源管理
            const resourceManageMain = {
              name: '资源管理',
              icon: 'api',
              position: 1,
              link: 'resourceManageMain',
            }
            result.functions.unshift(resourceManageMain)
            afterGeneral(result, options)
            setAccessToken(data)
            if (result.deps === '用户工单登记') {
              router.push(setting.ticketPage).catch(() => {
              })
            } else {
              console.log('去往的页面', pathname)
              router.push(pathname).catch(() => {
              })
            }
          })
          .finally(() => {
          })
      })
      .catch((res) => {
      })
  }
}

function afterLoginV4(res, option) {
  const { router, pathname } = option
  setV4AccessToken(res)
  let data = res.resources
  if (data.data) {
    data = data.data
  }
  loginGen(data).then(() => {
    afterGeneral(data, option).then(() => {
      router.push(pathname)
    })
  }).catch(res => {
  }).finally(() => {
  })
}

function unwrapV4LoginPayload(res) {
  if (!res || typeof res !== 'object') return null
  if (res.access_token !== undefined && res.access_token !== null) return res
  if (
    res.data &&
    typeof res.data === 'object' &&
    res.data.access_token !== undefined &&
    res.data.access_token !== null
  ) {
    return res.data
  }
  return null
}

function getWebConfigFromStorage() {
  try {
    const str = localStorage.getItem(process.env.VUE_APP_WEB_CONFIG_KEY)
    return str ? JSON.parse(str) : {}
  } catch {
    return {}
  }
}

/** 解析登录接口返回的 session 并写入 v4-session-key（受 webConfig.requestEncrypt 控制） */
export function setV4SessionKey(res) {
  const webConfig = getWebConfigFromStorage()
  if (!res?.session || !webConfig?.setting?.requestEncrypt) return
  const sessionKey = EncryptUtil.RSADecryptRaw(res.session, RSA_PRIVATE_KEY)
  if (sessionKey) localStorage.setItem(V4_SESSION_KEY, sessionKey)
}

export function setV4AccessToken(res) {
  const payload = unwrapV4LoginPayload(res)
  if (!payload?.access_token) return
  localStorage.setItem(ACCESS_TOKEN, payload.access_token)
  let timestamp = new Date().getTime() // 当前的时间戳
  timestamp += (payload.expire ?? 0) * 60 * 1000
  const dateAfter = new Date(timestamp)
  setAuthorization({ token: payload.access_token, expireAt: dateAfter })
  setV4SessionKey(payload)
}

export function startLogin(options) {
  const { name, password, store } = options
  const setting = store.state.setting
  switch (setting.compatible) {
    case 'V2':
    case 'V3': {
      login(name, password)
        .then((res) => {
          afterLogin(res, options)
        })
        .catch((msg) => {
        })
      break
    }
    case 'V4': {
      V4Login(name, password, '智慧燃气').then((res) => {
        afterLoginV4(res, options)
      }).catch(msg => {
      })
      break
    }
  }
}
