import { SYSTEM_SERVICE_PREFIX } from '@/constants/service';
import { request } from '../request';
import { clearUserRouteCache } from './route';
import type { ServiceRequestResult } from './shared';

/** 后端登录返回 */
interface BackendLoginToken {
  userId: number;
  accessToken: string;
  refreshToken: string;
  expiresTime: number;
}

interface BackendUserInfoDTO {
  userId: string | number;
  userName?: string | null;
  nickname?: string | null;
  roles?: string[] | null;
  buttons?: string[] | null;
}

let userInfoPromise: Promise<ServiceRequestResult<BackendUserInfoDTO>> | null = null;

/** 将后端 token 结构转换成前端现有结构 */
function mapLoginToken(data: BackendLoginToken): Api.Auth.LoginToken {
  return {
    token: data.accessToken,
    refreshToken: data.refreshToken
  };
}

function mapUserInfo(data: BackendUserInfoDTO): Api.Auth.UserInfo {
  return {
    userId: String(data.userId ?? ''),
    userName: data.userName ?? '',
    nickname: data.nickname ?? '',
    roles: data.roles ?? [],
    buttons: data.buttons ?? []
  };
}

export function clearUserInfoCache() {
  userInfoPromise = null;
}

export function clearAuthApiCache() {
  clearUserInfoCache();
  clearUserRouteCache();
}

/**
 * 登录
 *
 * @param userName 用户名
 * @param password 密码
 */
export async function fetchLogin(
  userName: string,
  password: string
): Promise<ServiceRequestResult<Api.Auth.LoginToken>> {
  clearAuthApiCache();

  const result = await request<BackendLoginToken>({
    url: `${SYSTEM_SERVICE_PREFIX}/auth/login`,
    method: 'post',
    data: {
      username: userName,
      password,
      rememberMe: true
    }
  });

  if (result.error || !result.data) {
    return result as ServiceRequestResult<Api.Auth.LoginToken>;
  }

  return {
    ...result,
    data: mapLoginToken(result.data)
  };
}

/** 获取用户信息 */
export async function fetchGetUserInfo(force = false): Promise<ServiceRequestResult<Api.Auth.UserInfo>> {
  if (!userInfoPromise || force) {
    userInfoPromise = request<BackendUserInfoDTO>({
      url: `${SYSTEM_SERVICE_PREFIX}/auth/get-user-info`
    }).then(result => result as ServiceRequestResult<BackendUserInfoDTO>);
  }

  const result = await userInfoPromise;

  if (result.error || !result.data) {
    userInfoPromise = null;
    return result as ServiceRequestResult<Api.Auth.UserInfo>;
  }

  return {
    ...result,
    data: mapUserInfo(result.data)
  };
}

/**
 * 刷新 token
 *
 * @param refreshToken 刷新 token
 */
export function fetchRefreshToken(refreshToken: string) {
  return request<Api.Auth.LoginToken>({
    url: `${SYSTEM_SERVICE_PREFIX}/auth/refresh-token`,
    method: 'post',
    data: {
      refreshToken
    }
  });
}

/**
 * 返回自定义后端错误
 *
 * @param code 错误码
 * @param msg 错误信息
 */
export function fetchCustomBackendError(code: string, msg: string) {
  return request({ url: '/auth/error', params: { code, msg } });
}
