import { describe, expect, it, vi } from "vitest";
import type { JsonResult } from "../../../shared/api/types";
import { createAuthApi } from "../authApi";
import type {
  LoginRequest,
  LoginResponseData,
  UserSummary,
} from "../authTypes";

const user: UserSummary = {
  id: "9223372036854775807",
  username: "admin",
  realName: "系统管理员",
  organizationId: "10",
  organizationName: "机关",
  roleCode: "ADMIN",
  securityLevel: "TOP_SECRET",
  status: "ENABLED",
  allowedModules: [
    "DOCUMENT_BROWSER",
    "BACKEND_MANAGEMENT",
    "AUDIT_LOG",
  ],
};

function result<T>(data: T): JsonResult<T> {
  return {
    data,
    message: "success",
    requestId: "request-id",
    httpStatus: 200,
    headers: new Headers(),
  };
}

describe("authApi", () => {
  it("login 使用 auth/login、契约请求体并禁用旧会话401处理", async () => {
    const request: LoginRequest = {
      username: "admin",
      password: "password",
      keepSignedIn: true,
    };
    const response: LoginResponseData = {
      accessToken: "jwt",
      tokenType: "Bearer",
      expiresIn: 604800,
      user,
    };
    const post = vi.fn().mockResolvedValue(result(response));
    const api = createAuthApi({ post, get: vi.fn() });

    await expect(api.login(request)).resolves.toEqual(response);
    expect(post).toHaveBeenCalledWith("auth/login", request, { auth: false });
  });

  it("logout 只调用 auth/logout 且请求体为空", async () => {
    const post = vi.fn().mockResolvedValue(result({}));
    const api = createAuthApi({ post, get: vi.fn() });

    await expect(api.logout()).resolves.toBeUndefined();
    expect(post).toHaveBeenCalledWith("auth/logout");
  });

  it("getCurrentUser 只调用 users/me", async () => {
    const get = vi.fn().mockResolvedValue(result(user));
    const api = createAuthApi({ post: vi.fn(), get });

    await expect(api.getCurrentUser()).resolves.toEqual(user);
    expect(get).toHaveBeenCalledWith("users/me");
  });

  it("拒绝 number ID，不静默兼容错误后端响应", async () => {
    const get = vi.fn().mockResolvedValue(result({ ...user, id: 1 }));
    const api = createAuthApi({ post: vi.fn(), get });

    await expect(api.getCurrentUser()).rejects.toMatchObject({
      code: "INTERNAL_ERROR",
      message: "当前用户响应不符合DMS接口契约",
      requestId: "request-id",
    });
  });

  it("拒绝与 keepSignedIn 不一致的 expiresIn", async () => {
    const post = vi.fn().mockResolvedValue(
      result({
        accessToken: "jwt",
        tokenType: "Bearer",
        expiresIn: 7200,
        user,
      }),
    );
    const api = createAuthApi({ post, get: vi.fn() });

    await expect(
      api.login({
        username: "admin",
        password: "password",
        keepSignedIn: true,
      }),
    ).rejects.toMatchObject({
      code: "INTERNAL_ERROR",
      message: "登录凭证有效期不符合DMS接口契约",
    });
  });
});
