import { describe, expect, it, vi } from "vitest";

import { AuthRepository } from "@/data/repositories/auth_repository";
import {
  FacebookIdentityResponseSchema,
} from "@/data/schemas/auth";
import type { AuthApi } from "@/data/services/api";
import type { IAuthStorage } from "@/data/storage/auth";
import type { IUserStorage } from "@/data/storage/user";
import { Result } from "@/utils/result";

function createRepository(overrides: Partial<AuthApi>) {
  const storage = {
    setAsid: vi.fn(async () => Result.ok(undefined)),
    setPsid: vi.fn(async () => Result.ok(undefined)),
    setLoginToken: vi.fn(async () => Result.ok(undefined)),
    setRefreshToken: vi.fn(async () => Result.ok(undefined)),
    setLoginProvider: vi.fn(async () => Result.ok(undefined)),
    setGuestToken: vi.fn(async () => Result.ok(undefined)),
    setDeviceId: vi.fn(async () => Result.ok(undefined)),
  } as unknown as IAuthStorage;
  const userStorage = {
    setUser: vi.fn(async () => Result.ok(undefined)),
    setUserId: vi.fn(async () => Result.ok(undefined)),
  } as unknown as IUserStorage;
  const repository = new AuthRepository(
    overrides as AuthApi,
    storage,
    userStorage,
  );
  return { repository, storage, userStorage };
}

describe("AuthRepository facebook identity", () => {
  it("binds facebook identity and stores returned ids", async () => {
    const bindFacebookIdentity = vi.fn(async () =>
      FacebookIdentityResponseSchema.parse({
        fbAsid: "asid-1",
        fbPsid: "psid-1",
        facebookBinding: { conflicts: [], bound: [] },
      }),
    );
    const { repository, storage } = createRepository({ bindFacebookIdentity });

    const result = await repository.bindFacebookIdentity({
      asid: "asid-1",
      psid: "psid-1",
    });

    expect(result.success).toBe(true);
    expect(bindFacebookIdentity).toHaveBeenCalledOnce();
    expect(storage.setAsid).toHaveBeenCalledWith("asid-1");
    expect(storage.setPsid).toHaveBeenCalledWith("psid-1");
  });
});
