// Shared Wails bindings mock. Tests import { matrixServiceMock, runtimeMock }
// and call `vi.mock(...)` at module level pointing at this implementation, then
// override individual fns per test with .mockResolvedValueOnce / .mockRejectedValueOnce.
import { vi } from "vitest";

export const matrixServiceMock = {
  Login: vi.fn(async () => "@alice:matrix-af2f3d.organic-machine.com"),
  Logout: vi.fn(async (_uid: string) => undefined),
  GetSession: vi.fn(async (uid: string) => ({
    user_id: uid,
    device_id: "DEVICE123",
    homeserver_url: "https://matrix-af2f3d.organic-machine.com",
    has_token: true,
    expires_at: undefined,
  })),
  GetLastUserID: vi.fn(async () => ""),
  Start: vi.fn(async (_uid: string) => undefined),
  Stop: vi.fn(async () => undefined),
  ListRooms: vi.fn(async () => []),
  LoadTimeline: vi.fn(async (_roomID: string, _limit: number) => []),
  SendText: vi.fn(async (_roomID: string, _body: string) => "$evt-1"),
  SendMarkdown: vi.fn(async (_roomID: string, _md: string) => "$evt-1"),
  GetDiagnostics: vi.fn(async () => ({
    started: true,
    client_ready: true,
    crypto_initialized: true,
    sync_active: true,
    user_id: "@alice:matrix-af2f3d.organic-machine.com",
    homeserver_url: "https://matrix-af2f3d.organic-machine.com",
    rooms_count: 0,
    encrypted_rooms: 0,
    dms_count: 0,
    last_error: "",
  })),
  GetLogTail: vi.fn(async (_n: number) => [] as string[]),
  GetLogPath: vi.fn(async () => "/tmp/matrix_client_pc.log"),
  SetContext: vi.fn(async () => undefined),
};

export const runtimeMock = {
  EventsOn: vi.fn((_event: string, _cb: (...args: any[]) => void) => {
    // Return an unsubscribe function (Wails contract).
    return () => {};
  }),
  EventsEmit: vi.fn((..._args: any[]) => {}),
  EventsOff: vi.fn((..._args: any[]) => {}),
  EventsOnce: vi.fn((..._args: any[]) => () => {}),
  EventsOnMultiple: vi.fn((..._args: any[]) => () => {}),
};

export function resetWailsMocks() {
  for (const fn of Object.values(matrixServiceMock)) {
    (fn as any).mockClear();
  }
  for (const fn of Object.values(runtimeMock)) {
    (fn as any).mockClear();
  }
}
