import type { Settings as LayoutSettings } from '@ant-design/pro-layout'
import { PageLoading } from '@ant-design/pro-layout'
import { notification } from 'antd'
import type { RequestConfig, RunTimeLayoutConfig } from 'umi'
import { getIntl, getLocale, history } from 'umi'
import RightContent from '@/components/RightContent'
import Footer from '@/components/Footer'
import type { RequestOptionsInit, ResponseError } from 'umi-request'
import { currentUser as queryCurrentUser } from './services/user/api'
import consts from './utils/consts'

const isDev = process.env.NODE_ENV === 'development'
const loginPath = '/user/login'

/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
  loading: <PageLoading />
}

/**
 * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
 * */
export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>
  currentUser?: API.CurrentUser
  menuList?: API.MenuListItem[]
  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>
}> {
  // eslint-disable-next-line react-hooks/rules-of-hooks
  // 获取用户信息
  const fetchUserInfo = async () => {
    const currentUser = await queryCurrentUser()
    return currentUser
  }

  // 如果是登录页面，不执行
  if (history.location.pathname !== loginPath) {
    try {
      const { data: currentUser } = await fetchUserInfo()
      return {
        fetchUserInfo,
        menuList: currentUser.menus,
        currentUser: currentUser.staff,
        settings: {}
      }
    } catch (error) {
      history.push(loginPath)
    }
    return undefined
  }
  return {
    settings: {}
  }
}

const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
  const token = window.localStorage.getItem('TOKEN_ID')
  // 如果是登录页面，不执行
  if (!token && history.location.pathname !== loginPath) {
    return history.push(loginPath)
  }
  const authHeader = { Authorization: `Bearer ${JSON.parse(token)}` }
  return {
    url: `${url}`,
    options: { ...options, interceptors: true, headers: authHeader }
  }
}

/**
 * 异常处理程序
 const codeMessage = {
    200: '服务器成功返回请求的数据。',
    201: '新建或修改数据成功。',
    202: '一个请求已经进入后台排队（异步任务）。',
    204: '删除数据成功。',
    400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
    401: '用户没有权限（令牌、用户名、密码错误）。',
    403: '用户得到授权，但是访问是被禁止的。',
    404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
    405: '请求方法不被允许。',
    406: '请求的格式不可得。',
    410: '请求的资源被永久删除，且不会再得到的。',
    422: '当创建一个对象时，发生一个验证错误。',
    500: '服务器发生错误，请检查服务器。',
    502: '网关错误。',
    503: '服务不可用，服务器暂时过载或维护。',
    504: '网关超时。',
 };
 * @see https://beta-pro.ant.design/docs/request-cn
 */
export const request: RequestConfig = {
  errorHandler: (error: ResponseError) => {
    const { messages } = getIntl(getLocale())
    const { response } = error

    if (response && response.status) {
      const { status, statusText, url } = response
      const requestErrorMessage = messages['app.request.error']
      const errorMessage = `${requestErrorMessage} ${status}: ${url}`
      const errorDescription = messages[`app.request.${status}`] || statusText
      notification.error({
        message: errorMessage,
        description: errorDescription
      })
    }

    if (!response) {
      notification.error({
        description: '您的网络发生异常，无法连接服务器',
        message: '网络异常'
      })
    }
    throw error
  },
  middlewares: [
    async (ctx, next) => {
      await next()
      const { req, res } = ctx
      // @ts-ignore
      if (req.options?.skipErrorHandler) {
        return
      }
      const errorAdaptor = req.options?.errorConfig.adaptor || (resData => resData)
      const { options } = req
      const { getResponse } = options
      const resData = getResponse ? res.data : res
      const errorInfo = errorAdaptor(resData, ctx)
      if (resData.code !== consts.RET_CODE.SUCCESS) {
        // 抛出错误到 errorHandler 中处理
        const error: ResponseError = new Error(errorInfo.errorMessage)
        error.name = 'BizError'
        error.data = resData
        error.info = errorInfo
        error.response = res
        throw error
      }
    }
  ],
  prefix: '/backstage',
  errorConfig: {
    adaptor: resData => {
      return {
        // success: resData.code === consts.RET_CODE.SUCCESS,
        data: resData.data,
        errorCode: resData.code,
        errorMessage: resData.msg
      }
    }
  },
  responseInterceptors: [
    async (response, options) => {
      const errorAdaptor = options?.errorConfig.adaptor || (resData => resData)
      const res = await response.clone().json()
      const { getResponse } = options
      const resData = getResponse ? res.data : res
      const errorInfo = errorAdaptor(resData, { res: response, req: options })

      if (res?.code !== consts.RET_CODE.SUCCESS) {
        // 抛出错误到 errorHandler 中处理
        const error: ResponseError = new Error(errorInfo.errorMessage)
        error.name = 'BizError'
        error.data = resData
        error.info = errorInfo
        error.response = res
        throw error
      }
      return response
    }
  ],
  requestInterceptors: [authHeaderInterceptor]
}

// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  return {
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    waterMarkProps: {
      content: initialState?.currentUser?.username
    },
    footerRender: () => <Footer />,
    onPageChange: () => {
      const { location } = history
      // 如果没有登录，重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        history.push(loginPath)
      }
    },
    links: isDev
      ? [
          // <Link to="/umi/plugin/openapi" target="_blank">
          //   <LinkOutlined />
          //   <span>openAPI 文档</span>
          // </Link>,
          // <Link to="/~docs">
          //   <BookOutlined />
          //   <span>业务组件文档</span>
          // </Link>
        ]
      : [],
    menuHeaderRender: undefined,
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    ...initialState?.settings
  }
}
