import { HttpError } from "../../shared/api/errors";
import {
  httpClient,
  type RequestOptions,
} from "../../shared/api/httpClient";
import type { JsonResult } from "../../shared/api/types";
import {
  isLoginResponseData,
  isUserSummary,
  type LoginRequest,
  type LoginResponseData,
  type UserSummary,
} from "./authTypes";

interface AuthHttpClient {
  get<T>(path: string, options?: RequestOptions): Promise<JsonResult<T>>;
  post<T>(
    path: string,
    body?: unknown | FormData,
    options?: RequestOptions,
  ): Promise<JsonResult<T>>;
}

function contractError(
  result: JsonResult<unknown>,
  message: string,
): HttpError {
  return new HttpError({
    httpStatus: result.httpStatus,
    code: "INTERNAL_ERROR",
    message,
    details: null,
    requestId: result.requestId,
  });
}

export function createAuthApi(client: AuthHttpClient = httpClient) {
  return {
    async login(request: LoginRequest): Promise<LoginResponseData> {
      const result = await client.post<unknown>("auth/login", request, {
        auth: false,
      });
      if (!isLoginResponseData(result.data)) {
        throw contractError(result, "登录响应不符合DMS接口契约");
      }
      const expectedExpiresIn = request.keepSignedIn ? 604800 : 7200;
      if (result.data.expiresIn !== expectedExpiresIn) {
        throw contractError(result, "登录凭证有效期不符合DMS接口契约");
      }
      return result.data;
    },

    async logout(): Promise<void> {
      await client.post<unknown>("auth/logout");
    },

    async getCurrentUser(): Promise<UserSummary> {
      const result = await client.get<unknown>("users/me");
      if (!isUserSummary(result.data)) {
        throw contractError(result, "当前用户响应不符合DMS接口契约");
      }
      return result.data;
    },
  };
}

export const authApi = createAuthApi();
export type AuthApi = ReturnType<typeof createAuthApi>;
