import { describe, it, expect, vi, beforeEach } from "vitest";
import { GetUserInfoHandler } from "./handler";
import { GetUserInfo } from "./request";
import { IUserInfo } from "./model";
import { UserInfoBackendAdapter } from "./backend-adapter";
import { PrimariaApi } from "../../api/api";

const createMockApi = (): PrimariaApi =>
  ({
    globalStateManager: {
      setData: vi.fn(),
    },
    notificationService: {
      error: vi.fn(),
    },
  }) as any;

const createMockBackendAdapter = (): UserInfoBackendAdapter =>
  ({
    getUserInfo: vi.fn(),
  }) as any;

describe("GetUserInfoHandler", () => {
  let handler: GetUserInfoHandler;
  let api: PrimariaApi;
  let backendAdapter: UserInfoBackendAdapter;

  const message = {} as GetUserInfo;
  const mockUserInfo: IUserInfo = {
    name: "John Doe",
    email: "john@example.com",
  };

  beforeEach(() => {
    api = createMockApi();
    backendAdapter = createMockBackendAdapter();
    handler = new GetUserInfoHandler(api, backendAdapter);
    vi.clearAllMocks();
  });

  it("should fetch user info and store it in global state", async () => {
    (backendAdapter.getUserInfo as any).mockResolvedValue(mockUserInfo);

    const result = await handler.handle(message);

    expect(backendAdapter.getUserInfo).toHaveBeenCalled();
    expect(api.globalStateManager.setData).toHaveBeenCalledWith("userInfo", mockUserInfo);
    expect(result).toEqual(mockUserInfo);
  });

  it("should handle error and call notificationService", async () => {
    const error = new Error("Failed to fetch user info");
    (backendAdapter.getUserInfo as any).mockRejectedValue(error);

    const result = await handler.handle(message);

    expect(api.notificationService.error).toHaveBeenCalledWith("Failed to fetch user info");
    expect(result).toBeUndefined();
  });
});
