import { queryCurrentUser, queryPermData } from './services/user'
import { history, createSearchParams } from '@umijs/max'
import RightContent from '@/components/RightContent'
import { message, notification } from 'antd'
import logo from '../public/logo.svg'
import { getToken } from '@/utils/auth'
import { tryChangeWorkStatus } from './components/RightContent/Book'
import { getAuthCache, setAuthCache } from './utils/auth'
import { LAYOUT_COLLAPSED_KEY } from './utils/cache/cacheEnum'
import consts from './consts'
import ModalStore from './components/ModalStore'
import MessageDetail from './pages/Hr/Notification/components/MessageDetail'
import defaultSettings from '../config/defaultSettings'
import type { ErrorShowType, RequestConfig } from '@umijs/max'

const loginPath = '/user/login'
export async function getInitialState() {
  // 如果是登录页面，不执行
  const fetchUserInfo = async () => {
    try {
      const res = await queryCurrentUser()
      return res.data
    } catch (error) {
      history.push(loginPath)
    }
    return undefined
  }

  const fetchPermData = async () => {
    try {
      const res = await queryPermData()
      return res.data
    } catch (error) {
      message.error('获取数据权限失败，请联系管理员')
    }
    return {}
  }
  // 如果是登录页面，不执行
  if (history.location.pathname !== loginPath) {
    const userInfo = (await fetchUserInfo()) || {}
    const permData = (await fetchPermData()) || {}
    const collapsed = getAuthCache(LAYOUT_COLLAPSED_KEY) || false
    return {
      fetchUserInfo,
      fetchPermData,
      permData,
      ...userInfo,
      settings: { ...defaultSettings, collapsed, defaultCollapsed: collapsed }
    }
  }
  return {
    fetchUserInfo,
    fetchPermData,
    settings: { ...defaultSettings }
  }
}

export const layout = ({ initialState, setInitialState }) => {
  const onCollapse = collapsed => {
    setInitialState({ ...initialState, settings: { ...initialState.settings, collapsed } })
    setAuthCache(LAYOUT_COLLAPSED_KEY, collapsed)
  }

  return {
    logo,
    rightContentRender: () => (
      <ModalStore _modalMap={{ D_NOTICE_DETAIL: MessageDetail }}>
        <RightContent />
      </ModalStore>
    ),
    disableContentMargin: false,
    waterMarkProps: initialState.currentUser && {
      fontColor: 'rgba(0,0,0,.1)',
      offsetTop: 200,
      content: `${initialState.currentUser?.username}  ${initialState.currentUser?.telephone.slice(-4)}`
    },

    onPageChange: async location => {
      // 如果没有登录，重定向到 login
      if (!initialState?.currentUser?.staffId && location.pathname !== loginPath) {
        history.replace({
          pathname: loginPath,
          search: createSearchParams({ redirect: window.location.pathname }).toString()
        })
      } else {
        location.pathname !== loginPath &&
          tryChangeWorkStatus(initialState?.currentUser?.staffId, location.pathname)
      }
    },
    childrenRender: children => <ModalStore>{children}</ModalStore>,
    ...initialState?.settings,
    breakpoint: false,
    onCollapse
  }
}

let notificationLimit = 0 // 最大1
const errorHandler = (error: any, opts: any) => {
  if (opts?.skipErrorHandler) throw error
  if (error.name === 'BizError') {
    const errorInfo = error.info
    if (errorInfo) {
      if (notificationLimit >= 1) {
        return
      }
      const { errorMessage = '请求失败', showType, errorCode } = info
      if (consts.TOKEN_INVALID_CODE.includes(errorCode) && window.location.pathname !== loginPath) {
        history.replace({
          pathname: loginPath,
          search: createSearchParams({ redirect: window.location.pathname }).toString()
        })
      }
      switch (showType) {
        case ErrorShowType.ERROR_MESSAGE:
          message.error(errorMessage)
          break
        case ErrorShowType.WARN_MESSAGE:
          message.warn(errorMessage)
          break
        case ErrorShowType.NOTIFICATION:
          if (!notificationLimit) {
            const title = consts.TOKEN_INVALID_CODE.includes(errorCode) ? '用户信息过期' : '请求失败'
            notification.error({
              message: title,
              description: errorMessage
            })
            notificationLimit++
          }
          break
        default:
          break
      }
    } else if (error.response) {
      // Axios 的错误
      // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
      notification.error({
        description: `状态码为${error.response.status}, 请联系管理员进行处理`,
        message: '请求异常'
      })
    } else {
      // 请求已经成功发起，但没有收到响应
      // 或请求根本没有发送出去
      notification.error({
        description: '您的网络发生异常，无法连接服务器',
        message: '网络异常'
      })
    }
  }
}
const authHeaderInterceptor = (options: any) => {
  const token = getToken()
  if (token) {
    // 在白名单里的请求放过
    if (consts.TOKEN_WHITE_LIST.includes(options.url)) {
      return options
    }
    options.headers[consts.TOKEN_HEADER] = `bearer ${token}`
  }
  return options
}

export const request: RequestConfig = {
  errorConfig: {
    // 错误抛出
    errorThrower: (res: ResponseStructure) => {
      const { data, code, msg, showType } = res
      if (code !== consts.RET_CODE.SUCCESS) {
        const error: any = new Error(errorMessage)
        error.name = 'BizError'
        error.info = { errorCode: code, errorMessage: msg, showType, data }
        throw error // 抛出自制的错误
      }
    },
    errorHandler
  },
  baseURL: consts.PREFIX_URL,
  requestInterceptors: [authHeaderInterceptor],
  responseInterceptors: [
    response => {
      // 处理notificationLimit，请求成功应重置
      if (
        notificationLimit >= 1 &&
        response.status === 200 &&
        response.data?.code === consts.RET_CODE.SUCCESS
      ) {
        notificationLimit = 0
      }
      const { code = -1 } = response?.data || {}
      if (code !== consts.RET_CODE.SUCCESS) {
        return Promise.reject(response?.data)
      }
      return Promise.resolve(response)
    }
  ]
}
