import React, { useState } from 'react'
import { useHistory } from 'react-router-dom'
import useRequest from '@ahooksjs/use-request/es'

import { message } from 'antd'

import { Login2pService, IPrivateEquityUser } from './Login2p.service'
import { getQueryString } from 'utils/getQueryString'
import { checkWechat } from 'utils/wxConfig'
import NewAxiosInstanceFunc from 'Service/NewAxiosInstance'

const Login2pContexts = React.createContext<
  | {
      jwt: string | undefined
      userInfo: IPrivateEquityUser | undefined
      isWechat: boolean
      inviteCode: string | undefined
      // login: (phone_number: number, password: string, next: string, unionID?: string) => Promise<void>
      logout: () => void
      loginWechatLaunch: (redirectURI: string) => void
      loginWechat: (code: string, next: string) => Promise<any>
      login2pByCode: (phone_number: string, code: string, next: string, token?: string) => Promise<any>
      getUserDetail: () => void
      getUserDetailLoading: boolean
      loginEnd: (access_token: string, next: string) => void
    }
  | undefined
>(undefined)

type ContextProviderProps = { children: React.ReactNode }

const Login2pProvider: React.FC<ContextProviderProps> = ({ children }: ContextProviderProps) => {
  const history = useHistory()
  const sm_token = localStorage.getItem('smtoken')
  // token初始值
  const [jwt, setJwt] = useState<string | undefined>(sm_token !== null ? sm_token : undefined)
  const inviteCode = getQueryString('invite_code') || sessionStorage.getItem('invite_code') || undefined
  const [userInfo, setUserInfo] = useState<IPrivateEquityUser>()
  const isWechat = checkWechat()
  const loginEnd = (access_token: string, next: string) => {
    localStorage.setItem('smtoken', access_token)
    setJwt(access_token)
    if (inviteCode) {
      sessionStorage.setItem('invite_code', inviteCode)
    }
    history.push(next)
  }

  const logout = (): void => {
    localStorage.removeItem('smtoken')
    setJwt(undefined)
    history.push(`/${inviteCode ? '?invite_code=' + inviteCode : ''}`)
    // 解决localstorage读取不到的过度方案
    history.go(0)
  }
  const loginWechatLaunch = (redirectURI: string) => {
    if (isWechat) {
      window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${
        process.env.REACT_APP_WECHART_APPID_NEW
      }&redirect_uri=${encodeURIComponent(
        redirectURI
      )}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
    } else {
      window.location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${
        process.env.REACT_APP_WECHAT_OPEN_APPID_NEW
      }&redirect_uri=${encodeURIComponent(
        redirectURI
      )}&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`
    }
  }
  const loginWechat = async (code: string, next: string) =>
    await Login2pService.loginWechat(code, isWechat ? 1 : 0)
      .then(data => {
        if (data.data.Data.Mobile) {
          loginEnd(data.data.Data.Token, next)
        } else {
          message.info('该微信号第一次授权登录平台，请先绑定手机号')
          history.push(`/login2p?smtoken=${data.data.Data.Token}&next=${next}`)
        }
      })
      .catch(error => message.error('微信登录错误'))

  const login2pByCode = async (phone_number: string, code: string, next: string, token?: string) =>
    await Login2pService.postLogin2p(phone_number, code, token, sessionStorage.getItem('invite_code') || inviteCode)
      .then(data => {
        if (data.data.Data?.Authorization) {
          setUserInfo(data.data.Data)
          loginEnd(data.data.Data?.Authorization, next)
        } else {
          message.error(data.data.Msg)
        }
      })
      .catch(error => message.error('验证码错误'))

  const { run: getUserDetail, loading: getUserDetailLoading } = useRequest(() => Login2pService.getUserDetail(jwt), {
    manual: true,
    cacheKey: 'userinfo',
    formatResult: response => response.data.Data,
    onSuccess: data => {
      if (!data) {
        NewAxiosInstanceFunc.defaults.headers.common['Authorization'] = ''
        message.error('登录状态已过期，请重新登录')
        localStorage.removeItem('smtoken')
        setJwt(undefined)
        setTimeout(() => {
          window.location.reload()
        }, 2000)
        return
      }
      // 如果有邀请码
      if (!!data.InviteShareCode) {
        sessionStorage.setItem('invite_code', data.InviteShareCode)
        history.replace(`${window.location.pathname}?invite_code=${data.InviteShareCode}`)
      }

      setUserInfo(data)
    },
    onError: e => console.log('尚未登录，您现在为游客身份～')
  })

  return (
    <Login2pContexts.Provider
      value={{
        jwt: jwt,
        userInfo: userInfo,
        isWechat: isWechat,
        inviteCode,
        // login,
        logout,
        loginWechatLaunch: loginWechatLaunch,
        loginWechat: loginWechat,
        login2pByCode: login2pByCode,
        getUserDetail: getUserDetail,
        getUserDetailLoading: getUserDetailLoading,
        loginEnd: loginEnd
      }}
    >
      {children}
    </Login2pContexts.Provider>
  )
}

const useLogin2p = () => {
  const context = React.useContext(Login2pContexts)
  if (context === undefined) {
    throw new Error('useContext must be used within a ContextProvider')
  }
  return context
}

export { Login2pProvider, useLogin2p }
